2013-01-31 176 views
35

为什么当我使用下面的ajax调用下面的Post方法时,参数总是为空?Web Api参数始终为空

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"); 
        } 
       }); 
      } 
     }); 
    } 

回答

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

非常有用的部分:邮政有效载荷是在这种形式'= somevalue'...我疯了试图找出为什么不为我工作。我以'key = value'的形式拥有它。那谢谢啦! – Learner

+0

'='+的上层解决方案很好,但不需要指定其内容类型,因为默认的ajax内容类型是“contentType:'application/x-www-form-urlencoded; charset = utf-8',“:] – dlght

14

你不能用一个简单的类型为[FromBody]属性与JSON内容类型。尽管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"} 
+0

为什么Visual Studio中使用的字符串作为默认呢? – daniel

+0

澄清补充说。值可以与application/x-www-form-urlencoded内容类型一起使用......但是您使用的是application/json。 –

+0

模型仍为空,也与数据类型json – daniel

1

每当我们调用Web API动作并采取[frombody]参数,然后输入参数前缀= 例如

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

调用上述网页API动作

  1. URI

  2. 2。

的User-Agent:提琴手

内容类型:应用/ X WWW的窗体-urlencoded

主机:本地主机:54702

的Content-Length:936

  1. 请求正文=数据

我希望这会给出清晰的想法。

1

我刚刚和这个和.NET Core Web API有过一段时间。所以希望能够节省时间:对于我来说,实际问题很简单 - 我没有转换为正确的类型(注意,@达林斯答案使用VM而不是字符串)。

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

E.g.这失败

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

}