Публикация XML в webapi только привязывает несобранные свойства в модели запроса [FromBody] - PullRequest
0 голосов
/ 30 октября 2019

( Первоначальный вопрос решен, но в разделе обновления ниже у меня есть вопросы о том, почему то, что я сделал, работает )

У нас есть проект asp.net webApi с одним POSTОперация, для которой раньше требовалось только принять запрос, отформатированный как JSON, и отвечать на него любым заголовком accept (будь то application / xml или application / json).

Теперь POST должен иметь возможность принимать XML какзапрос. Это просто вопрос установки типа контента в application / xml, и все должно быть хорошо.

Однако привязка модели не совсем работает, она работает частично, но не все

Вот упрощенная версия модели:

    [DataContract(Namespace = "")]
    public class PostModel
    {
        [DataMember(Name = "Identifier", Order = 0)]
        [Required]
        public string Identifier { get; set; }

        [DataMember(Name = "ReturnNullItems", Order = 1)]
        public bool? ReturnNullItems { get; set; }

        [DataMember(Name = "RequestedItems", Order = 2)]
        [Required]
        public List<string> RequestedItems { get; set; }

        [DataMember(Name = "Mileage", Order = 3)]
        public int Mileage { get; set; }
    }

Вот упрощенная версия метода контроллера:

    [HttpPost]
    [Route("")]
    public async Task<ResponseMessageResult> Post([FromBody]PostModel postModel)
    {

        var formatter = GetMediaTypeFormatter();

        if (postModel == null)
        {
            var message = new ErrorMessage { Message = "Malformed Request"};
            return GetResponseMessageResult(message, HttpStatusCode.BadRequest, formatter);
        }

        if (!ModelState.IsValid)
        {
            var message = new ErrorMessage { Message = string.Join("; ", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage)) };
            return GetResponseMessageResult(message, HttpStatusCode.BadRequest, formatter);
        }
    }

Вот примерный фрагмент тела XML из запроса:

<PostModel>
   <Identifier>ya05fom</Identifier>
   <ReturnNullItems>false</ReturnNullItems>
   <RequestedItems>
      <string>EngineCapacity</string>
      <string>FuelType</string>
      <string>ForwardGears</string>
      <string>Transmission</string>   
   </RequestedItems>
   <Mileage>20000</Mileage>
</PostModel>    

Мы видим, что в postModel свойства Identifer, ReturnNullItems и Пробег, которые являются простыми свойствами, связаны, но свойство RequestedItems, являющееся свойством коллекции, не является.

Так что вpostModel мы видим:

  • postModel.Identifer -> "ya05fom"
  • postModel.ReturnNullItems -> false
  • postModel.M Пробег -> 20000
  • postModel.RequestItems -> null

Свойство RequestItems имеет значение null. Я пытался, чтобы это свойство было списком строк и строковым массивом, и ни одно из них не работает.

Так что, похоже, есть проблема, связывающая вложенные дочерние элементы в xml со свойством коллекции в классе PostModel, ноЯ просто в растерянности относительно того, что мне не хватает.

ОБНОВЛЕНИЕ :

Благодаря Мэтту Дж в комментариях, его комментарий дал мне толчок в отношениичто посмотреть в документации .net, и это подтолкнуло меня к тому, что попробовать.

Ранее мне приходилось добавлять XmlMediaTypeFormatter в форматтеры на GlabalConfiguration:

GlobalConfiguration.Configuration.Formatters.Add(new System.Net.Http.Formatting.XmlMediaTypeFormatter());

Тамбыло также закомментировано это ниже:

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

Я прокомментировал две вышеупомянутые строки и вуаля, это работает.

Я предполагаю, что я говорю десериализатору использовать System.Net.Http.Formatting.XmlMediaTypeFormatter для десериализации тела запроса. Я также предполагаю, что стандартный DataContractSerialiser не очень хорошо справляется с десериализацией xml с иерархическим xml без какой-либо дополнительной информации (которую я не знаю, как дать).

Так что теперь это работает, но я толькоесть предположения относительно того, как и / или почему. Может ли какое-либо тело указать мне правильное направление или сообщить, почему то, что я сделал, исправило это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...