Параметр веб-Api всегда имеет значение null

Почему параметр всегда имеет значение null, когда я вызываю метод ниже Post с помощью следующего ajax?

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

Вот вызов метода Web API через ajax:

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

Ответ 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

Обратите внимание, что вопреки стандартным протоколам имя параметра отсутствует. Вы отправляете только значение.

Вы можете узнать больше о том, как привязка модели в 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');
    }
});

Ответ 2

Вы не можете использовать простой тип для атрибута [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"}

Ответ 3

всякий раз, когда мы вызываем действие web api и которое принимает параметр [frombody], затем вводим префикс параметра с = например

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

для вызова над веб-api-действием

  • URI

    2.

User-Agent: Fiddler

Content-Type: application/x-www-form-urlencoded

Хост: localhost: 54702

Content-Length: 936

  1. тело запроса = данные

Надеюсь, это даст четкое представление.

Ответ 4

У меня только что был зверь с этим и .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 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.');
        }
    });

}