Десериализация Microsoft.OData.Edm.Date - PullRequest
0 голосов
/ 31 октября 2018

Я использую JsonConvert.DeserializeObject для десериализации объекта, и подпрограмма наткнулась на поле даты, которое она не знала, как обрабатывать. Вот ошибка:

Error converting value \"2018-08-22\" to type 
'System.Nullable`1[Microsoft.OData.Edm.Date]'. Path 'value[3].actualclosedate'

Microsoft.OData.Edm.Date - это объект структуры, используемый Microsoft для хранения данных только по дате.

Я пытаюсь создать собственный конвертер для этого типа поля, но не могу заставить его работать должным образом.

Вот мой код конвертера:

public class EdmDateConverter : DateTimeConverterBase
{
    public override bool CanConvert(Type objectType) { return objectType == typeof(global::Microsoft.OData.Edm.Date); }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return (global::Microsoft.OData.Edm.Date)global::Microsoft.OData.Edm.Date.Parse(reader.ReadAsString());
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        string myDate = ((global::Microsoft.OData.Edm.Date)value).Year.ToString("D4");
        myDate += "-";
        myDate += ((global::Microsoft.OData.Edm.Date)value).Month.ToString("D2");
        myDate += "-";
        myDate += ((global::Microsoft.OData.Edm.Date)value).Day.ToString("D2");

        writer.WriteValue(myDate);
    }
}

А вот как я пытался связать его с глобальным списком конвертеров:

JsonConvert.DefaultSettings = () =>
            {
                var settings = new JsonSerializerSettings();
                settings.Converters.Add(new EdmDateConverter());
                //settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                return settings;
            };

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

Кто-нибудь может дать мне несколько советов по этому вопросу?

1 Ответ

0 голосов
/ 31 октября 2018

Ваше сообщение об ошибке указывает на то, что десериализованный тип элемента имеет значение Nullable<Microsoft.OData.Edm.Date>, но ваш метод CanConvert не учитывает вероятность того, что objectType может быть обнуляемым .

Вы можете исправить это, изменив CanConvert следующим образом:

public class EdmDateConverter : DateTimeConverterBase
{
    public override bool CanConvert(Type objectType) 
    {
        var type = Nullable.GetUnderlyingType(objectType) ?? objectType;
        return type == typeof(global::Microsoft.OData.Edm.Date); 
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.SkipComments().TokenType == JsonToken.Null)
            return null;
        return (global::Microsoft.OData.Edm.Date)global::Microsoft.OData.Edm.Date.Parse(reader.ReadAsString());
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        string myDate = ((global::Microsoft.OData.Edm.Date)value).Year.ToString("D4");
        myDate += "-";
        myDate += ((global::Microsoft.OData.Edm.Date)value).Month.ToString("D2");
        myDate += "-";
        myDate += ((global::Microsoft.OData.Edm.Date)value).Day.ToString("D2");

        writer.WriteValue(myDate);
    }
}

public static partial class JsonExtensions
{
    public static JsonReader SkipComments(this JsonReader reader)
    {
        while (reader.TokenType == JsonToken.Comment && reader.Read())
            ;
        return reader;
    }
}

Примечания:

  • Также необходимо проверить наличие токена null в ReadJson(). WriteJson(), с другой стороны, никогда не вызывается для значения null; вместо этого Json.NET пишет null автоматически.

  • Могут быть другие проблемы с вашим кодом, поскольку ваш вопрос не включает пример JSON, код десериализации или классы c #.

...