简体   繁体   English

Asp.net MVC URL重写操作和带有名称的ID

[英]Asp.net MVC url rewrite action and id with name

Asp.net Mvc Url MapRoute does not recognize the rout without Action: 如果没有Action,Asp.net Mvc Url MapRoute无法识别溃败:

Error: A public action method was not found on controller 错误: 在控制器上找不到公共操作方法

routes.MapRoute(
             "WorldWithoutAction",
             "World/{id}/{name}",
             new { id = UrlParameter.Optional, name = UrlParameter.Optional },
             new[] { "MyProject.Web.Controllers" });

Although trying this to catch World/Details but same error occurred: 虽然试图抓住世界/细节,但是发生了同样的错误:

routes.MapRoute(
            name: "World",
            url: "World",
            defaults: new { controller = "World", action = "Details" }
        );

What shoud I do to catch http://domain.com/world/1/australia to http://domain.com/world/details/1 ? 什么768,16我赶上http://domain.com/world/1/australiahttp://domain.com/world/details/1 Seems that it just accept action instead of {id} in url. 似乎它只是接受操作而不是网址中的{id}。

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
             "Default",
             "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional },
             new[] { "MyProject.Web.Controllers" });

        routes.MapRoute(
             "Default2",
             "{controller}/{action}/{id}/{name}",
             new { controller = "Agency", action = "Show", id = UrlParameter.Optional, name = UrlParameter.Optional },
             new[] { "MyProject.Web.Controllers" });

        routes.MapRoute(
             "Default3",
             "{controller}/{action}/{id}/{name}",
             new { id = UrlParameter.Optional, name = UrlParameter.Optional },
             new[] { "MyProject.Web.Controllers" });

        routes.MapRoute(
             "WorldWithoutAction",
             "World/{id}/{name}",
             new { id = UrlParameter.Optional, name = UrlParameter.Optional, action = "Details" },
             new[] { "MyProject.Web.Controllers" });

        routes.MapRoute(
            name: "World",
            url: "World",
            defaults: new { controller = "World", action = "Details" }
        );

    }

You need to reorder your routes so the most specific routes are defined first. 您需要重新排列路线,以便首先定义最具体的路线。 You also need to provide default values for: 您还需要提供以下默认值:

  • controller and action when they don't appear in the route 不在路线中的controlleraction
  • Any other parameter required by the action method. 操作方法需要的任何其他参数。 (For example in a method Details(int id) id is required and so in your route you need to either add a segment {id} or a default value) (例如,在方法Details(int id) id中是必需的,因此在您的路线中,您需要添加一个段{id}或默认值)

Also, your default routes won't work well with each other, you may want to rethink/simplify them. 另外,您的默认路由无法互相配合,您可能需要重新考虑/简化它们。 For example, you could hardcode the controller to "Agency" in default2 and combine default and default3 together. 例如,您可以在default2中将控制器硬编码为“ Agency”,并将default和default3组合在一起。

With all these changes, your routes definition would look something like this: 经过所有这些更改,您的路线定义将如下所示:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "World",
        url: "World",
        defaults: new { controller = "World", action = "Details", id = 0 }
    );

    routes.MapRoute(
        "WorldWithoutAction",
        "World/{id}/{name}",
        new { controller = "World", action = "Details", id = 0, name = UrlParameter.Optional },
        new[] { "MyProject.Web.Controllers" }
    );

    routes.MapRoute(
        "DefaultAgency",
        "Agency/{action}/{id}/{name}",
        new { controller = "Agency", action = "Show", id = UrlParameter.Optional, name = UrlParameter.Optional },
        new[] { "MyProject.Web.Controllers" }
    );

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}/{name}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional, name = UrlParameter.Optional },
        new[] { "MyProject.Web.Controllers" }
    );
}

As discussed in the chat, it might not make sense to declare the id as optional for controller actions that require a valid id to retrieve data. 如聊天中所讨论的,对于需要有效ID来检索数据的控制器操作,将ID声明为可选是没有意义的。 You might need to find another solution for having SEO friendly urls. 您可能需要找到另一种具有SEO友好URL的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM