2011-01-12 59 views
4

不同的參數綁定優先考慮這條路線:ASP.NET MVC 3疑難雜症(錯誤):用於GET和POST

routes.MapRoute("home", "{action}/{id}", 
    new { controller = "home", action = "index", id = UrlParameter.Optional }); 

......這個動作:

public ActionResult Hi(string id) { 
    return Content("hello, id: " + id); 
} 

問題# 1 什麼是響應:

GET http://localhost:2247/hi/7?id=55 HTTP/1.1 

問題2 什麼是響應:

POST http://localhost:2247/hi/7?id=55 HTTP/1.1 
Content-Length: 4 
Content-Type: application/x-www-form-urlencoded 

id=3 


我相信這是一個錯誤,路線值應始終優先,因爲URL是什麼標識資源。如果您編寫POST,PUT或DELETE操作,您希望該ID來自URL,而不是來自請求的主體。這可能會導致更改不同的資源,並可能被惡意用戶利用。
經過一番研究發現問題是默認的ValueProviderFactory註冊順序,其中FormValueProviderFactory在RouteDataValueProviderFactory之前。相反的順序搞亂我創建了一個CustomModelBinderAttribute:

[AttributeUsage(AttributeTargets.Parameter)] 
public sealed class FromRouteAttribute : CustomModelBinderAttribute, IModelBinder { 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 

     bindingContext.ValueProvider = new RouteDataValueProvider(controllerContext); 

     return ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext); 
    } 

    public override IModelBinder GetBinder() { 
     return this; 
    } 
} 

...你可以使用這樣的:

public ActionResult Hi([FromRoute]string id) { 
    return Content("hello, id: " + id); 
} 

回答

6

在ASP.NET MVC 3 RC2:

  • GET:響應:你好,ID:7
  • POST:響應:你好,ID:3

而且這裏是測試視圖:

<a href="/hi/7?id=55">GET</a> 
<form action="/hi/7?id=55" method="POST"> 
    <input type="hidden" name="id" value="3" /> 
    <input type="submit" value="POST" /> 
</form> 

因此,這裏的評價優先順序:

  1. POST身體參數
  2. 路線
  3. 查詢字符串參數

而且通過與ASP.NET MVC 2.0獲得完全相同的結果的方式。

+0

有沒有這方面的官方文檔?我可以找到幾篇文章來確認你的答案,但沒有官方的。 – Stijn 2012-04-12 12:28:55

1

我猜想,對於得到的迴應是「你好7」而POST則是「Hello 3」。