在路由参数不工作MVC 3 [英] parameters in routing do not work MVC 3

查看:90
本文介绍了在路由参数不工作MVC 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我做错了什么,但在这花几个小时没有运气好的话后,我会很高兴,如果有人能帮助我了这一点。

好像路由系统荣誉仅在第一路由登记的参数。

这是我的global.asax.cs怎么看起来像

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;
使用System.Web.Routing;命名空间MvcApplication4
{
    公共类MvcApplication:System.Web.HttpApplication
    {
        公共静态无效RegisterGlobalFilters(GlobalFilterCollection过滤器)
        {
            filters.Add(新HandleErrorAttribute());
        }        公共静态无效的RegisterRoutes(RouteCollection路线)
        {
            routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);            routes.MapRoute(
                     T,//路线名称
                     {控制器} / {行动} / {I} / {V},
                     新{I = UrlParameter.Optional,V = UrlParameter.Optional}
                 );            routes.MapRoute(
                默认,//路线名称
                {控制器} / {行动} / {ID}
                新{ID = UrlParameter.Optional}
            );        }        保护无效的Application_Start()
        {
            AreaRegistration.RegisterAllAreas();            RegisterGlobalFilters(GlobalFilters.Filters);
            的RegisterRoutes(RouteTable.Routes);
        }
    }
}

这是主控制器的样子

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;命名空间MvcApplication4.Controllers
{
    公共类HomeController的:控制器
    {
        公众的ActionResult指数(INT?ID)
        {
            ViewBag.Message =欢迎使用ASP.NET MVC!;            返回查看();
        }        公众的ActionResult关于(INT?一)
        {
            返回查看();
        }    }
}

问题是,当我尝试这个网址

 的http://本地主机:52230 /首页/索引/ 2

的ID永远是零。但是,如果我尝试
的http://本地主机?:52230 /首页/索引ID = 2 ....它的工作原理

它还如果我任何其他途径之前注册家庭/工作指标。在这种情况下,后来注册的途径有同样的问题在接受参数。

我在做什么错在这里?

更新:

我想这两个控制器工作,怎么会我的路线注册什么样子的?

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;命名空间MvcApplication4.Controllers
{
    公共类HomeController的:控制器
    {
        公众的ActionResult指数(INT?ID)
        {
            ViewBag.Message =欢迎使用ASP.NET MVC!;            返回查看();
        }
    }
}

第二控

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;命名空间MvcApplication4.Controllers
{
    公共类VisitorController:控制器
    {
        //
        // GET:/ VisitorSecurityPoints /
        公众的ActionResult测试(字符串我,串五)
        {            返回查看();
        }    }
}


解决方案

该路由下令从特殊到一般。这意味着MVC将始终尝试在已请求的URL时,寻找匹配的最具体的路线。该航线将变得更加贪婪的进一步下跌的路由列表他们。

如果我们以在有问题的两条路线仔细一看,我们可以看到,有没有办法为MVC两个区分,除非 v 参数提供。它们都具有控制器操作参数,并且他们也有一个可选的第三个参数。如果 v 没有提供,MVC将无法知道使用哪种路线,除非这样的优先权制度已经到位的办法,那就是为什么在路线的顺序路由表是重要的。

有办法让MVC对两条路线这样区分,但是这取决于所讨论的参数的数据类型。例如,如果 I 的DateTime ,而不是 INT ,您可以添加一个路由约束只有它匹配的日期。见<一href=\"http://stephenwalther.com/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx\"相对=nofollow>有关约束的详细信息,这文章。

有关使用RouteDebugger我也是第二理查德的建议。这是非常宝贵的帮助,了解像这样的情况,可能会导致更清洁的路由表的设计。

修改

我还要提到该URL的原因作品当你标记?ID = 2 上到底是因为MVC尝试直接建模绑定到匹配动作参数在查询字符串。但是,请注意匹配的路由参数将采取precedence在查询字符串提供的值。例如,使用以下路线:

  routes.MapRoute(
    默认,//路线名称
    {控制器} / {行动} / {ID},// URL带参数
    新{控制器=家,行动=索引,ID = UrlParameter.Optional}
);

导航到的http://本地主机:50754 /家庭/指标/ 2 将导致 ID 为2 。结果
导航到的http://本地主机:50754 /家庭/索引/ ID = 4 将导致 ID 为4 。结果
导航到的http://本地主机:50754 /家庭/指标/ 2 ID = 4 将导致 ID 是2.

的意见后,已更新

为您解决特定问题的最简单的方法是改变路由表包括以下路线:

 公共静态无效的RegisterRoutes(RouteCollection路线)
{
    routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);    routes.MapRoute(
        游客,//路线名称
        先生/ {行动} / {I} / {V},//带参数的URL
        新
        {
            控制器=访客,行动=测试,
            I = UrlParameter.Optional,V = UrlParameter.Optional
        }
    );    routes.MapRoute(
        默认,//路线名称
        {控制器} / {行动} / {ID},// URL带参数
        新{控制器=家,行动=索引,ID = UrlParameter.Optional}
    );
}

注意 {行动} 参数仍然是present在这条新航线。这使事情变得更容易一些就可以了扩展,以满足在控制器的其他操作。如果您需要限制在那些在控制器上present行动的路线,你需要添加一个路由约束正如前面提到的。

注意,该方法的缺点是路由表中可以很迅速成长,如果你不断地specifiying新航线来匹配几个URL。这可以增加新的功能到一个站点,因为现有的路由更加困难,也可以使维护更加困难。只要有可能,你应该尝试设计的路线,因为它使维护和调试容易得多了相匹配的默认 {控制器} / {行动} / {ID} 路线长远之计。

I am sure I am doing something wrong, but after spending a few hours on this with no luck, I would be really happy if someone can help me out with this.

Seems like the routing system honors the parameters only in the first routing registration.

This is how my global.asax.cs looks like

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication4
{


    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

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

            routes.MapRoute(
                     "t", // Route name
                     "{controller}/{action}/{i}/{v}",  
                     new { i = UrlParameter.Optional, v = UrlParameter.Optional }  
                 );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", 
                new {  id = UrlParameter.Optional } 
            );





        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

This is how the home controller looks like

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication4.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index(int? id)
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About(int? a)
        {
            return View();
        }



    }
}

The problem is when I try this url

http://localhost:52230/Home/Index/2

The id is always null. But if I try http://localhost:52230/Home/Index?id=2 ....it works.

It also works if I register home/index before any other route. In which case the routes registered later have the same problem in accepting parameters.

What am I doing wrong here?

UPDATE:

I want both these controllers to work, how would my route registration look like?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication4.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index(int? id)
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }




    }
}

2nd controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication4.Controllers
{
    public class VisitorController : Controller
    {
        //
        // GET: /VisitorSecurityPoints/


        public ActionResult Test(string i,string v)
        {

            return View();
        }

    }
}

解决方案

The routes are ordered from specific to general. That means MVC will always try to match the most specific route when looking at the URL which has been requested. The routes will become more "greedy" the further down the route list they are.

If we take a closer look at the two routes in question, we can see that there is no way for MVC to differentiate between the two, unless the v parameter is supplied. They both have the controller and action parameters, and they both also have an optional third parameter. If v isn't supplied, MVC would have no way of knowing which route to use unless a priority system like this was in place, and that's why the order of the routes in the routing table is important.

There are ways to allow MVC to differentiate between two routes like this, but it depends on the data type of the parameter in question. For example, if i was a DateTime, rather than an int, you could add a Route Constraint which matched dates only. See this article for more information on constraints.

I also second Richard's advice for using RouteDebugger. It's invaluable for helping to understand situations such as this and can lead to cleaner routing table design.

Edit

I should also mention that the reason the URL "works" when you tag ?id=2 on the end is because MVC tries to model bind directly to matching action parameters in the query string. However, note that a parameter matching a route will take precedence over a value supplied in the query string. For example, using the following route:

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

Navigating to http://localhost:50754/home/index/2 will result in id being 2.
Navigating to http://localhost:50754/home/index/?id=4 will result in id being 4.
Navigating to http://localhost:50754/home/index/2?id=4 will result in id being 2.

Updated after comments

The simplest way to solve your particular problem is to change the route table to include the following route:

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

    routes.MapRoute(
        "visitors", // Route name
        "visitor/{action}/{i}/{v}", // URL with parameters
        new
        {
            controller = "Visitor", action = "Test",
            i = UrlParameter.Optional, v = UrlParameter.Optional
        }
    );

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

Notice the {action} parameter is still present in this new route. This makes things a little easier to expand on it to cater for other actions in the controller. If you need to constrain the route to the actions that are present on the controller, you'd need to add a route constraint as mentioned earlier.

One caveat to this approach is that the route table can grow quite quickly if you're constantly specifiying new routes to match a few URLs. That can make adding new features to a site more difficult because of the existing routing and can also make maintenance more difficult. Whenever possible, you should try to design a route to match the default {controller}/{action}/{id} route because it makes maintenance and debugging so much easier in the long run.

这篇关于在路由参数不工作MVC 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆