本文介绍了ASP.net MVC路由具有可选的第一个参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要提供以下的网站之一的功能。

http://www.mysite.com/[sponsor]/{controller}/{action}

根据[赞助],网页具有定制。

我试过用注册和的Application_Start能在session_start得到它的工作路线,但不是组合。

 公共静态无效的RegisterRoutes(RouteCollection路线,串赞助商)
{
        如果(路线[赞助] == NULL)
    {
      routes.MapRoute(
     赞助商,//路线名称
     保荐+/ {控制器} / {行动} / {ID},// URL带参数
     新{控制器=家,行动=索引,ID = UrlParameter.Optional} //参数默认
     );
    }
}

此外,没有默认行为的 [赞助] 也应该发挥作用。
有人可以请让我知道,如果它是有在MVC3 URL一个可选的第一个参数技术上是可行的。如果是的话,请分享的实现。谢谢你。


更新code
为使所建议的修改后的谢尔盖·库德里亚夫采夫的中,code为给定值时起作用。
如果未提供名称,然后MVC不路由到控制器/动作。

请注意,这仅适用于家用控制器(包括与非赞助商)。对于其他控制器/动作,即使赞助商参数中指定它不是路由。

请有什么建议,必须修改。谢谢你。

 公共静态无效的RegisterRoutes(RouteCollection路线)
    {
        routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);
        routes.MapRoute(
             SponsorRoute
             {赞助} / {控制器} / {行动} / {ID},// URL带参数
             新{控制器=家,行动=索引,ID = UrlParameter.Optional}
        );        routes.MapRoute(
            NonSponsorRoute
            {控制器} / {行动} / {ID}
            新{控制器=家,行动=索引,ID = UrlParameter.Optional,赞助商=的String.Empty}
        );
    }

动作方法
公众的ActionResult指数(字符串赞助商)
        {

 }


解决方案

在你的情况赞助不应该被视为URL的恒定部分,但作为一个可变部分

在Global.asax中:

 公共静态无效的RegisterRoutes(RouteCollection路线)
{
...
     routes.MapRoute(
     SponsorRoute
     {赞助} / {控制器} / {行动} / {ID},// URL带参数
     新{控制器=家,行动=索引,ID = UrlParameter.Optional}
     );
     routes.MapRoute(
     NonSponsorRoute
     {控制器} / {行动} / {ID}
     新{控制器=家,行动=索引,ID = UrlParameter.Optional,赞助商=的String.Empty}
     );...
}

在你的控制器,例如,HomeController.cs:

 命名空间YourWebApp.Controllers
{
    公共类HomeController的:控制器
    {
        公众的ActionResult指数(字符串赞助商)
        {
            //在这里你可以做任何pre-处理取决于赞助商价值,包括重定向等。
        }
        ...
    }
}

请注意,此类型参数的永远是 System.String 和路由模板组件的名称 {赞助} 必须在控制器操作参数字符串赞助的名称完全一致。

UPD:增加第二条途径对于非赞助商的情况下

请注意,这样的设置将你的逻辑复杂,因为你可能会混淆不同的网址,例如网址

可以通过两个途径匹配:第一个将有赞助商= A,控制器= b和行动= C;第二个将控制器= A,动作= B和id = C。

例如,您可能希望ID来仅是数字 -

可如果指定了严格的要求到URL来避免这种情况。限制在 routes.MapRoute()函数的第四个参数中指定。

有关消歧的另一种方法是赞助商通用路由前指定对所有的控制器(通常你不会有太多人在你的应用程序)的独立路线。

UPD:

最直接但至少维护的方式赞助商和非赞助商的路线来区分被指定特定的控制器的路线,像这样的:

 公共静态无效的RegisterRoutes(RouteCollection路线)
{
...
     routes.MapRoute(
     HomeRoute
     首页/ {}动作/(编号),// URL带参数
     新{控制器=家,行动=索引,ID = UrlParameter.Optional,赞助商=的String.Empty}
     );
     routes.MapRoute(
     AccountRoute
     帐户/ {}动作/(编号),// URL带参数
     新{控制器=账户,行动=索引,ID = UrlParameter.Optional,赞助商=的String.Empty}
     );     ...     routes.MapRoute(
     SponsorRoute
     {赞助} / {控制器} / {行动} / {ID},// URL带参数
     新{控制器=家,行动=索引,ID = UrlParameter.Optional}
     );...
}

请注意,这里所有的控制器特定的路线,必须添加的之前 SponsorRoute。

从@counsellorben在回答中描述更复杂而更清洁的方式实施赞助商,控制器名称RouteConstraints。

I need to provide following functionality for one of the web sites.

http://www.mysite.com/[sponsor]/{controller}/{action}

Depending on the [sponsor], the web page has to be customized.

I tried combination of registering the routes with Application_Start and Session_Start but not able to get it working.

public static void RegisterRoutes(RouteCollection routes, string sponsor)
{
        if (routes[sponsor] == null)
    {
      routes.MapRoute(
     sponsor, // Route name
     sponsor + "/{controller}/{action}/{id}", // URL with parameters
     new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
     );
    }
}

Also, the default behavior without [sponsor] should also function.Can someone please let me know if it is technically feasible to have an optional first parameter in the MVC3 URL. If yes, please share the implementation. Thank you.


Updated CodeAfter making the changes as suggested by Sergey Kudriavtsev, the code works when value is given.If name is not provided then MVC does not route to the controller/action.

Note that this works only for the home controller (both and non-sponsor). For other controllers/actions, even when sponsor parameter is specified it is not routing.

Please suggest what has to be modified. Thank you.

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
             "SponsorRoute",
             "{sponsor}/{controller}/{action}/{id}", // URL with parameters
             new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        routes.MapRoute(
            "NonSponsorRoute",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional, sponsor = string.Empty }
        );
    }

Action Methodpublic ActionResult Index(string sponsor) {

     }
解决方案

In your case sponsor should not be treated as a constant part of URL, but as a variable part.

In Global.asax:

public static void RegisterRoutes(RouteCollection routes)
{
...
     routes.MapRoute(
     "SponsorRoute",
     "{sponsor}/{controller}/{action}/{id}", // URL with parameters
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }
     );
     routes.MapRoute(
     "NonSponsorRoute",
     "{controller}/{action}/{id}",
     new { controller = "Home", action = "Index", id = UrlParameter.Optional, sponsor=string.Empty }
     );

...
}

In your controllers, for example, HomeController.cs:

namespace YourWebApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index(string sponsor)
        {
            // Here you can do any pre-processing depending on sponsor value, including redirects etc.
        }
        ...
    }
}

Note that type of this parameter will always be System.String and the name of route template component {sponsor} must exactly match the name of action parameter string sponsor in your controllers.

UPD: Added second route for non-sponsor case.

Please note that such setup will complicate your logic, because you might confuse different urls, for example URL

http://www.mysite.com/a/b/c

could be matched by both routes: first one will have sponsor=a, controller=b and action=c; second one will have controller=a, action=b and id=c.

This situation can be avoided if you specify more strict requirements to URLs - for example, you may want IDs to be numerical only. Restrictions are specified in fourth parameter of routes.MapRoute() function.

Another approach for disambiguation is specifying separate routes for all of your controllers (usually you won't have much of them in your app) before generic route for sponsors.

UPD:

Most straightforward yet least maintainable way to distinguish between sponsor and non-sponsor routes is specifying controller-specific routes, like this:

public static void RegisterRoutes(RouteCollection routes)
{
...
     routes.MapRoute(
     "HomeRoute",
     "Home/{action}/{id}", // URL with parameters
     new { controller = "Home", action = "Index", id = UrlParameter.Optional, sponsor=string.Empty }
     );
     routes.MapRoute(
     "AccountRoute",
     "Account/{action}/{id}", // URL with parameters
     new { controller = "Account", action = "Index", id = UrlParameter.Optional, sponsor=string.Empty }
     );

     ...

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

...
}

Note that here all controller-specific routes must be added before SponsorRoute.

More complex yet more clean way is implementing RouteConstraints for sponsor and controller names as described in answer from @counsellorben.

这篇关于ASP.net MVC路由具有可选的第一个参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 18:21