在 ASP.NET MVC 中自动切换 AMP 的视图
Automatically switching views for AMP in ASP.NET MVC
我想使用 .NET Core 2.0 在 ASP.NET MVC 中创建我网站的 AMP 版本。以前我在 .Net Framework 上用 DisplayModeProvider
实例做过一些工作,但这似乎不是 .NET Core 中的一个选项。
我想做的是在我的 URL 开始时将视图名称更改为 index.amp.cshtml
而不是 index.cshtml
/amp
。在 .NET Core 中实现此目标的最佳方法是什么?
您可以使用 IViewLocationExpander
执行类似的操作。碰巧的是,几天前我正在玩这个,所以我手头有一些代码示例。如果你创建这样的东西:
public class AmpViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context)
{
var contains = context.ActionContext.HttpContext.Request.Query.ContainsKey("amp");
context.Values.Add("AmpKey", contains.ToString());
var containsStem = context.ActionContext.HttpContext.Request.Path.StartsWithSegments("/amp");
context.Values.Add("AmpStem", containsStem.ToString());
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
if (!(context.ActionContext.ActionDescriptor is ControllerActionDescriptor descriptor)) { return viewLocations; }
if (context.ActionContext.HttpContext.Request.Query.ContainsKey("amp")
|| context.ActionContext.HttpContext.Request.Path.StartsWithSegments("/amp")
)
{
return viewLocations.Select(x => x.Replace("{0}", "{0}.amp"));
}
return viewLocations;
}
}
iViewLocationExpander
can be found in Microsoft.AspNetCore.Mvc.Razor
然后在 Startup.cs
中的 Configure Services
方法中,添加以下内容:
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new AmpViewLocationExtender());
});
这将根据请求更新视图位置,以便在 .cshtml
之前插入 .amp
任何时候 URL 以 /amp
开头或有查询amp
的字符串键。如果您的 AMP 视图不存在,它可能 blow-up 一点点,我还没有完全测试它,但它应该可以帮助您入门。
你可以这样定义 Middleware
:
public class AmpMiddleware
{
private RequestDelegate _next;
public AmpMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
const string ampTag = "/amp";
var path = context.Request.Path;
if (path.HasValue)
{
var ampPos = path.Value.IndexOf(ampTag);
if (ampPos >= 0)
{
context.Request.Path = new PathString(path.Value.Remove(ampPos, ampTag.Length));
context.Items.Add("amp", "true");
}
}
return _next(context);
}
}
public static class BuilderExtensions
{
public static IApplicationBuilder UseAmpMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<AmpMiddleware>();
}
}
并在Startup
中调用它:
app.UseAmpMiddleware();
然后可以检查页面并简单地设置另一个布局或限制一些代码,以这种方式无需为 amp 版本创建单独的页面:
@if (HttpContext.Items.ContainsKey("amp"))
{
<b>Request AMP Version</b>
}
我想使用 .NET Core 2.0 在 ASP.NET MVC 中创建我网站的 AMP 版本。以前我在 .Net Framework 上用 DisplayModeProvider
实例做过一些工作,但这似乎不是 .NET Core 中的一个选项。
我想做的是在我的 URL 开始时将视图名称更改为 index.amp.cshtml
而不是 index.cshtml
/amp
。在 .NET Core 中实现此目标的最佳方法是什么?
您可以使用 IViewLocationExpander
执行类似的操作。碰巧的是,几天前我正在玩这个,所以我手头有一些代码示例。如果你创建这样的东西:
public class AmpViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context)
{
var contains = context.ActionContext.HttpContext.Request.Query.ContainsKey("amp");
context.Values.Add("AmpKey", contains.ToString());
var containsStem = context.ActionContext.HttpContext.Request.Path.StartsWithSegments("/amp");
context.Values.Add("AmpStem", containsStem.ToString());
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
if (!(context.ActionContext.ActionDescriptor is ControllerActionDescriptor descriptor)) { return viewLocations; }
if (context.ActionContext.HttpContext.Request.Query.ContainsKey("amp")
|| context.ActionContext.HttpContext.Request.Path.StartsWithSegments("/amp")
)
{
return viewLocations.Select(x => x.Replace("{0}", "{0}.amp"));
}
return viewLocations;
}
}
iViewLocationExpander
can be found inMicrosoft.AspNetCore.Mvc.Razor
然后在 Startup.cs
中的 Configure Services
方法中,添加以下内容:
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new AmpViewLocationExtender());
});
这将根据请求更新视图位置,以便在 .cshtml
之前插入 .amp
任何时候 URL 以 /amp
开头或有查询amp
的字符串键。如果您的 AMP 视图不存在,它可能 blow-up 一点点,我还没有完全测试它,但它应该可以帮助您入门。
你可以这样定义 Middleware
:
public class AmpMiddleware
{
private RequestDelegate _next;
public AmpMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
const string ampTag = "/amp";
var path = context.Request.Path;
if (path.HasValue)
{
var ampPos = path.Value.IndexOf(ampTag);
if (ampPos >= 0)
{
context.Request.Path = new PathString(path.Value.Remove(ampPos, ampTag.Length));
context.Items.Add("amp", "true");
}
}
return _next(context);
}
}
public static class BuilderExtensions
{
public static IApplicationBuilder UseAmpMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<AmpMiddleware>();
}
}
并在Startup
中调用它:
app.UseAmpMiddleware();
然后可以检查页面并简单地设置另一个布局或限制一些代码,以这种方式无需为 amp 版本创建单独的页面:
@if (HttpContext.Items.ContainsKey("amp"))
{
<b>Request AMP Version</b>
}