2017-03-29 1 views
1

다음 코드에서 Json.Net을 사용하여 개체를 serialize합니다. 이 Json에는 유형 이름이 임베드되어 있습니다. 그런 다음 유형 이름 중 하나를 변경하여 오류를 유도합니다 (테스트입니다. 기존 프로젝트의 실제 문제를 처리하고 있습니다). Json을 비 직렬화 할 때, 필자는 입력 된 유형 이름을 가진 속성에 대해 null 값을 갖는 객체를 다시 가져올 것으로 예상합니다. 대신 serializer가 쓰레기를 반환하고 null을 반환합니다. 내 기대가 맞습니까? 어떻게 든 설정을 변경하여 루트 객체에 null이 아닌 객체를 가져올 수 있습니까? 두 번째 오류는 serializer에 버그가 있음을 나타냅니다.Json.Net으로 알 수없는 형식을 비 직렬화 할 때 예기치 않은 오류가 발생했습니다.

static public class JsonTest 
{ 
    static public void Test() 
    { 
     // Create test object 
     A a = new A 
     { 
      MyTest = new MyTest(), 
     }; 

     // Serialize it. 
     string json = JsonConvert.SerializeObject(a, new JsonSerializerSettings 
     { 
      TypeNameHandling = TypeNameHandling.Auto 
     }); 

     // Fiddle class name to induce error 
     json = json.Replace("+MyTest", "+MyTest2"); 

     // Before: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest, <Assembly>"}} 
     // After: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest2, <Assembly>"}} 

     // Deserialize 
     A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings 
     { 
      TypeNameHandling = TypeNameHandling.Auto, 
      Error = (object sender, ErrorEventArgs e) => 
      { 
       e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type 
      } 
     }); 

     // A second error occurs: Error = {Newtonsoft.Json.JsonSerializationException: Additional text found in JSON string after finishing deserializing object.... 
     // a2 is null 
    } 

    public class A 
    { 
     public ITest MyTest { get; set; } 
    } 

    public interface ITest { } 
    public class MyTest : ITest { } 
} 

답변

1

issue 업데이트this submission에 Json.NET 10.0.2에서 수정되었습니다.

원래 답변

이 Json.NET에서 버그가 수 있도록 보인다. 내가 JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead을 설정하면 다음 문제는 사라집니다 :

// Deserialize 
A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings 
{ 
    TypeNameHandling = TypeNameHandling.Auto, 
    MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead, 
    Error = (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) => 
    { 
     Debug.WriteLine(e.ErrorContext.Path); 
     e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type 
    } 
}); 

Debug.Assert(a2 != null); // No assert. 

을하지만, 오히려 단지 첫번째로보다, JSON 개체의 아무 곳이나 위치 "$type"를 포함하는 메타 데이터 속성을 읽는 가능이 설정을 켤 필요는 없습니다 재산. 대부분 비 직렬화를 시작하기 전에 전체 JSON 객체를 미리로드해야하기 때문에 우연히 버그가 수정 될 가능성이 높습니다.

원할 경우 report an issue 수 있습니다. 비트 디버깅

문제는 내부 MyTest 객체가 생성 될 수 없으므로, 예외가 걸려와 외부 개체 A를 채우는 동안 JsonSerializerInternalReader.PopulateObject() 처리, 그 보인다. 이 때문에 JsonReader은 안쪽의 중첩 된 개체를 지나치게 진행하지 않으므로 판독기와 serializer는 일관성이없는 상태가됩니다. 이것은 두 번째 예외와 결국 Additional text found in JSON string after finishing deserializing object. Path '' 예외를 설명합니다.

+1

[문제] (https://github.com/JamesNK/Newtonsoft.Json/issues/1266#event-1025062578)로 신고했으며 문제가 수정되었습니다. – AbleArcher