2014-01-10 213 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(','); 
... 
}