【问题标题】:Add static Routes without visible Identifiers in Url in Razor Pages在 Razor 页面的 Url 中添加没有可见标识符的静态路由
【发布时间】:2021-06-11 12:10:18
【问题描述】:

我们希望将网站从 Asp.Net Webforms 迁移到 Asp.Net Core Webapplication (Razor Pages)。我们现在有没有可见标识符的可读 URL(为了可读性、SEO 和防止在可能的数据库迁移后更改 URL...)。

为此,我在启动时在 Global.Asax 中动态生成了路由:

RouteTable.Routes.MapPageRoute("myroute1",
    "banana/",
     "~/content.aspx", false, new RouteValueDictionary { { "id", "4711" }, , { "otherid", "4812" }
     
RouteTable.Routes.MapPageRoute("myroute2",
    "apple/",
     "~/content.aspx", false, new RouteValueDictionary { { "id", "4913" }, , { "otherid", "5014" }  

这样用户就可以像这样调用 content.aspx:

https://example.com/banana
https://example.com/apple

在 content.aspx 中,我从 RouteValues 中获得了映射的“id”和“otherid”。

如何在 Razor Pages 中实现这一点?

现在我有一个“Content.cshtml”,我需要访问 id 和 otherid。我在顶部添加了这个:

@page "/content/{id:int}/{otherid:int}/{title:string}"

上面的代码允许 mit 像这样调用 Urls:

https://example.com/content/4711/4812/banana // still have the ids in it and prefix "content"

是否有可能在启动时使用固定参数添加所有路由?我找不到类似的东西。

问候 cpt.oneeye

【问题讨论】:

    标签: c# asp.net asp.net-core routes razor-pages


    【解决方案1】:

    感谢这个帖子,我找到了解决方案:

    Is there a way to do dynamic routing with Razor Pages?

    另一个完整的例子可以在这里找到:

    https://github.com/dotnet/AspNetCore.Docs/issues/12997

    根据我在顶部的示例,您首先制作自己的 DynamicRouteValueTransformer(请参阅命名空间 Microsoft.AspNetCore.Mvc.Routing):

    public class NavigationTransformer : DynamicRouteValueTransformer
    {
        private readonly MyDatabaseContext _repository;
    
        public NavigationTransformer(MyDatabaseContext repository)
        {
            _repository = repository;
        }
    
        public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            // all requests which are incoming and fit a specific pattern will go through this method
            
            var slug = values["slug"] as string;
    
            // just get your needed info according to the "slug"
            // in my case i have to map according to NavigationNodes that are stored in the Database
            var myNavigationNode = _repository.NavigationNodes.FirstOrDefault(nn => nn.Name == slug);
    
            if (node == null)
            {
                // User will get a 404
                return null;
            }
            
            // set Path to Page according to Type (or whatever fits your logic)
            string pagename = "";
            
            if(node.Type == "ContentPage")
            {
                pagename = "/Content"  // Pages/Content.cshtml
            }
            else if(node.Type == "ContactForm")
            {
                pagename = "/Contact" // Pages/Contact.cshtml
            } 
            else 
            {
                pagename = "/Someotherpage"
            } 
    
            // return all RouteValues you need on your Page
            return new RouteValueDictionary()
            {
                { "page", pagename },
                { "id", node.Id },
                { "otherid", node.OtherId }
            };
        }
    }
    

    在 Startup.ConfigureServices() 中注册新服务:

    services.AddScoped<NavigationTransformer>();
    

    在 Startup.Configure() 中,您将 NavigationTransformer 添加到 Endpoints:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapDynamicPageRoute<NavigationTransformer>("{slug}"); // just "slug" so that every request will be handled by NavigationTransformer, you can also add a prefix-folder
    });
    

    现在,当您调用如下所示的 url 时,您将通过 Transformer 并且可以即时重新路由:

    https://example.com/banana
    https://example.com/apple
    

    请注意现有页面的路由更强大。因此,如果我们有 Apple.cshtml,第二个 Url 仍将路由到 Apple.cshtml 而不是 Content.cshtml

    【讨论】:

      【解决方案2】:

      要拥有静态网址,您可以将您的路线放在启动类中。例如:

      app.UseEndpoints(endpoints =>
      {
          endpoints.MapControllerRoute(
               name: "default1",
               pattern: "{controller=Home}/{action=Index}/{id?}"
          );
      });
      

      在这种情况下,您可以根据需要定义端点。例如,对于您的路线,您可以这样写:

      endpoints.MapControllerRoute(
           name: "default",
           pattern: "{content}/{id?}/{id?}/{banana}"
      );
      

      或者您可以使用Attribute Routing,您可以将其用于您的每个控制器。 read more about that in

      对不起我的英语?

      【讨论】:

      • 感谢您的回答。但我真的可以用这个吗?这一切都基于我认为我不能用于 Razorpages 的 MVC。抱歉,我犯了一个错误,在我的问题上标记了“mvc”。
      猜你喜欢
      • 2019-03-21
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 2021-05-29
      • 2020-01-25
      相关资源
      最近更新 更多