У меня есть простой контроллер, который принимает один параметр из тела запроса POST.Обычно он должен автоматически десериализовать его из JSON в тип объекта, но это не удается.Когда я пытаюсь десериализовать это самостоятельно, это работает без проблем.Вот некоторый код:
Контроллер (переменная documentCommand равна нулю):
public async Task<IActionResult> Create([FromBody]CreateDocumentCommand documentCommand)
{
if (documentCommand == null)
{
return StatusCode(403); //Deserialization fails, documentCommand is null
}
//we have to reach this :(
return Json(documentCommand.Document.Id);
}
Вот как я его сериализую и как я проверяю, еслион сможет десериализовать его:
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
string serialized = JsonConvert.SerializeObject(item, jsonSerializerSettings);
CreateDocumentCommand deserialized = JsonConvert.DeserializeObject<CreateDocumentCommand>(serialized, jsonSerializerSettings);
В моем классе CreateDocumentCommand у меня есть свойство интерфейса, и при удалении TypeNameHandling = TypeNameHandling.Auto происходит сбой во второйНапример.
Есть ли способ сказать десериализатору MVC принять во внимание TypeNameHandling ?Мне кажется, что он пропускает это.
РЕДАКТИРОВАТЬ Еще немного кода:
public class CreateDocumentCommand : Command, ICreateDocumentCommand
{
public CreateDocumentCommand()
{
}
public IDocument Document { get; set; }
}
МОЕ РЕШЕНИЕ: Добавил тот ConcreteTypeConverter, который я нашелпо ссылке, предоставленной Бабаком Наффасом и внесшей некоторые изменения, потому что я получал некоторые исключения из круговой ссылки.Также добавлен [JsonConverter (typeof (ConcreteTypeConverter))]] перед классом CreateDocumentCommand.
public class ConcreteTypeConverter<T> : JsonConverter
{
static bool read = false;
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
serializer.TypeNameHandling = TypeNameHandling.Auto;
serializer.NullValueHandling = NullValueHandling.Ignore;
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
return serializer.Deserialize<T>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override bool CanRead
{
get
{
read = !read;
return read;
}
}
}