web-dev-qa-db-fra.com

Web Api Parameter toujours null

Pourquoi le paramètre est-il toujours nul lorsque j'appelle la méthode Post ci-dessous avec l'ajax ci-dessous?

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

Voici l'appel à la méthode API Web via 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");
                    }
                });
            }
        });
    }
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');
    }
});

Fondamentalement, vous ne pouvez avoir qu'un seul paramètre de type scalaire qui est décoré avec le [FromBody] attribut et votre demande doit utiliser application/x-www-form-urlencoded et la charge utile POST devrait ressembler à ceci:

=somevalue

Notez que contrairement aux protocoles standard, le nom du paramètre est manquant. Vous envoyez uniquement la valeur.

Vous pouvez en savoir plus sur le fonctionnement de la liaison de modèle dans Web Api dans this article .

Mais bien sûr, ce piratage est une chose malade. Vous devez utiliser un modèle de vue:

public class MyViewModel
{
    public string Value { get; set; }
}

puis se débarrasser du [FromBody] attribut:

public IEnumerable<string> Post(MyViewModel model)
{
    return new string[] { "value1", "value2", model.Value };
}

puis utilisez une requête 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

Vous ne pouvez pas utiliser un type simple pour le [FromBody] attribut avec le type de contenu JSON. Bien que la valeur par défaut dans Visual Studio ait une chaîne de body, c'est pour le type de contenu application/x-www-form-urlencoded.

Mettez la valeur de chaîne en tant que propriété sur une classe de modèle de base et le désérialiseur fonctionnera.

public class SimpleModel()
{
    public string Value {get;set;}
}

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

Modifiez le JSON auquel vous envoyez:

{"Value":"test"}
14
Mark Jones

chaque fois que nous appelons une action web api et qui prennent le paramètre [frombody] puis saisissent le préfixe du paramètre avec = par exemple

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

appeler ci-dessus l'action web api

  1. URI

    2.

User-Agent: Fiddler

Type de contenu: application/x-www-form-urlencoded

Hôte: localhost: 54702

Longueur du contenu: 936

  1. le corps de la demande est = data

J'espère que cela vous donnera une idée claire.

1
user4975137

Je viens de passer un temps fou avec cela et l'API Web .NET Core. Espérons donc gagner du temps pour quelqu'un: Le problème réel pour moi était simple - je ne convertissais pas au type correct (Remarquez que la réponse @Darins utilise un VM plutôt qu'une chaîne).

Le type par défaut dans le modèle est string. Je pensais que parce que nous envoyons du JSON stratifié, nous verrions une chaîne JSON, mais ce n'était pas le cas. J'ai dû en faire le bon type.

Par exemple. Cela a échoué

[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;

}

Mais cela a fonctionné.

[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