【问题标题】:Apply Google AMP (Accelerated Mobile Pages) to ASP.NET Core site将 Google AMP(加速移动页面)应用到 ASP.NET Core 站点
【发布时间】:2018-12-11 22:00:26
【问题描述】:

我正在尝试使用 ASPNET Core MVC 创建一个 AMP 页面。如果有的话,我找不到很多文件。对于 ASPNET,建议使用 DisplayModes 创建 Google AMP Display。但是,ASPNet Core 不支持DisplayModes,我正在尝试想办法解决它。 任何建议将不胜感激!

@model Models.Article
@{
    Layout = null;
}

<!doctype html>
<html amp>
    <head>
        <meta charset="utf-8">
        <link rel="canonical" href="/article.cshtml">
        <link rel="amphtml" href="/article.amp.cshtml">
        <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
        <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
        <noscript>
        <style amp-boilerplate>
          body {
          -webkit-animation: none;
          -moz-animation: none;
          -ms-animation: none;
          animation: none
          }
    </style></noscript>
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    </head>
    <body>
        <article>
            <h2>@Html.DisplayFor(model => model.Title)</h2>
            <div>@Convert.ToDateTime(Model.PublishedDate).ToString("dddd, MMMM d, yyyy")</div>
        </article>    
    </body>
</html>

【问题讨论】:

    标签: c# asp.net asp.net-core amp-html


    【解决方案1】:

    有几种方法可以实现这样的目标。一种可能性是根据路线动态更改布局,即对 AMP 使用模板 X,否则使用 Y。

    一个更强大的解决方案是查看位置扩展器。这通常也被认为是显示模式的继承者。视图位置扩展器基本上是一种机制,允许您对 Razor 引擎将查找视图的物理位置进行后处理。因此,您可以使用它来有条件地修改或扩展视图所在的路径。

    在您的情况下,您可能希望更改行为,以便在通过 AMP 访问您的网站时,Razor 应首先查找&lt;view&gt;.amp.cshtml,然后再返回&lt;view&gt;.cshtml

    为此,您必须实现IViewLocationExpander。在PopulateViews 中,您必须检测您是否处于 AMP 模式;然后在ExpandViewLocations 中,您可以修改视图位置。

    这可能看起来有点像这样(未经测试,作为一个关于如何处理这个问题的想法):

    public class AmpViewLocationExpander : IViewLocationExpander
    {
        private const string ValueKey = "ampmode";
    
        public void PopulateValues(ViewLocationExpanderContext context)
        {
            // magic utility method that determines whether this is within an AMP context
            var isAmp = context.ActionContext.HttpContext.IsAmp();
    
            // persist the value on the context to allow the cache to consider this
            context.Values[ValueKey] = isAmp.ToString();
        }
    
        public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
            IEnumerable<string> viewLocations)
        {
            // when in AMP mode
            if (context.Values.TryGetValue(ValueKey, out var isAmpValue) && isAmpValue == "True")
            {
                return ExpandAmpViewLocations(viewLocations);
            }
    
            // otherwise fall back to default locations
            return viewLocations;
        }
    
        private IEnumerable<string> ExpandAmpViewLocations(IEnumerable<string> viewLocations)
        {
            foreach (var location in viewLocations)
            {
                // yield the AMP version first
                yield return location.Replace("{0}", "{0}.amp");
    
                // then yield the normal version as a fallback
                yield return location;
            }
        }
    }
    

    一旦你有了它,你只需要在你的ConfigureServices 中的AddMvc 调用之后注册扩展器:

    services.AddMvc()
        .AddRazorOptions(options =>
        {
            options.ViewLocationExpanders.Add(new AmpViewLocationExpander());
        });
    

    然后您只需为 AMP 创建备用视图。

    【讨论】:

    • 嘿,这是一个很好的答案!我只是想补充一点,我正在使用asp.net core 2.1,但在MvcOptions 中没有找到ViewLocationExpanders 属性;相反,我使用 services.Configure&lt;RazorViewEngineOptions&gt;(o =&gt; { o.ViewLocationExpanders.Add(new MyViewLocationExpander()); }); 配置了我的 ViewLocationExpander
    • @MartinShishkov 哦,你是对的,它们是 Razor 选项的一部分。不知道为什么我认为它们是 MvcOptions 的一部分。在我的回答中更正了,谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多