Вопрос по c#, asp.net-web-api – При отправке XML параметр AspNet WebApi POST равен нулю

23

У меня есть служба веб-API, изначально использующая бета-биты, которые я восстановил с использованием битов-кандидатов на выпуск, и теперь у меня возникла эта проблема.

У меня есть действие POST, которое принимает комплексный параметр в качестве единственного параметра. Когда я отправляю запрос с телом в формате json, объект десериализуется, как и ожидалось, но если я отправляю XML, вместо этого параметр имеет значение null.

В бете я обошел это, отключив привязку модели, как описано в блоге Карлоса Фигейры.Отключение привязки модели в бета-версии ASP.NET Web API

В RC, однако, они удалили IRequestContentReadPolicy, который реализовывал этот метод.

Мои действия:

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

Моя модель:

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

Я тестирую с помощью Fiddler для отправки запросов в сервис.

Это работает и возвращает мне ожидаемые результаты.

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"
    }
  ]
}

Это терпит неудачу, потому что параметр requestValues является нулем

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>
Подробности в этом [вопросе] [1] ... [1]:stackoverflow.com/questions/14068288/… barrypicker

Ваш Ответ

2   ответа
5

У меня была та же проблема, что и у вас, и я нашел решение, сериализовав объект с помощью XmlMediaTypeFormatter, как описано здесь:http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#testing_object_serialization, Я использовал код в «Сериализации объектов тестирования» раздел в нижней части статьи, и заменил его объект Person на мою модель.

Когда я сериализовал свой объект, я заметил, что следующие атрибуты были добавлены в корневой узел:

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

Если вы добавите эти атрибуты в ваш xml примерно так, ваш контроллер должен правильно сериализовать объект 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>
24

Добавив следующие строки в метод ApplicationStart () в вашем Global.asax.cs, ваш оригинальный XML-запрос должен работать:

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

По умолчанию веб-API использует класс DataContractSerializer, который требует дополнительной информации в запросе XML.

Мне кажется, что XmlSerializer работает более плавно, поскольку мне не нужно добавлять пространство имен модели в каждый запрос XML.

Еще раз, я нашел свою информацию в статье Майка Уоссона:http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

не работает для меня. теперь приложение возвращает "тип носителя" объекта запроса "application / xml"; не поддерживается для этого ресурса. & quot ;.
это было решение, которое я искал. У меня была такая же проблема, где JSON будет работать нормально, но объект всегда будет нулевым при использовании XML

Похожие вопросы