2014-01-10 144 views
5

(爲了澄清,我看過其他的問題進行解答,並嘗試了所有的解決方案,但它們都沒有解決問題)的ASP.NET Web API POST參數爲null

我在本地調試代碼,我將部署到Windows Azure雲服務。它是幾天前正在運行的ASP.NET Web API應用程序,但現在不再用了。

我有一個同時具有GET和POST處理程序的控制器。 GET處理程序正常工作並返回所需的結果,但POST處理程序無法從POST正文請求中獲取參數。這個處理程序在前幾天(大約2天前)工作得很好,但現在不工作。下面是詳細信息:

首先,GET和POST處理程序:

public class PlayerController : ApiController 
{ 
    [HttpGet] 
    public HttpResponseMessage Information(string userID) 
    { 
     // Works fine! 
    } 

    [HttpPost] 
    public HttpResponseMessage Insert(PlayerEntry entry) 
    { 
     // All values from entry are null or 0! 
    } 
} 

這是PlayerEntry模型:

public class PlayerEntry 
{ 
    public string userID; 
    public string userName; 
    public int userProgress; 
} 

這是所提出的POST請求(來自提琴手截取):

POST http://127.0.0.1/api/player/insert HTTP/1.1 
Host: 127.0.0.1 
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 80 
Connection: keep-alive 
Pragma: no-cache 
Cache-Control: no-cache 

userID=20&userName=Test&userProgress=9 

而這是服務器中的調試輸出:

iisexpress.exe Information: 0 : Request, Method=POST, Url=http://127.0.0.1:81/api/player/insert, Message='http://127.0.0.1:81/api/player/insert' 
iisexpress.exe Information: 0 : Message='Player', Operation=DefaultHttpControllerSelector.SelectController 
iisexpress.exe Information: 0 : Message='MvcWebRole1.Controllers.PlayerController', Operation=DefaultHttpControllerActivator.Create 
iisexpress.exe Information: 0 : Message='MvcWebRole1.Controllers.PlayerController', Operation=HttpControllerDescriptor.CreateController 
iisexpress.exe Information: 0 : Message='Selected action 'Insert(PlayerEntry entry)'', Operation=ApiControllerActionSelector.SelectAction 
iisexpress.exe Information: 0 : Message='Value read='MvcWebRole1.Models.PlayerEntry'', Operation=JQueryMvcFormUrlEncodedFormatter.ReadFromStreamAsync 
iisexpress.exe Information: 0 : Message='Parameter 'entry' bound to the value 'MvcWebRole1.Models.PlayerEntry'', Operation=FormatterParameterBinding.ExecuteBindingAsync 
iisexpress.exe Information: 0 : Message='Model state is valid. Values: entry=MvcWebRole1.Models.PlayerEntry', Operation=HttpActionBinding.ExecuteBindingAsync 
iisexpress.exe Information: 0 : Message='Action returned 'StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers: 
{ 
    Content-Type: text/plain; charset=utf-8 
}'', Operation=ReflectedHttpActionDescriptor.ExecuteAsync 
iisexpress.exe Information: 0 : Operation=ApiControllerActionInvoker.InvokeActionAsync, Status=200 (OK) 
iisexpress.exe Information: 0 : Operation=PlayerController.ExecuteAsync, Status=200 (OK) 
iisexpress.exe Information: 0 : Response, Status=200 (OK), Method=POST, Url=http://127.0.0.1:81/api/player/insert, Message='Content-type='text/plain; charset=utf-8', content-length=0' 
iisexpress.exe Information: 0 : Operation=PlayerController.Dispose 

到目前爲止,這些都是我已經試過了沒有任何改變的東西:

  • 添加一個「=」,在POST正文的開頭(只是要確定它止跌「T工作)
  • 一個[FromBody]之前PlayerEntry entry添加在Insert()功能
  • 嘗試測試其它的後處理程序我在其他控制器(他們沒有工作!)

但是,當我簡單地刪除PlayerEntry模型並從URL獲取POST參數(並通過URL發送參數。我只是做了一個測試),我可以毫無問題地得到所有的參數。

這可能是什麼原因造成的?據我所知,我沒有更改處理程序中的任何代碼(只有在內部運行並連接到SQL Server並返回結果的代碼),並且突然之間出現此問題。

+0

有時您需要確保您的實體具有無參數構造函數。因爲它首先從實體創建對象,然後設置屬性。 –

回答

9

我相信默認模型聯編程序不會綁定到字段,只有屬性與公共setter。嘗試改變你的領域的屬性:

public class PlayerEntry 
{ 
    public string userID { get; set; } 
    public string userName { get; set; } 
    public int userProgress { get; set; } 
} 
+0

那麼,只要我看到你的代碼,我意識到我已經改變了:) 我改變了這些字段,因爲這些屬性的行爲就像字段一樣。粘合劑無法與領域綁定是否是技術限制? 無論如何,謝謝你的答案。解決了一些開始成爲頭痛的問題。 – Bernardo

+0

謝謝。拯救生命! – Yasser

+0

只是好奇,我們是否需要一直髮布對象?或者我們可以將字符串作爲「post sting」或整數數組作爲{[1,2,3]}並在postWebApiMethod(字符串postString)或postWebApiMethod(List nums)中接收它? – karim

1

爲什麼它的價值,我厭倦了試圖讓它序列化正確,並做了我自己。

我的數據是一個字符串,其類似「值= thing1,thing2,thing3」的帖子,我能夠使用串行化了下列的一個javascript數組:

$('<form>', { 
     "id": "dynamicForm", 
     "html": '<input type="hidden" id="val" name="val" value="' + $scope.items + '" />', 
     "action": '/api/Example/', 
     "method": "post" 
    }).appendTo(document.body).submit(); 

然後在服務器側:

[HttpPost] 
[Route("")] 
public HttpResponseMessage Post() 
{ 
    var values = HttpContext.Current.Server.UrlDecode(Request.Content.ReadAsStringAsync().Result).Replace("val=","").Split(','); 
... 
}