4

次のクラスに逆シリアル化しています。

public abstract class Tail_Metrics
{
    [DataMember(Order = 1, IsRequired = true)]
    public double probability { get; set; }
    [DataMember(Order = 2, IsRequired = true)]
    public double min { get; set; }
    [DataMember(Order = 3)]
    public double max { get; set; }
    [DataMember(Order = 4, IsRequired = true)]
    public double mean { get; set; }
    [DataMember(Order = 5)]
    public double variance { get; set; }
    [DataMember(Order = 6)]
    public double skewness { get; set; }
    [DataMember(Order = 7)]
    public double kurtosis { get; set; }
}
public class Layer_Tail_Metrics : Tail_Metrics { }

ご覧のとおり、確率、最小、平均は必須で、残りはオプションです。

サーバーから次の JSON 応答を逆シリアル化しています。

{
    "probability": 0.01,
    "mean": 0,
    "variance": 0,
    "min": 0,
    "max": 0
}

そして、私はNewtonsoft.Json.JsonSerializationExceptionメッセージを受け取っていますRequired property 'probability' not found in JSON. Path '', line 1, position 95.

それはどうしてですか?プロパティは JSON に存在し、正しい型を持っています!

IsRequired最も奇妙なことは、属性からプロパティを削除するDataMemberと、この例外が発生しなくなり、オブジェクトが完全に逆シリアル化されることです。いずれかのIsRequiredプロパティが true に設定されている場合、そのプロパティは同じ例外をスローします。


逆シリアル化コードは次のとおりです。

T retVal = converter.Deserialize<T>(response);

どこtypeof(T)ですかLayer_Tail_Metrics

converterRestSharp.Deserializers.IDeserializer次のように実装するクラスです。

using Newtonsoft.Json;
public class RestSharp...Converter :  RestSharp.Deserializers.IDeserializer
{
    //...
    private JsonSerializerSettings deserializerSettings;

    public RestSharpDataContractNewtonsoftJsonConverter()
    {
        Culture = CultureInfo.InvariantCulture;
        ContentType = "application/json";

        deserializerSettings = new JsonSerializerSettings()
        {
            Converters = new JsonConverter[]{
                new Newtonsoft.Json.Converters.IsoDateTimeConverter()
            }
        };
    }

    public T Deserialize<T>(IRestResponse response)
    {
        return Deserialize<T>(response.Content);
    }
    public T Deserialize<T>(String json)
    {
        return JsonConvert.DeserializeObject<T>(json, deserializerSettings);
    }
}

エラーを再現する小さなスタンドアロン サンプルを次に示します。

[DataContract()]
public abstract class Tail_Metrics
{
    [DataMember(IsRequired = true)]
    public double probability { get; set; }

    public Tail_Metrics(double probability)
    {
        this.probability = probability;
    }
}
public class Layer_Tail_Metrics : Tail_Metrics
{
    public Layer_Tail_Metrics(double probability) : base(probability) { }
}

class TestClass
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""probability"": 0.01
        }";
        Layer_Tail_Metrics tm = Newtonsoft.Json.JsonConvert.DeserializeObject<Layer_Tail_Metrics>(json);
    }
}
4

1 に答える 1