2015-12-16 79 views
1

我有這樣的控制器:MVC路由問題:無效項

public class TestController : Controller 
{ 
    // GET: Test 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult Edit(int accessLevel) 
    { 
     return View(); 
    } 
} 

成立於RouteConfig.cs爲:

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

routes.MapRoute(
    name: "Test Edit", 
    url: "Test/Edit/{accessLevel}", 
    defaults: new { controller = "Test", action = "Edit", accessLevel = UrlParameter.Optional } 
); 

如果我去這個網址:

http://localhost:35689/Test/Edit/2 

我得到這個錯誤:

The parameters dictionary contains a null entry for parameter 'accessLevel' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'MyProject.Mvc.Client.Controllers.TestController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

任何想法,爲什麼這是?我會認爲我提供了正確的數據類型/2

+0

只要使用AttributeRouting並溝渠shitty破碎的路由表廢話。 – Phill

+0

我嘗試過,但我得到了同樣的結果,你能提供一個樣本嗎? – Spikee

+0

請問您可以在RouteConfig訂單中交換您的路線並試用它 – Dilip

回答

8

具體的路由定義應該在通用默認路由定義之前定義。 路由定義的順序真的很重要

routes.MapRoute(
    name: "Test Edit", 
    url: "Test/Edit/{accessLevel}", 
    defaults: new { controller = "Test", action = "Edit", 
                accessLevel = UrlParameter.Optional } 
); 

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

如果保持其他命令一樣,你有什麼(一般默認第一,具體的一個版本),當收到請求時爲Test/Edit/2因爲Test是一個有效的控制,這將是匹配的通用路由定義Edit是有效的操作方法名稱,2可能是Id參數的有效參數值。 由於請求獲得了有效的路由定義以匹配它的url模式,因此它將永遠不會根據第一個定義下的其他路由定義進行評估。

保留所有特定的路由定義,並將generic-default作爲最後一個。

或者您可以使用屬性路由在Test控制器中定義此路由模式。要啓用屬性路由,您可以調用RouteConfig.cs的RegisterRoutes方法中的MapMvcAttributeRoutes方法。您仍將保留默認路由定義。

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

    routes.MapMvcAttributeRoutes(); 

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

    ); 
} 

,並在您TestController

[Route("Test/Edit/{id?}")] 
public ActionResult Edit(int? id) 
{ 
    //check id value and return something 
} 

而且,存在如果它與一般的默認路由定義相匹配定義自定義路線沒有意義的。在你的情況下,即使你沒有定義自定義路由,Test/Edit/2將會去行動方法TestController作爲請求匹配的默認路由定義。

人們通常使用這些定製的路由定義來創建像

[Route("Product/{id}/{name}")] 
public ActionResult View(int id,string name) 
{ 
    //check id value and return something 
} 

這條路線定義好的URL模式將匹配請求Product/34/seo-friendly-name。看看這個問題的網址,你就會明白我在這裏解釋的是什麼。

2

在RoutesConfig.cs中切換路由。他們應該從最具體到一般。

您的默認路線是抓住這一個。

1

請在RouteConfig中交換您的路線,因爲路線的順序真的很重要。