2012-06-22 46 views
5

我在ASP.NET MVC 4 RC Web API中看到我認爲是一個奇怪的綁定問題。我有一個方法來接受來自客戶的請求。問題是,當post方法被調用時,沒有任何參數是綁定的,我到了我的break line和name,email都是null。如果我在JavaScript中將請求的類型更改爲GET,那麼下面的Get函數被綁定的參數調用。ASP.NET MVC 4 RC Web API參數綁定問題

爲什麼參數無法爲Post方法綁定,我該如何解決這個問題?

send: function(evt) { 
    evt.preventDefault(); 
    $.ajax({ 
     url: '/api/person', 
     data: this.model.toJSON(), 
     type: "POST", 
     dataType: "json", 
     success: function(data) { 
      console.log("Success"); 
     }, 
     error: function(data) { 
      console.log("Error"); 
     } 
    }); 
    } 

以下是控制器操作:

public void Get(string name, string email) { 
    throw new NotImplementedException(); 
} 

public void Post(string name, string email) { 
    throw new NotImplementedException(); 
} 

注:

  • 我使用所有的ASP.NET MVC 4 RC的Web API的默認值(所以解串器應該是Json.NET)
  • JS調試器上的Chrome網絡選項卡正確顯示錶單數據中的參數。

回答

13

與MVC(網頁)不同,簡單的參數類型爲will not, by default, bind from the post body but instead from the URI。因此,使用您的代碼,您需要將nameemail參數傳遞給查詢字符串或作爲路由參數。

但是,這可以通過創建模型類型(在MVC白話中)並將其用於方法參數來輕鬆解決。事實上,你可以使用它兩個(在你給的情況下),如果你再上get方法使用[FromUri]

public class SomeParams { 
    public string name { get; set; } 
    public string email { get; set; } 
} 

//now an alternative way to write the Get method 
public MyResult Get([FromUri] SomeParams p){ 
    //members are bound from the query string (more like MVC traditional binding) 
    //note - as in MVC, SomeParams will need a default constructor for this to work. 
} 

public PostResult Post(SomeParams p){ 
    //'p' is bound from your JSON (assuming correct format) 
    //because 'complex' types are deserialized using formatters 
    //only one object can be read from the body with a formatter in Web API 
    //as the request body is not buffered; unlike MVC. 
} 

我堅持在返回類型的方法,只是因爲他們需要返回一些東西!

我真的推薦閱讀邁克斯托爾的文章,我鏈接到上面(和他的許多人)。

很容易假設Web API,因爲它共享MVC的相同範例甚至類名,實際上與MVC相同 - 但事實並非如此。我最初想知道爲什麼會出現這種情況(因爲我自己在MVC上編寫了很多REST服務,發現它很酷,一旦你編寫了一些實用程序類和基類增強),但是他們已經對編寫Web API的挑戰進行了適當的考慮,我認爲可能是正確的做了他們已有的改變。

但是,這意味着我們必須採取一些我們現在認爲理所當然的事情,並重新學習Web API。

+0

我的get參數不是void,實際上它不存在。我可能並不清楚,但它只是爲了說明該功能在GET上運行,並不在POST上。 – Cody

+1

好吧 - 那好吧,然後:)。總而言之,如果你從請求的主體中綁定了多個參數,那麼基本上最簡單的事情就是寫一個簡單的模型類型,就像我之前展示的那樣。 –

+0

感謝Mike Stall文章鏈接,它對於發生了什麼非常有幫助。我剛剛假定Web API使用與MVC完全相同的綁定策略。創建一個自定義類來接收參數就像一個魅力,我不是那種解決方案的粉絲,但我不知道爲什麼,所以我可能只是固執。 :)無論如何,這是我將使用的解決方案。謝謝!:) – Cody