( Первоначальный вопрос решен, но в разделе обновления ниже у меня есть вопросы о том, почему то, что я сделал, работает )
У нас есть проект 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 без какой-либо дополнительной информации (которую я не знаю, как дать).
Так что теперь это работает, но я толькоесть предположения относительно того, как и / или почему. Может ли какое-либо тело указать мне правильное направление или сообщить, почему то, что я сделал, исправило это?