2013-01-31 132 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.'); 
     } 
    }); 

}