web-dev-qa-db-fra.com

Web Api 2 POST avec le paramètre de chaîne simple ne fonctionne pas

J'ai le contrôleur suivant:

public class ValuesController : ApiController
{
    // POST api/values
    public IHttpActionResult Post(string filterName)
    {
        return new JsonResult<string>(filterName, new JsonSerializerSettings(), Encoding.UTF8, this);

    }
}

WebApi config

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional });

J'utilise ce code js pour appeler l'api

$.ajax(
{
    url: "/api/values/",
    type: "POST",
    dataType: 'json',
    data: { filterName: "Dirty Deeds" },
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});

Je reçois une méthode 405 non autorisée (post) 

Des idées?

22
Danny

c #

public class ValuesController : ApiController
{
    // POST api/values
    [HttpPost] // added attribute
    public IHttpActionResult Post([FromBody] string filterName) // added FromBody as this is how you are sending the data
    {
        return new JsonResult<string>(filterName, new JsonSerializerSettings(), Encoding.UTF8, this);
    }

JavaScript

$.ajax(
{
    url: "/api/Values/", // be consistent and case the route the same as the ApiController
    type: "POST",
    dataType: 'json',
    data: "=Dirty Deeds", // add an = sign
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});

Explication

Comme vous n'envoyez qu'une seule valeur, ajoutez le signe = devant elle pour qu'elle soit traitée comme un encodage de formulaire. Vous pouvez également ajouter le type de contenu si vous souhaitez préciser que c'est ce que vous faites pour l'appel ajax.

contentType: 'application/x-www-form-urlencoded'

Sinon, vous pouvez également envoyer le contenu via l'URL OR en enveloppant le contenu dans un objet sur le serveur ainsi que dans l'appel ajax et le stringifier.

public class Filter {
    public string FilterName {get;set;}
}

public class ValuesController : ApiController
{
    // POST api/values
    [HttpPost] // added attribute
    public IHttpActionResult Post([FromBody] Filter filter) // added FromBody as this is how you are sending the data
    {
        return new JsonResult<string>(filter.FilterName, new JsonSerializerSettings(), Encoding.UTF8, this);
    }

JavaScript

$.ajax(
{
    url: "/api/Values/", // be consistent and case the route the same as the ApiController
    type: "POST",
    dataType: 'json',
    contentType: 'application/json',
    data: JSON.stringify({FilterName: "Dirty Deeds"}), // send as json
    success: function (result) {
        console.log(result);
    },
    error: function (xhr, status, p3, p4) {
        var err = "Error " + " " + status + " " + p3;
        if (xhr.responseText && xhr.responseText[0] == "{")
            err = JSON.parse(xhr.responseText).message;
        console.log(err);
    }
});
27
Igor

Ajoutez [FromBody] à la signature de méthode d'API, comme public IHttpActionResult Post([FromBody]string filterName), et enveloppez le paramètre de données ajax avec des guillemets: data: '"' + bodyContent + '"'.

Pas très intuitif, mais ça marche.

8
misha

Ajouter l'attribut [HttpPost] à la méthode dans le contrôleur

0
meJustAndrew