Parámetro web Api siempre nulo

¿Por qué el parámetro siempre es nulo cuando llamo al siguiente método de publicación con el siguiente ajax?

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

Aquí está la llamada al método Web API a través de 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"); } }); } }); } 

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

Básicamente, puede tener solo un parámetro de tipo escalar decorado con el atributo [FromBody] y su solicitud debe usar application/x-www-form-urlencoded y la carga de POST debe tener el siguiente aspecto:

 =somevalue 

Tenga en cuenta que, al contrario de los protocolos estándar, falta el nombre del parámetro. Usted está enviando solo el valor.

Puede leer más sobre cómo el enlace de modelo en la API web funciona en this article .

Pero, por supuesto, esta piratería es una cosa enferma. Deberías usar un modelo de vista:

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

y luego deshacerse del atributo [FromBody] :

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

y luego usa una solicitud 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'); } }); 

No puede usar un tipo simple para el atributo [FromBody] con el tipo de contenido JSON. Aunque el valor predeterminado en Visual Studio tiene una cadena del cuerpo, esto es para el tipo de contenido application / x-www-form-urlencoded.

Coloque el valor de cadena como una propiedad en una clase de modelo básica y el deserializador funcionará.

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

Cambie el JSON al que está enviando:

 {"Value":"test"} 

siempre que llamemos a la acción web api y que tome el parámetro [frombody], ingrese el prefijo del parámetro con = por ejemplo

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

llamar a la acción web api arriba

  1. URI

  2. 2.

User-Agent: Fiddler

Tipo de contenido: application / x-www-form-urlencoded

Anfitrión: localhost: 54702

Longitud del contenido: 936

  1. cuerpo de solicitud es = datos

Espero que esto dé una idea clara.

Acabo de pasarlo muy mal con esto y .NET Core Web API. Así que con suerte para ahorrar tiempo para alguien: el problema real para mí era simple: no me estaba convirtiendo al tipo correcto (Aviso @Darins Answer utiliza una VM en lugar de una cadena).

El tipo predeterminado en la plantilla es string . Pensé que porque estamos enviando JSON en cadena, veríamos una cadena JSON, pero este no era el caso. Tenía que hacerlo del tipo correcto.

Por ejemplo, esto falló

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

Pero esto funcionó.

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

Llamada Ajax

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