问题描述
我有一个使用Angular(10)作为前端的网站。在有角度的应用程序背后,ASP.Net Core 3.1提供了所有文件和api查询。
我想让open graph与该网站合作,以使社交媒体中的引荐链接更好。在google上进行的任何搜索都会导致您发现需要启用服务器端渲染。这样的页面:Server-side rendering in ASP.NET Core Angular。
我真的不想实现SSR,因为它有很多要求,这似乎有些过头了。因此,我着手用Asp net core中的中间件解决此问题。
现在我有一个可行的解决方案。
下面的代码可以工作,并根据请求更改我的index.html文件中的以下值。它拦截对/
(索引)的请求或对/details/
页面的任何请求。
<meta name="description" content="((og:description))">
<meta property="og:title" content="((og:title))" />
<meta property="og:description" content="((og:description))" />
<meta property="og:image" content="((og:previewImage))" />
我想知道这是否可以改进,或者这是一个可怕的主意,如果可以,为什么。
通过在app.UseMiddleware(typeof(OpenGraphsMiddleWare));
的Configure方法中放置Startup.cs
来运行代码。
代码:
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace NiftySite.Web.Middleware
{
public class OpenGraphMiddleWare
{
private readonly RequestDelegate _next;
private readonly static OpenGraphsData _defaultOpenGraph = new OpenGraphsData(
"mysite.com","Really nifty description.","https://myurl.com/favicon.ico"
);
private static Dictionary<string,string> _cache = new Dictionary<string,string>();
public OpenGraphMiddleWare(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context,IDetailsProcess listItemProcess,ILogger<OpenGraphMiddleWare> logger)
{
try
{
await HandleOGRequest(context,listItemProcess,logger);
}
catch (Exception e)
{
logger.LogError(e,$"OpenGraphMiddleWare failed: {e.Message}");
}
}
private async Task HandleOGRequest(HttpContext context,ILogger<OpenGraphMiddleWare> logger)
{
var path = context?.Request?.Path.ToString() ?? string.Empty;
if (path != "/" && path.StartsWith("/details/") == false)
{
await _next(context);
}
else
{
context.Response.ContentType = "text/html";
using (var originalIndexStream = new FileStream("wwwroot/index.html",FileMode.Open))
{
using (var streamReader = new StreamReader(originalIndexStream))
{
var pageString = string.Empty;
if (_cache.ContainsKey(path))
{
pageString = _cache[path];
}
else
{
var indexString = await streamReader.ReadToEndAsync();
pageString = await InjectOpenGraphData(indexString,path,listItemProcess);
}
byte[] byteArray = Encoding.UTF8.GetBytes(pageString);
using (MemoryStream resulStream = new MemoryStream(byteArray))
{
await resulStream.CopyToAsync(context.Response.Body);
}
}
}
}
}
private async Task<string> InjectOpenGraphData(string pageString,string path,IDetailsProcess listItemProcess)
{
var details = await GetOpenGraphValues(path,listItemProcess);
pageString = pageString
.Replace("((og:title))",details.Title)
.Replace("((og:description))",details.Description)
.Replace("((og:previewImage))",details.ImagePath);
_cache[path] = pageString;
return pageString;
}
private async Task<OpenGraphsData> GetOpenGraphValues(string path,IDetailsProcess listItemProcess)
{
var auctionId = GetAuctionId(path);
if (auctionId != null)
{
var details = await listItemProcess.GetSingleAuctionListItem(auctionId.Value);
return new OpenGraphsData("Details: " + details.Title,details.Advert,details.Thumbnail);
}
return _defaultOpenGraph;
}
private int? GetAuctionId(string path)
{
var auctionIdString = Regex.Match(path,@"\d+").Value;
if (int.TryParse(auctionIdString,out int auctionId))
return auctionId;
return null;
}
}
class OpenGraphsData
{
public string Title { get; }
public string Description { get; }
public string ImagePath { get; }
public OpenGraphsData(string title,string description,string imagePath)
{
Title = title;
Description = description;
ImagePath = imagePath;
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)