ASP.NET Core Web API Автоматическая десериализация параметров JSON не работает - PullRequest
0 голосов
/ 30 мая 2018

У меня есть простой контроллер, который принимает один параметр из тела запроса 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;
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Если вы хотите глобальные настройки, вы можете указать JsonSerializerSetting на уровне приложения, используя расширение AddJsonOptions.Прочтите о здесь .

services.AddMvc()
.AddJsonOptions(opt =>
{
    if (opt.SerializerSettings != null)
    {
            opt.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto,
            opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore,
            opt.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore
    }
});

AddJsonOptions определен в Microsoft.AspNetCore.Mvc.Formatters.Json пакет nuget.

0 голосов
/ 30 мая 2018

Ваша проблема в интерфейсе IDocument, который не может быть десериализован из коробки, поскольку десериализатор не может знать, какой конкретный класс использовать.

Также убедитесь, что создан модульный тест, которыйберет необработанный JSON, который вы передадите методу контроллера, и убедитесь, что его можно десериализовать.

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