Asp.net-Mvc-3

帶有可選第一個參數的 ASP.net MVC 路由

  • July 25, 2017

我需要為其中一個網站提供以下功能。

http://www.example.com/$$ sponsor $$/{控制器}/{動作}

取決於

$$ sponsor $$,必須自定義網頁。 我嘗試將路由與 Application_Start 和 Session_Start 結合使用,但無法使其正常工作。

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
    );
   }
}

此外,預設行為沒有**$$ sponsor $$**也應該起作用。有人可以告訴我在 MVC3 URL 中有一個可選的第一個參數在技術上是否可行。如果是,請分享實現。謝謝你。


更新程式碼按照Sergey Kudriavtsev的 建議進行更改後,程式碼在給出值時工作。如果未提供名稱,則 MVC 不會路由到控制器/操作。

請注意,這僅適用於家庭控制器(包括非贊助商)。對於其他控制器/操作,即使指定了贊助商參數,它也不是路由。

請建議必須修改的內容。

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 }
       );
   }

動作方法

public ActionResult Index(string sponsor)
   {
   }

在您的情況下sponsor,不應將其視為 URL 的常量部分,而應視為可變部分。

在 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 }
    );

...
}

例如,在您的控制器中,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.
       }
       ...
   }
}

請注意,此參數的類型將始終為System.String,並且路由模板組件的名稱必須與控制器{sponsor}中的操作參數名稱完全匹配。string sponsor

UPD:為非贊助商案件增加了第二條路線。

請注意,這樣的設置會使您的邏輯複雜化,因為您可能會混淆不同的 url,例如 URL

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

可以通過兩條路線匹配:第一個將有贊助商=a、控制器=b和動作=c;第二個將有controller=a、action=b 和id=c。

如果您對 URL 指定更嚴格的要求,則可以避免這種情況 - 例如,您可能希望 ID 僅為數字。限制在函式的第四個參數中指定routes.MapRoute()

另一種消除歧義的方法是在為贊助商提供通用路由之前為所有控制器指定單獨的路由(通常您的應用程序中不會有太多控制器)。

升級版:

區分贊助商和非贊助商路由的最直接但最不易維護的方法是指定特定於控制器的路由,如下所示:

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 }
    );

...
}

請注意,此處必須在SponsorRoute之前添加所有特定於控制器的路由。

更複雜但更簡潔的方法是為贊助商和控制器名稱實現 RouteConstraints,如@counsellorben 的回答中所述。

引用自:https://stackoverflow.com/questions/8310815