wake-up-neo.net

Web-API 2 POST mit einzelnen String-Parametern funktioniert nicht

Ich habe den folgenden Controller:

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

    }
}

WebApi-Konfig

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

Ich benutze diesen js-Code, um die API .__ aufzurufen.

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

Ich bekomme eine 405 Methode nicht erlaubt (post) 

Irgendwelche Ideen?

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

Erläuterung

Da Sie nur einen einzelnen Wert senden, fügen Sie das = -Zeichen vor dem Wert ein, so dass es wie Formularkodierung behandelt wird. Sie können den Inhaltstyp auch hinzufügen, wenn Sie deutlich machen möchten, dass dies der Aufruf von Ajax ist.

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

Alternativ können Sie den Inhalt auch über die URL OR senden, den Inhalt in ein Objekt auf dem Server sowie in den Ajax-Aufruf einpacken und stringifizieren.

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

Fügen Sie [FromBody] zur Signatur der API-Methode wie public IHttpActionResult Post([FromBody]string filterName) hinzu und umschließen Sie den ajax-Datenparameter in Anführungszeichen: data: '"' + bodyContent + '"'.

Nicht sehr intuitiv, aber es funktioniert.

8
misha

Fügen Sie der Methode im Controller das Attribut [HttpPost] hinzu

0
meJustAndrew