I want to create and AMP version of my website in ASP.NET MVC using .NET Core 2.0. Previously I had done some work with DisplayModeProvider
instances in tha past on .Net framework, but that does not seem to be an option in .NET Core.
What I want to be able to do is alter the view names to be index.amp.cshtml
rather than index.cshtml
when my URL starts iwth /amp
. What's the best way to achieve this in .NET Core?
You can do something like this using IViewLocationExpander
. As it happens, I was playing with this a few days ago so I have some code samples to hand. If you create something like this:
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
Then in your Configure Services
method in Startup.cs
, add the following:
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new AmpViewLocationExtender());
});
What this will do is update the view locations per request to insert .amp
before .cshtml
any time the URL either starts with /amp
or there is a query string key of amp
. If your AMP views don't exist, it might blow-up a little, I've not fully tested it, but it should get you started.