【问题标题】:Web Api Parameter always nullWeb Api 参数始终为空
【发布时间】:2013-01-15 11:12:48
【问题描述】:

为什么我用下面的ajax调用下面的Post方法时参数总是为空?

public IEnumerable<string> Post([FromBody]string value)
{
    return new string[] { "value1", "value2", value };
}

这里是通过 ajax 调用 Web API 方法:

  function SearchText() {
        $("#txtSearch").autocomplete({
            source: function (request, response) {
                $.ajax({
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: "api/search/",
                    data: "test",
                    dataType: "text",
                    success: function (data) {
                        response(data.d);
                    },
                    error: function (result) {
                        alert("Error");
                    }
                });
            }
        });
    }

【问题讨论】:

    标签: asp.net ajax asp.net-web-api


    【解决方案1】:
    $.ajax({
        url: '/api/search',
        type: 'POST',
        contentType: 'application/x-www-form-urlencoded; charset=utf-8',
        data: '=' + encodeURIComponent(request.term),
        success: function (data) {
            response(data.d);
        },
        error: function (result) {
            alert('Error');
        }
    });
    

    基本上你只能有一个标量类型的参数,它用[FromBody] 属性修饰,你的请求需要使用application/x-www-form-urlencoded,POST 有效负载应该如下所示:

    =somevalue
    

    请注意,与标准协议相反,缺少参数名称。您只发送值。

    您可以在this article 中阅读有关 Web Api 中模型绑定如何工作的更多信息。

    当然,这种乱七八糟的事情是很恶心的。您应该使用视图模型:

    public class MyViewModel
    {
        public string Value { get; set; }
    }
    

    然后去掉[FromBody]属性:

    public IEnumerable<string> Post(MyViewModel model)
    {
        return new string[] { "value1", "value2", model.Value };
    }
    

    然后使用 JSON 请求:

    $.ajax({
        url: '/api/search',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify({ value: request.term }),
        success: function (data) {
            response(data.d);
        },
        error: function (result) {
            alert('Error');
        }
    });
    

    【讨论】:

    • 非常有用的部分:POST 有效负载以这种形式 '=somevalue' ... 我疯狂地试图弄清楚为什么对我不起作用。我有它的形式'key = value'。非常感谢!
    • 带有 '=' + 的上层解决方案是很好的 hack,但是您不需要为此指定内容类型,因为默认的 ajax 内容类型是 "contentType: 'application/x-www -form-urlencoded; charset=utf-8'," :]
    【解决方案2】:

    您不能对带有 JSON 内容类型的 [FromBody] 属性使用简单类型。虽然 Visual Studio 中的默认值有一个来自 body 的字符串,但它用于 application/x-www-form-urlencoded 内容类型。

    将字符串值作为属性放在基本模型类上,反序列化器就会工作。

    public class SimpleModel()
    {
        public string Value {get;set;}
    }
    
    public IEnumerable<string> Post([FromBody]SimpleModel model)
    {
        return new string[] { "value1", "value2", model.Value };
    }
    

    更改您要发送到的 JSON:

    {"Value":"test"}
    

    【讨论】:

    • 为什么 Visual Studio 使用字符串作为默认值?
    • 已添加说明。 Values 可以与 application/x-www-form-urlencoded 内容类型一起使用...但您使用的是 application/json。
    • model 还是 null,数据类型也是 json
    • 在我的帖子和达林的帖子之间,你应该有你的答案。如果您想使用 JSON,则需要 Model 方法,如果您宁愿只发布一个字符串,然后按照 Darin 的示例更改 contentType 并格式化数据属性。
    【解决方案3】:

    每当我们调用 web api 操作并使用 [frombody] 参数时,然后输入带有 = 的参数前缀 例如

    public string GetActiveEvents([FromBody] string XMLRequestString) {
    }
    

    调用上面的 web api 操作

    1. URI

    2. 2.

    用户代理:提琴手

    内容类型:application/x-www-form-urlencoded

    主机:本地主机:54702

    内容长度:936

    1. 请求正文为 =data

    我希望这会给你一个清晰的想法。

    【讨论】:

      【解决方案4】:

      我刚刚用这个和 .NET Core Web API 玩得很开心。所以希望为某人节省时间:对我来说,实际问题很简单——我没有转换为正确的类型(注意@Darins 的答案使用的是虚拟机而不是字符串)。

      模板中的默认类型是string。我想因为我们发送的是字符串化的 JSON,我们会看到一个 JSON 字符串,但事实并非如此。我必须使它成为正确的类型。

      例如这失败了

      [EnableCors("AllowAll")]
      [HttpPost]
      public HttpResponseMessage Post([FromBody]string value)
      {
          // Do something with the blog here....
      
          var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
          return msg;
      
      }
      

      但这有效。

      [EnableCors("AllowAll")]
      [HttpPost]
      public HttpResponseMessage Post([FromBody]Blog value)
      {
          // Do something with the blog here....
      
         var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
        return msg;
      
      }
      

      Ajax 调用

      function HandleClick() {
      
          // Warning - ID's should be hidden in a real application 
          //         - or have covering GUIDs.
          var entityData = {
              "blogId": 2,
              "url": "http://myblog.com/blog1",
              "posts": [
              {
                  "postId": 3,
                  "title": "Post 1-1",
                  "content": "This is post 1 for blog 1",
                  "blogId": 2
              },
              {
                  "postId": 4,
                  "title": "Post 1-2",
                  "content": "This is post 2 for blog 1",
                  "blogId": 2
              }
              ]
          };
      
      
          $.ajax({
              type: "POST",
              url: "http://localhost:64633/api/blogs",
              async: true,
              cache: false,
              crossDomain: true,
              data: JSON.stringify(entityData),
              contentType: "application/json; charset=utf-8",
              dataType: "json",
              success: function (responseData, textStatus, jqXHR) {
                  var value = responseData;
              },
              error: function (responseData, textStatus, errorThrown) {
                  alert('POST failed.');
              }
          });
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-09
        • 2014-08-06
        • 1970-01-01
        • 1970-01-01
        • 2017-08-28
        • 1970-01-01
        • 1970-01-01
        • 2016-05-12
        相关资源
        最近更新 更多