【问题标题】:MVC url routing with slug and id. Makes a mess with default routing带有 slug 和 id 的 MVC url 路由。使默认路由变得一团糟
【发布时间】:2017-09-14 09:23:04
【问题描述】:

我试图让我的网址看起来不错,并且对蛞蝓的 seo 友好。我坚持我成功了,但后来我的默认路由停止工作。 当我转到这个 example.com/location/viewlocation/528 时,网址最终会像 example.com/528/a-nice-location

那就太好了! 但是现在我的正常东西不起作用。 输入 example.com/home/index 会导致错误

参数字典包含“Oplev.Controllers”中方法“System.Web.Mvc.ActionResult ViewLocation(Int32, System.String)”的不可为空类型“System.Int32”的参数“id”的空条目。位置控制器'。可选参数必须是引用类型、可空类型或声明为可选参数。

我尝试了不同的解决方案,但我遗漏了一些东西。不能让它工作。

我的代码: 路由配置

routes.MapRoute(
            name: "view_location",
            url: "{id}/{slug}",
            defaults: new { controller = "Location", action = "ViewLocation", id = UrlParameter.Optional, slug = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

位置控制器

public ActionResult ViewLocation(int id, string slug)
    {
        if (string.IsNullOrEmpty(slug))
        {
            slug = "a-nice-location"; // testing..
            return RedirectToRoute("view_location", new { id = id, slug = slug });
        }
        return View();
    }

家庭控制器

    public ActionResult Index()
{
    return View();
}

【问题讨论】:

    标签: asp.net-mvc url-routing slug


    【解决方案1】:

    您的第一个路由匹配 url 中包含 0、1 或 2 个段的任何内容。例如它匹配../Home/Index。你需要一些方法来区分它,例如你可以做到

    routes.MapRoute(
        name: "view_location",
        url: "ViewLocation/{id}/{slug}",
        defaults: new { controller = "Location", action = "ViewLocation", slug = UrlParameter.Optional }
    );
    

    或者你可以添加一个路由约束

    另请注意,只有最后一个参数可以标记为 UrlParameter.Optional,但在您的情况下,id 无论如何都不是可选的

    【讨论】:

      【解决方案2】:

      好的,所以我以某种方式最终得到了一些有用的东西! 将 view_location 的路由更改为:

                  routes.MapRoute(
                  name: "view_location",
                  url: "{id}/{slug}",
                  defaults: new { controller = "Location", action = "ViewLocation", slug = UrlParameter.Optional},
                  constraints: new { id = @"\d+" }
              );
      

      【讨论】:

      • 或者你可以使用int?类型而不是int。消息很简单:如果您使用的是不可为空的类型,则需要为路由声明数字约束。
      【解决方案3】:

      这是为了补充已经给出的答案。带有路由约束的属性路由也可以。

      首先确保RouteConfig中启用了属性路由

      //Attribute routing
      routes.MapMvcAttributeRoutes(); // placed before convention-based routes
      
      //convention-based routes
      routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      );
      

      接下来在控制器上使用必要的Route属性

      [HttpGet]
      [Route("{id:int}/{*slug?}", Name = "view_location")] // Matches GET 528/some-nice-location
      public ActionResult ViewLocation(int id, string slug) {
          if (string.IsNullOrEmpty(slug)) {
              slug = "a-nice-location"; // testing..
              return RedirectToRoute("view_location", new { id = id, slug = slug });
          }
          return View();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-29
        • 2011-07-02
        • 2020-07-13
        • 2015-12-26
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        相关资源
        最近更新 更多