2017-03-09 15 views
0

Imシリアル化/シリアライズするデシリアライズを試みると全く同じクラス構造になります。したがって、プロパティのデフォルト値が提供されていなくても、エラーが発生するはずです。私は、メンバーの処理と契約の決議をして、それを達成したと思ったが、それはうまくいかなかった。例外的に例外がスローされることはありません(契約レゾルバで明示的に指定する必要があります)。Newtonsoft.Json:AllowNullバグ?

そして、ここでは私のシリアライザです:

public sealed class JsonSerializer : ISerializer 
{ 
    private readonly JsonSerializerSettings _settings = new JsonSerializerSettings 
    { 
     ContractResolver = new RequireObjectPropertiesContractResolver(),//Everything required. Null are allowed. 
     MissingMemberHandling = MissingMemberHandling.Error, //If something missing in target class - it should throw error. 
     Formatting = Formatting.Indented 
    }; 

    public object Deserialize(string input, Type type) 
    { 
     return JsonConvert.DeserializeObject(input, type, _settings); 
    } 

    public string Serialize(object input) 
    { 
     return JsonConvert.SerializeObject(input, _settings); 
    } 

    private class RequireObjectPropertiesContractResolver : DefaultContractResolver 
    { 
     protected override JsonObjectContract CreateObjectContract(Type objectType) 
     { 
      var contract = base.CreateObjectContract(objectType); 
      contract.ItemRequired = Required.AllowNull; 
      return contract; 
     } 
    } 
} 

そして、ここで私が働いて得ることができないテストケースである:

[DataContract] 
    private class TestInput 
    { 
     [DataMember] 
     public string Value0 { get; set; } 

     [DataMember] 
     public string Value1 { get; set; } 

     [DataMember] 
     public Inner Inner { get; set; } 
    } 

    [DataContract] 
    private class Inner 
    { 
     [DataMember] 
     public string NewValue0 { get; set; } 
    } 

    [TestMethod] 
    public void TestSerialization() 
    { 
     using (var kernel = new StandardKernel(new MyModule())) 
     { 
      var serializer = kernel.Get<ISerializer>(); 

      //It should throw error because Inner not provided as null (not thrown) 
      string json = "{\"Value0\":\"test0\", \"Value1\":\"test1\"}"; 
      Extensions.Throws<Exception> (()=>serializer.Deserialize(json, typeof(TestInput))); 

      //It should throw error because nothing were provided as null (not thrown) 
      json = "{}"; 
      Extensions.Throws<Exception>(() => serializer.Deserialize(json, typeof(TestInput))); 

      //this one is correct one (no problems here) 
      json = "{\"Value0\":\"test0\", \"Value1\":\"test1\", \"Inner\":null}"; 
      Extensions.NotThrows(()=>serializer.Deserialize(json, typeof(TestInput))); 
     } 
    } 

これら二つの試験だけで合格しません。

+0

最新バージョンのNewtonsoftのJSONシリアライザでは、次のように表示されます。 "追加情報:必要なプロパティ 'Inner'がJSONに見つかりませんパス '、1行目、36桁目。 – john

+0

ニュートンソフトのJSON 9.0.1を使用しています。私のプロジェクトを完全にきれいにして再構築しました。それでも、成功はありません。 – eocron

+0

フレームワークのバージョン?私はテストで4.5.1に対してコンパイルされたコンソールアプリケーションを使用しています。 – john

答えて

1

しばらくして、私はそれを機能させることができました。代わりに、契約自体、すべてのプロパティの

private class RequireObjectPropertiesContractResolver : DefaultContractResolver 
    { 
     protected override JsonObjectContract CreateObjectContract(Type objectType) 
     { 
      var contract = base.CreateObjectContract(objectType); 
      contract.ItemRequired = Required.AllowNull; 
      return contract; 
     } 

     protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
     { 
      var properties = base.CreateProperties(type, memberSerialization); 
      foreach (var p in properties) 
      { 
       p.Required = Required.AllowNull; 
      } 
      return properties; 
     } 
    } 

だけsetted Required.AllowNull:のDataContractので、私はちょうど彼らが設定されている値を再割り当て方法にあった私のクラスに適用されます。