35

为什么当我使用下面的 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");
                    }
                });
            }
        });
    }
4

4 回答 4

60
$.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

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

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

但当然,这种黑客行为是一件病态的事情。您应该使用视图模型:

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');
    }
});
于 2013-01-31T11:25:12.563 回答
14

您不能对[FromBody]具有 JSON 内容类型的属性使用简单类型。尽管 Visual Studio 中的默认值有一个来自正文的字符串,但这是针对 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"}
于 2013-01-31T11:17:35.493 回答
1

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

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

调用上面的 web api 操作

  1. URI

  2. 2.

用户代理:提琴手

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

主机:本地主机:54702

内容长度:936

  1. 请求正文是 =data

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

于 2015-06-04T19:00:29.973 回答
1

我刚刚用这个和 .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;

}

阿贾克斯调用

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

}
于 2016-10-26T17:23:24.413 回答