Десериализация ObjectResult с помощью declaredType правильно

#c# #asp.net-core #deserialization

Вопрос:

Проблема

Моя структура API в настоящее время тесно связана с внешней структурой API в одном классе из-за десериализации одного типа.

Более подробная информация

Десериализация ObjectResult из внешнего API использует свойство declaredType с пользовательским типом ErrorDetails, включая пространство имен внешнего API. Десериализация работает только в том случае, если в моем решении есть тип ErrorDetails с тем же самым пространством имен, в противном случае она выдает:

Ньютонсофт.Json.Исключение JsonSerializationException: Ошибка преобразования значения «x.y.ErrorDetails, x, Версия=1.0.0.0, Культура=нейтральная, PublicKeyToken=null» в тип «Система».Типа». Путь «Объявленный тип», строка 1, позиция 6928. —> Система.Исключение ArgumentException: Не удалось выполнить приведение или преобразование из системы.Строка в System.Type.

Я десериализуюсь с

 JsonConvert.DeserializeObject<ObjectResult>(content);
 

Вопрос

Я думал попробовать, ObjectResult<ErrorDetails> но это из NET framework, а не из NET Core 3.1, который использует мой API. Есть какие-нибудь идеи о том, как это правильно решить?

Json для сериализации

 {
"value":{//this is ErrorDetails
    "stackTrace": "...",
    "errors":{
        "gameUrl":[
            "GameUrl cannot be parsed"
        ]
    },
    "type":"https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title":"One or more validation errors occurred.",
    "extensions":{
        
    }
},
"formatters":[
    
],
"contentTypes":[
    
],
"declaredType":"x.y.ErrorDetails, x, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"statusCode":400
}
 

Сообщения об ошибках в моем API с другим пространством имен не работают

 namespace m.n
{
    public class ErrorDetails : ProblemDetails //Microsoft.AspNetCore.Mvc
    {
        public ErrorDetails()
        {
        }

        public string StackTrace { get; set; }

        public string InnerException { get; set; }

        public string Identifier { get; internal set; }
    }
}
 

Комментарии:

1. Не могли бы вы, пожалуйста, опубликовать json и полный тип, в который вы пытаетесь десериализоваться?

2. @LasseV.Карлсен закончил

Ответ №1:

Основываясь на сериализованной строке Json, классы должны, как показано ниже:

 public class ErrorDetails
{
    [JsonProperty("value")]
    public Value Value { get; set; }

    [JsonProperty("formatters")]
    public List<object> Formatters { get; set; }

    [JsonProperty("contentTypes")]
    public List<object> ContentTypes { get; set; }

    [JsonProperty("declaredType")]
    public string DeclaredType { get; set; }

    [JsonProperty("statusCode")]
    public int StatusCode { get; set; }
}
public class Errors
{
    [JsonProperty("gameUrl")]
    public List<string> GameUrl { get; set; }
}

public class Extensions
{
}

public class Value
{
    [JsonProperty("stackTrace")]
    public string StackTrace { get; set; }

    [JsonProperty("errors")]
    public Errors Errors { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("title")]
    public string Title { get; set; }

    [JsonProperty("extensions")]
    public Extensions Extensions { get; set; }
}
 

Затем пользовательский JsonConvert.DeserializeObject метод для десериализации строки JSON:

         var jsonstring = "{"value":{"stackTrace":"...","errors":{"gameUrl":["GameUrl cannot be parsed"]},"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","extensions":{}},"formatters":[],"contentTypes":[],"declaredType":"x.y.ErrorDetails, x, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","statusCode":400}";
        //using Newtonsoft.Json;
        var result = JsonConvert.DeserializeObject<ErrorDetails>(jsonstring);
 

результат, как показано ниже:

введите описание изображения здесь