web-dev-qa-db-ja.com

Web APIパラメーターは常にnull

以下のajaxで以下のPostメソッドを呼び出すと、パラメーターが常にnullになるのはなぜですか?

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");
                    }
                });
            }
        });
    }
35
daniel
$.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]属性で装飾されたスカラー型のパラメーターを1つだけ持つことができ、リクエストは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');
    }
});
60
Darin Dimitrov

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"}
14
Mark Jones

web APIアクションを呼び出し、[frombody]パラメーターを使用する場合は、パラメーターのプレフィックスを=で入力する

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

上記のWeb APIアクションを呼び出す

  1. URI

    2。

ユーザーエージェント:フィドラー

コンテンツタイプ:application/x-www-form-urlencoded

ホスト:localhost:54702

コンテンツの長さ:936

  1. リクエスト本文は= data

これが明確なアイデアを与えることを願っています。

1
user4975137

私は、これと.NET Core Web APIに夢中になりました。だから、誰かの時間を節約することを願っています:私にとって実際の問題は簡単でした-私は正しいタイプに変換していませんでした(@Darinsの答えは文字列ではなくVMを使用します)。

テンプレートのデフォルトのタイプは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 Call

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

}
1
HockeyJ