代码之家  ›  专栏  ›  技术社区  ›  lonix

更改ASP.NET Core RazorPages中cshtml文件的名称

  •  0
  • lonix  · 技术社区  · 5 年前

    以极薄的篇幅( .cshtml

    我可以编写模板化的cshtml文件,并通过网页包填充它们:

    ContactUs.cshtml.cs
    ContactUs.cshtml                     <------ read by webpack
    ContactUs.generated.cshtml           <------ generated by webpack
    

    ContactUs.generated.cshtml )而不是模板文件( ContactUs.cshtml

    我怀疑答案是使用 IPageRouteModelConvention 但我不确定怎么做。

    (一个肮脏的解决方法是使用文件名 ContactUs.template.cshtml 和 ContactUs.cshtml 但我更喜欢上面的内容,因为“生成”更清晰。)


    使现代化

    要简化问题,请执行以下操作:

    Foo.cshtml.cs 和 Foo.cshtml .

    我如何告诉它去寻找 Foo.cshtml.cs Foo.generated.cshtml ?

    0 回复  |  直到 5 年前
        1
  •  1
  •   King King    5 年前

    加载应用程序时,框架会为您加载一组 PageRouteModel 从razor页面文件夹自动生成的。每个这样的模型都包含一组 SelectorModel AttributeRouteModel . 你需要做的就是修改它 AttributeRouteModel.Template

    您可以创建一个自定义 IPageRouteModelConvention 针对每个 PageRouteModel AttributeRouteModel.Template ,它可能与其他现有路线重复)。除非您必须管理一组共享的管线模板。相反,您可以创建一个自定义 IPageRouteModelProvider . 它提供了所有 PageRouteModel Index.cshtml 和 Index.generated.cshtml 你想让它摘下来 . 如果生成的视图不存在,则默认为

    下面是详细的代码:

    public class SuffixedNamePageRouteModelProvider : IPageRouteModelProvider
    {
        public SuffixedNamePageRouteModelProvider(string pageNameSuffix, int order = 0)
        {
            _pageNameSuffixPattern = string.IsNullOrEmpty(pageNameSuffix) ? "" : $"\\.{Regex.Escape(pageNameSuffix)}$";
            Order = order;
        }
        readonly string _pageNameSuffixPattern;
        public int Order { get; }
    
        public void OnProvidersExecuted(PageRouteModelProviderContext context)
        {
    
        }
    
        public void OnProvidersExecuting(PageRouteModelProviderContext context)
        {
            if(_pageNameSuffixPattern == "") return;
            var suffixedRoutes = context.RouteModels.Where(e => Regex.IsMatch(e.ViewEnginePath, _pageNameSuffixPattern)).ToList();
            var overriddenRoutes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            foreach (var route in suffixedRoutes)
            {
                //NOTE: this is not required to help it pick the right page we want.
                //But it's necessary for other related code to work properly (e.g: link generation, ...)
                //we need to update the "page" route data as well
                route.RouteValues["page"] = Regex.Replace(route.RouteValues["page"], _pageNameSuffixPattern, "");
    
                var overriddenRoute = Regex.Replace(route.ViewEnginePath, _pageNameSuffixPattern, "");
                var isIndexRoute = overriddenRoute.EndsWith("/index", StringComparison.OrdinalIgnoreCase);
    
                foreach (var selector in route.Selectors.Where(e => e.AttributeRouteModel?.Template != null))
                {
                    var template = Regex.Replace(selector.AttributeRouteModel.Template, _pageNameSuffixPattern, "");
                    if (template != selector.AttributeRouteModel.Template)
                    {
                        selector.AttributeRouteModel.Template = template;
                        overriddenRoutes.Add($"/{template.TrimStart('/')}");
                        selector.AttributeRouteModel.SuppressLinkGeneration = isIndexRoute;
                    }                                                                              
                }
                //Add another selector for routing to the same page from another path.
                //Here we add the root path to select the index page
                if (isIndexRoute)
                {
                    var defaultTemplate = Regex.Replace(overriddenRoute, "/index$", "", RegexOptions.IgnoreCase);
                    route.Selectors.Add(new SelectorModel()
                    {
                        AttributeRouteModel = new AttributeRouteModel() { Template = defaultTemplate }
                    });
                }
            }
            //remove the overridden routes to avoid exception of duplicate routes
            foreach (var route in context.RouteModels.Where(e => overriddenRoutes.Contains(e.ViewEnginePath)).ToList())
            {
                context.RouteModels.Remove(route);
            }
        }
    }
    

    登记 IPageRouteModelProvider Startup.ConfigureServices :

    services.AddSingleton<IPageRouteModelProvider>(new SuffixedNamePageRouteModelProvider("generated"));