【问题标题】:ASP.Net MVC routing issue url not workingASP.Net MVC 路由问题 url 不起作用
【发布时间】:2012-08-04 04:52:51
【问题描述】:

我在 home 控制器中创建了两个不同名称的操作方法

public ActionResult Default()
{
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View("index");
}

public ActionResult Index(int a)
{
    ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + a;
    return View();
}

我的路由代码如下:

routes.MapRoute(
  "Default1", // Route name
  "{Home}/{ID}", // URL with parameters
  new { controller = "Home", action = "Index", id =UrlParameter.Optional});

routes.MapRoute(
    "Default2", // Route name
    "{Home}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

routes.MapRoute(
    "Default", // Route name
    "{controller}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

但还是有问题

当我输入像 http://localhost:7221 这样的 URL 时,首页就来了,调用 Default() 方法,但是如果我输入像这样的 URL

http://localhost:7221/Home 然后出现错误。为了处理这种情况,我定义了类似的路线

routes.MapRoute(
    "Default2", // Route name
    "{Home}", // URL with parameters
    new { controller = "Home", action = "Default" }
);

但它不起作用.......你能告诉我为什么吗?

如果我键入 http://localhost:7221/Home/88 之类的 URL,则应该调用 Index(int a) 方法但出现错误。为什么

我希望在输入 URL http://localhost:7221http://localhost:7221/Home 时调用 Default() 以及何时输入

http://localhost:7221/Home/88 然后应该调用 Index(int a)。我的路线有什么问题?我该如何纠正它?如果可能,请纠正我的路线代码。谢谢

【问题讨论】:

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


    【解决方案1】:

    这条规则实际上应该涵盖你需要的一切:

            routes.MapRoute(
                "Default",
                "{controller}/{action}/{a}",
                new {
                    controller = "Home",
                    action = "Index",
                    a = UrlParameter.Optional 
                }
            );
    

    注意以下几点:

    1. 参数名称需要匹配方法上的参数,你有ida - 所以框架无法匹配它们。在上面的规则中,我把a放在了映射规则中来匹配你的方法,但是你应该在这两个地方给它一个更好的名字。

    2. 如果未提供控制器或操作,则此规则默认为 /Home/Index。如果你想点击你命名为Default的动作,你会去/Home/Default

    3. 如果您提供 /Home/Index/21,它将调用 Index 方法 - 但如果您不提供年龄,则会出现问题,因为您没有匹配规则的方法。需要添加方法public ActionResult Index()或者使用默认值public ActionResult Index(int a = 0)

    以下是一些违反此规则的 URL 示例。

    • http://yourapp/ - 将转到 /Home/Index
    • http://yourapp/Home - 将转到 /Home/Index
    • http://yourapp/Home/Default - 将转到 /Home/Default
    • http://yourapp/Home/Index - 见我上面的笔记 - 你需要一种方法来支持这个
    • http://yourapp/Home/Index/21 - 将转到 /Home/Index 并将 a 传递为 21

    【讨论】:

    • 你说用上面的一个路由代码我的情况可以处理但是如何因为在路由代码中你定义 action = "Index" 总是所以总是会调用 index 方法......我是正确的?那么默认方法将如何被调用。我测试你的代码并在明天回复更多关于你答案的问题。谢谢
    • 这是在 URL 中未提供操作时使用的默认值。如果您提供/Accounts/List,这条路线会将您带到AccountsController 并调用方法List()
    【解决方案2】:

    您遇到问题的原因是您的路由参数与操作方法不匹配。您的操作方法需要 int a,但在任何情况下您都没有提供它,而是提供了称为 id 的整数。

    你应该在 routevalues 中拥有的是:

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

    注意年龄参数是可选的。我们的控制器应该如下所示:

    public class HomeController : Controller
    {
    
        public ActionResult Index(int? age)
        {
            if ( age != null )
                ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + age;
            else
                ViewData["Message"] = "Welcome to ASP.NET MVC!";
    
            return View();
        }
    }
    

    当然,我们可以使用名为 id 的参数,但出于演示目的,我将其称为 age。

    更新:

    以下内容更接近您的原始要求:

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

    控制器:

        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";
            return View();
        }
        public ActionResult IndexA(int age)
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC! and Your Age is " + age;
            return View("Index");
        }
    

    【讨论】:

    • 我很清楚,操作方法参数名称和路由参数名称必须与 age = UrlParameter.Optional 相同。但我说我有两种方法,一种有参数,一种没有参数。当我输入localhost:7221localhost:7221/Home 时,应该调用defult。当我输入localhost:7221/Home/88 时,应该调用索引。所以现在根据我的要求告诉我如何在 global.asax 中编写和订购路由代码。帮助我,我是 MVC 的初学者。非常感谢。
    • 更新了答案。我也不是这些方面的专家。
    【解决方案3】:

    移除 Home 周围的大括号,将 ID 更改为 Age 并移除 Age 的可选行为。

    routes.MapRoute(
        "Default1", // Route name
         "Home/{Age}", // URL with parameters
         new { controller = "Home", action = "Index" }
    );
    

    我希望我理解您想要正确实现的目标。如果没有,我建议使用 Route 调试器进一步了解。

    试试https://github.com/Haacked/RouteMagic(在 NuGet 上作为 RouteMagic.Mvc 提供)

    我自己没有尝试过,但我确实使用了它的一个组件。

    祝你好运!

    【讨论】:

      【解决方案4】:

      您遇到了哪些错误?我只是不想在这里假设任何事情。我认为 //localhost:7221/Home 调用失败是因为它与第一个路由匹配(因为 id 参数是可选的),而不是您期望的第二个路由。此外,路由定义中的参数名称应与操作方法声明中的参数名称匹配。

      如果我输入像 //localhost:7221/Home/88 这样的 url,那么应该调用 Index(int a) 方法,但会出错。为什么

      将参数重命名为 id 或将路由可选参数重命名为 a。路由引擎找不到任何东西来推断“a”的值,因此它尝试传递一个空值来代替不可为空的 int 参数,从而导致错误。

      我希望当我输入 url //localhost:7221 或 //localhost:7221/Home 时应该调用 Default()

      然后将最后一个路由的映射移动到代码块的顶部,就像它将首先添加到路由集合中一样,并且 localhost:7221/Home 将首先与之匹配。

      您还应该研究一下 Phil Haack 的这个工具:

      http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        相关资源
        最近更新 更多