【问题标题】:ASP.NET Web API POST parameter is nullASP.NET Web API POST 参数为空
【发布时间】:2014-01-28 22:13:58
【问题描述】:

(澄清一下,我已阅读其他问题及其答案并尝试了所有解决方案,但没有一个解决问题)

我正在本地调试我将部署到 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 请求(取自 Fiddler):

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 正文的开头添加一个“=”(只是为了确保它不起作用)
  • Insert() 函数中的PlayerEntry entry 之前添加[FromBody]
  • 尝试测试我在其他控制器中的任何其他 POST 处理程序(它们都不起作用!)

但是,当我简单地删除 PlayerEntry 模型并从 URL 获取 POST 参数(并通过 URL 发送参数。我这样做只是作为测试)时,我可以毫无问题地获取所有参数。

这里的问题可能是什么原因造成的?据我所知,我没有更改处理程序中的任何代码(仅在内部运行并连接到 SQL Server 并返回结果的代码),突然间我遇到了这个问题。

【问题讨论】:

  • 有时您需要确保您的实体具有无参数构造函数。因为它首先从实体创建对象,然后设置属性。

标签: c# asp.net asp.net-mvc azure asp.net-web-api


【解决方案1】:

我相信默认模型绑定器不会绑定到 fields,只有 properties 具有公共设置器。尝试将您的字段更改为属性:

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

【讨论】:

  • 好吧,一看到你的代码,我就意识到我已经改变了:) 我将这些更改为字段,因为这些属性的行为就像字段一样。活页夹不能绑定到字段是技术限制吗?无论如何,谢谢你的回答。解决了一些开始令人头疼的问题。
  • 只是好奇,我们需要一直发布对象吗?或者我们可以将字符串发布为“post sting”或将整数数组发布为 {[1,2,3]} 并在 postWebApiMethod(string postString) 或 postWebApiMethod(List nums) 中接收它?
  • @karim 你可以接收任何你想要的参数,并且活页夹应该能够弄清楚。
【解决方案2】:

为了它的价值,我厌倦了试图让它正确序列化并自己做。

我的数据是一个 javascript 字符串数组,其中包含“value=thing1,thing2,thing3”之类的帖子,我可以使用以下命令对其进行序列化:

    $('<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(',');
...
}

【讨论】:

    猜你喜欢
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多