por objeto mostrar leer externo enviar ejemplos ejemplo datos convertir con javascript asp.net-mvc json asp.net-mvc-4 asp.net-web-api

javascript - mostrar - ¿Cómo pasar los datos json POST al método de la API web como un objeto?



leer json externo con javascript (9)

La aplicación web de ASP.NET MVC4 API define el método de publicación para salvar al cliente. El cliente se pasa en formato json en el cuerpo de solicitud POST. El parámetro del cliente en el método posterior contiene valores nulos para las propiedades.

¿Cómo solucionar esto para que los datos publicados pasen como objeto del cliente?

Si es posible, se debería usar Content-Type: application / x-www-form-urlencoded ya que no sé cómo cambiarlo en el método javascript que se publica.

Controlador:

public class CustomersController : ApiController { public object Post([FromBody] Customer customer) { return Request.CreateResponse(HttpStatusCode.OK, new { customer = customer }); } } } public class Customer { public string company_name { get; set; } public string contact_name { get; set; } }

Solicitud:

POST http://localhost:52216/api/customers HTTP/1.1 Accept: application/json, text/javascript, */*; q=0.01 X-Requested-With: XMLHttpRequest Content-Type: application/x-www-form-urlencoded; charset=UTF-8 {"contact_name":"sdfsd","company_name":"ssssd"}


¡Trabajar con POST en webapi puede ser complicado! Me gustaría añadir a la respuesta ya correcta ...

Se centrará específicamente en POST, ya que tratar con GET es trivial. No creo que muchos buscarían para resolver un problema con GET con webapis. De todos modos ..

Si su pregunta es: En MVC Web Api, ¿cómo: usar nombres de métodos de acción personalizados que no sean los verbos HTTP genéricos? - ¿Realizar múltiples publicaciones? - ¿Publicar múltiples tipos simples? - ¿Publicar tipos complejos a través de jQuery?

Entonces las siguientes soluciones pueden ayudar:

Primero, para usar Métodos de acción personalizados en la API web, agregue una ruta de api web como

public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}"); }

Y luego puedes crear métodos de acción como:

[HttpPost] public string TestMethod([FromBody]string value) { return "Hello from http post web api controller: " + value; }

Ahora, dispare el siguiente jQuery desde la consola de su navegador

$.ajax({ type: ''POST'', url: ''http://localhost:33649/api/TestApi/TestMethod'', data: {'''':''hello''}, contentType: ''application/x-www-form-urlencoded'', dataType: ''json'', success: function(data){ console.log(data) } });

Segundo, para realizar múltiples publicaciones , es simple, crear múltiples métodos de acción y decorar con el atributo [HttpPost]. Use [ActionName ("MyAction")] para asignar nombres personalizados, etc. Llegará a jQuery en el cuarto punto a continuación.

En tercer lugar, en primer lugar, no es posible publicar varios tipos SIMPLE en una sola acción. Además, hay un formato especial para publicar incluso un solo tipo simple (además de pasar el parámetro en la cadena de consulta o el estilo REST). Este fue el punto que me hizo golpear mi cabeza con Rest Clients (como Fiddler y la extensión de cliente REST avanzado de Chrome) y buscar en la web durante casi 5 horas cuando, finalmente, la siguiente URL resultó ser de ayuda. ¡Citaré el contenido relevante para que el enlace se vuelva muerto!

Content-Type: application/x-www-form-urlencoded in the request header and add a = before the JSON statement: ={"Name":"Turbo Tina","Email":"[email protected]"}

PD: notado la sintaxis peculiar ?

http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+when+I+try+to+Post+to+my+Web+Api

De todos modos, vamos a superar esa historia. Moviéndose en

Cuarto, la publicación de tipos complejos a través de jQuery, por supuesto, $ .ajax () entrará rápidamente en el rol:

Digamos que el método de acción acepta un objeto Person que tiene un ID y un nombre. Así, desde javascript:

var person = { PersonId:1, Name:"James" } $.ajax({ type: ''POST'', url: ''http://mydomain/api/TestApi/TestMethod'', data: JSON.stringify(person), contentType: ''application/json; charset=utf-8'', dataType: ''json'', success: function(data){ console.log(data) } });

Y la acción se verá como:

[HttpPost] public string TestMethod(Person person) { return "Hello from http post web api controller: " + person.Name; }

Todo lo anterior, funcionó para mí !! ¡Aclamaciones!


1) En su lado del cliente, puede enviar su solicitud http.post en una cadena como la que se muestra a continuación

var IndexInfo = JSON.stringify(this.scope.IndexTree); this.$http.post(''../../../api/EvaluationProcess/InsertEvaluationProcessInputType'', "''" + IndexInfo + "''" ).then((response: any) => {}

2) Luego en tu web api controlador puedes deserializarlo

public ApiResponce InsertEvaluationProcessInputType([FromBody]string IndexInfo) { var des = (ApiReceivedListOfObjects<TempDistributedIndex>)Newtonsoft.Json.JsonConvert.DeserializeObject(DecryptedProcessInfo, typeof(ApiReceivedListOfObjects<TempDistributedIndex>));}

3) Tu clase ApiReceivedListOfObjects debería ser como abajo

public class ApiReceivedListOfObjects<T> { public List<T> element { get; set; } }

4) asegúrese de que su cadena serializada (IndexInfo aquí) se convierta en una estructura inferior a la del comando JsonConvert.DeserializeObject en el paso 2

var resp = @" { ""element"": [ { ""A"": ""A Jones"", ""B"": ""500015763"" }, { ""A"": ""B Smith"", ""B"": ""504986213"" }, { ""A"": ""C Brown"", ""B"": ""509034361"" } ] }";


Acabo de jugar con esto y descubrí un resultado bastante extraño. Digamos que tienes propiedades públicas en tu clase en C # como esta:

public class Customer { public string contact_name; public string company_name; }

entonces debes hacer el truco JSON.stringify como lo sugiere Shyju y llamarlo así:

var customer = {contact_name :"Scott",company_name:"HP"}; $.ajax({ type: "POST", data :JSON.stringify(customer), url: "api/Customer", contentType: "application/json" });

Sin embargo, si define getters y setters en su clase así:

public class Customer { public string contact_name { get; set; } public string company_name { get; set; } }

entonces puedes llamarlo mucho más simple:

$.ajax({ type: "POST", data :customer, url: "api/Customer" });

Esto utiliza el encabezado HTTP:

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

No estoy muy seguro de lo que está sucediendo aquí, pero parece un error (¿característica?) En el marco. Presumiblemente, los diferentes métodos de enlace están llamando a diferentes "adaptadores", y mientras el adaptador para aplicación / json funciona con propiedades públicas, el de datos codificados para formularios no lo hace.

Sin embargo, no tengo idea de cuál sería la mejor práctica.


Asegúrese de que su servicio WebAPI esté esperando un objeto fuertemente tipado con una estructura que coincida con el JSON que está pasando. Y asegúrate de que tienes la cadena JSON que estás POSTANDO.

Aquí está mi JavaScript (usando AngluarJS):

$scope.updateUserActivity = function (_objuserActivity) { $http ({ method: ''post'', url: ''your url here'', headers: { ''Content-Type'': ''application/json''}, data: JSON.stringify(_objuserActivity) }) .then(function (response) { alert("success"); }) .catch(function (response) { alert("failure"); }) .finally(function () { });

Y aquí está mi controlador WebAPI:

[HttpPost] [AcceptVerbs("POST")] public string POSTMe([FromBody]Models.UserActivity _activity) { return "hello"; }



Utilice JSON.stringify () para obtener la cadena en formato JSON, asegúrese de que al hacer la llamada AJAX pase los atributos mencionados a continuación:

  • contentType: ''application / json''
  • tipo de datos: ''json''

A continuación se muestra el código de jQuery para hacer una llamada de post ajax a la api web asp.net:

var product = JSON.stringify({ productGroup: "Fablet", productId: 1, productName: "Lumia 1525 64 GB", sellingPrice: 700 }); $.ajax({ URL: ''http://localhost/api/Products'', type: ''POST'', contentType: ''application/json'', dataType: ''json'', data: product, success: function (data, status, xhr) { alert(''Success!''); }, error: function (xhr, status, error) { alert(''Update Error occurred - '' + error); } });


EDITAR : 31/10/2017

El mismo código / enfoque también funcionará para Asp.Net Core 2.0 . La principal diferencia es que, en el núcleo de asp.net, tanto los controladores de API web como los controladores Mvc se fusionan en un solo modelo de controlador. Por lo tanto, su tipo de retorno podría ser IActionResult o una de sus implementaciones (Ej: OkObjectResult )

Utilizar

contentType:"application/json"

JSON.stringify utilizar el método JSON.stringify para convertirlo en una cadena JSON cuando lo envíe,

Y la carpeta del modelo enlazará los datos json a su objeto de clase.

El siguiente código funcionará bien (probado)

$(function () { var customer = {contact_name :"Scott",company_name:"HP"}; $.ajax({ type: "POST", data :JSON.stringify(customer), url: "api/Customer", contentType: "application/json" }); });

Resultado

contentType propiedad contentType le dice al servidor que estamos enviando los datos en formato JSON. Desde que enviamos una estructura de datos JSON, el enlace del modelo se realizará correctamente.

Si inspecciona los encabezados de la solicitud ajax, puede ver que el valor de Content-Type se establece como application/json .

Si no especifica contentType explícitamente, utilizará el tipo de contenido predeterminado que es application/x-www-form-urlencoded;

Edite en noviembre de 2015 para abordar otras posibles cuestiones planteadas en los comentarios.

Publicar un objeto complejo

Supongamos que tiene una clase de modelo de vista compleja como su parámetro de método de acción de API web como este

public class CreateUserViewModel { public int Id {set;get;} public string Name {set;get;} public List<TagViewModel> Tags {set;get;} } public class TagViewModel { public int Id {set;get;} public string Code {set;get;} }

y su punto final de API es como

public class ProductController : Controller { [HttpPost] public CreateUserViewMode Save([FromBody] CreateUserViewModel m) { // I am just returning the posted model as it is. // You may do other stuff and return different response. // Ex : missileService.LaunchMissile(m); return m; } }

En el momento de escribir este artículo, ASP.NET MVC 6 es la última versión estable y en MVC6, tanto los controladores de api web como los controladores de MVC se heredan de la clase base Microsoft.AspNet.Mvc.Controller .

Para enviar datos al método desde el lado del cliente, el siguiente código debería funcionar bien

//Build an object which matches the structure of our view model class var model = { Name: "Shyju", Id: 123, Tags: [{ Id: 12, Code: "C" }, { Id: 33, Code: "Swift" }] }; $.ajax({ type: "POST", data: JSON.stringify(model), url: "../product/save", contentType: "application/json" }).done(function(res) { console.log(''res'', res); // Do something with the result :) });

El enlace del modelo funciona para algunas propiedades, pero no todas! Por qué ?

Si no decora el parámetro del método de api web con el atributo [FromBody]

[HttpPost] public CreateUserViewModel Save(CreateUserViewModel m) { return m; }

Y envíe el modelo (objeto javascript en bruto, no en formato JSON) sin especificar el valor de la propiedad contentType

$.ajax({ type: "POST", data: model, url: "../product/save" }).done(function (res) { console.log(''res'', res); });

El enlace del modelo funcionará para las propiedades planas del modelo, no para las propiedades donde el tipo es complejo / otro tipo. En nuestro caso, las propiedades Id y Name se vincularán correctamente al parámetro m , pero la propiedad Tags será una lista vacía.

El mismo problema ocurrirá si está utilizando la versión corta, $.post que utilizará el Tipo de contenido predeterminado al enviar la solicitud.

$.post("../product/save", model, function (res) { //res contains the markup returned by the partial view console.log(''res'', res); });


Siguiendo el código para devolver datos en formato json, en lugar de xml -Web API 2:

Ponga la siguiente línea en el archivo global.asax

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);


@model MVCClient.Models.ProductDetails @{ ViewBag.Title = "ProductDetails"; } <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#Save").click(function () { var ProductDetails = new Object(); ProductDetails.ProductName = $("#txt_productName").val(); ProductDetails.ProductDetail = $("#txt_desc").val(); ProductDetails.Price= $("#txt_price").val(); $.ajax({ url: "http://localhost:24481/api/Product/addProduct", type: "Post", dataType:''JSON'', data:ProductDetails, success: function (data) { alert(''Updated Successfully''); //window.location.href = "../Index"; }, error: function (msg) { alert(msg); } }); }); }); </script> <h2>ProductDetails</h2> <form id="form1" method="post"> <fieldset> <legend>ProductDetails</legend> <div class="editor-label"> @Html.LabelFor(model => model.ProductName) </div> <div class="editor-field"> <input id="txt_productName" type="text" name="fname"> @Html.ValidationMessageFor(model => model.ProductName) </div> <div class="editor-label"> @Html.LabelFor(model => model.ProductDetail) </div> <div class="editor-field"> <input id="txt_desc" type="text" name="fname"> @Html.ValidationMessageFor(model => model.ProductDetail) </div> <div class="editor-label"> @Html.LabelFor(model => model.Price) </div> <div class="editor-field"> <input id="txt_price" type="text" name="fname"> @Html.ValidationMessageFor(model => model.Price) </div> <p> <input id="Save" type="button" value="Create" /> </p> </fieldset> </form> <div> @Html.ActionLink("Back to List", "Index") </div> </form> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }