fromuri frombody from example body c# asp.net-web-api

frombody - web api post example c#



El parámetro ASTNet WebApi POST es nulo cuando se envía XML (2)

Tengo un servicio de API web que originalmente usaba bits beta que he reconstruido usando los bits de lanzamiento de candidato y ahora estoy teniendo este problema.

Tengo una acción POST que toma una opción compleja como único parámetro. Cuando envío la solicitud con el cuerpo en formato json, el objeto se deserializa como se esperaba, pero si envío XML en su lugar, el parámetro es nulo.

En la versión beta trabajé al respecto deshabilitando la vinculación del modelo como se describe en la publicación del blog de Carlos Figueira. Desactivación de la vinculación del modelo en las API web ASP.NET Beta

Sin embargo, en RC han eliminado el IRequestContentReadPolicy que este método estaba implementando.

Mi acción:

public List<Models.Payload> Post([FromBody]Models.AimiRequest requestValues) { try { if (requestValues == null) { var errorResponse = new HttpResponseMessage(); errorResponse.StatusCode = HttpStatusCode.NotFound; errorResponse.Content = new StringContent("parameter ''request'' is null"); throw new HttpResponseException(errorResponse); } var metadataParams = new List<KeyValuePair<string, string>>(); foreach (Models.MetadataQueryParameter param in requestValues.Metadata) { metadataParams.Add(new KeyValuePair<string, string>(param.Name, param.Value)); } List<Core.Data.Payload> data = _payloadService.FindPayloads(metadataParams, requestValues.ContentType, requestValues.RuleTypes); var retVal = AutoMapper.Mapper.Map<List<Core.Data.Payload>, List<Models.Payload>>(data); return retVal; // new HttpResponseMessage<List<Models.Payload>>(retVal); } catch (System.Exception ex) { _logger.RaiseError(ex); throw; } }

Mi modelo:

public class AimiRequest { public MetadataQueryParameter[] Metadata { get; set; } public string ContentType { get; set; } public string RuleTypes { get; set; } } public class MetadataQueryParameter { public string Name { get; set; } public string Value { get; set; } }

Estoy probando el uso de Fiddler para enviar solicitudes al servicio.

Esto funciona y me devuelve los resultados esperados.

POST http://localhost:51657/api/search HTTP/1.1 User-Agent: Fiddler Content-Type: application/json; charset=utf-8 Accept: application/json Host: localhost:51657 Content-Length: 219 { "ContentType":null, "RuleTypes":null, "Metadata":[ { "Name":"ClientName", "Value":"Client One" }, { "Name":"ClientName", "Value":"Client Two" } ] }

Esto falla porque el parámetro requestValues ​​es nulo

POST http://localhost:51657/api/search HTTP/1.1 User-Agent: Fiddler Content-Type: application/xml; charset=utf-8 Accept: application/xml Host: localhost:51657 Content-Length: 213 <AimiRequest> <ContentType /> <RuleTypes /> <Metadata> <MetadataQueryParameter> <Name>ClientName</Name> <Value>Client One</Value> </MetadataQueryParameter> <MetadataQueryParameter> <Name>ClientName</Name> <Value>Client Two</Value> </MetadataQueryParameter> </Metadata> </AimiRequest>


Al agregar las siguientes líneas al método ApplicationStart () en su Global.asax.cs, su solicitud XML original debería funcionar:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

De forma predeterminada, la API web utiliza la clase DataContractSerializer, que requiere información adicional en la solicitud XML.

El XmlSerializer parece funcionar más fácilmente para mí, ya que no tengo que agregar el nombre del modelo a cada solicitud XML.

Una vez más, encontré mi información en el artículo de Mike Wasson: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter


Estaba teniendo el mismo problema que usted, y encontré la solución serializando el objeto usando XmlMediaTypeFormatter como se describe aquí: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#testing_object_serialization . Usé el código en la sección "Serialización de objetos de prueba" en la parte inferior del artículo, y reemplacé su objeto Person con mi modelo.

Cuando serialicé mi objeto, noté que los siguientes atributos se agregaron al nodo raíz:

xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL"

Si agrega estos atributos a su xml, su controlador debe serializar correctamente el objeto requestValues:

<AimiRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL"> <ContentType /> <RuleTypes /> <Metadata> <MetadataQueryParameter> <Name>ClientName</Name> <Value>Client One</Value> </MetadataQueryParameter> <MetadataQueryParameter> <Name>ClientName</Name> <Value>Client Two</Value> </MetadataQueryParameter> </Metadata> </AimiRequest>