2016-10-09 4 views
5

मुझे एक अजीब समस्या का सामना करना पड़ा: ऐसी स्ट्रिंग {"text":"s","cursorPosition":189,"dataSource":"json_northwind", जो सही जेसन नहीं है, यह अभी भी सफलतापूर्वक पार्स हो गया है।न्यूटॉन्सॉफ्ट.जेसन पार्स गलत जेसन

var s = @"{""text"":""s"",""cursorPosition"":189,""dataSource"":""json_northwind"","; 
var request = JsonConvert.DeserializeObject<CompletionDataRequest>(s); 
request.Text.Should().Be("s"); 
request.CursorPosition.Should().Be(189); 
request.DataSource.Should().Be("json_northwind"); 
request.Project.Should().BeNull(); 

पुस्तकालय कुछ को पार्स नियम ढीला है करता है या हो सकता है यह एक बग है:

public class CompletionDataRequest 
{ 
    public CompletionDataRequest(string text, int cursorPosition, string dataSource, string project) 
    { 
     Text = text; 
     CursorPosition = cursorPosition; 
     DataSource = dataSource; 
     Project = project; 
    } 

    public string Text { get; } 
    public int CursorPosition { get; } 
    public string DataSource { get; } 
    public string Project { get; } 
} 

यहाँ परीक्षण है कि आश्चर्यजनक रूप से सफल होता है:

इस वर्ग है? मैं पुस्तकालय संस्करण 9.0.1

उत्तर

5

अद्यतन

एक मुद्दा Deserializing unclosed object succeeds when the object has a parameterized constructor. #1038 इस प्रश्न के लिए खोला गया था हूँ। यह 0721bd4 में परिवर्तन सेट Json.NET release 10.0.1 में तय किया गया था।

मूल उत्तर

आप Json.NET में एक बग मिल गया है। यह तब उत्पन्न होता है जब आपकी ऑब्जेक्ट पैरामीटरयुक्त कन्स्ट्रक्टर के साथ बनाई जाती है। अगर मैं एक गैर पैरामिट्रीकृत निर्माता है करने के लिए अपने ऑब्जेक्ट को संशोधित:

public class CompletionDataRequest 
{ 
    public CompletionDataRequest(string text, int cursorPosition, string dataSource, string project) 
    { 
     Text = text; 
     CursorPosition = cursorPosition; 
     DataSource = dataSource; 
     Project = project; 
    } 

    [JsonConstructor] 
    private CompletionDataRequest() 
    { 
    } 

    [JsonProperty] 
    public string Text { get; private set; } 
    [JsonProperty] 
    public int CursorPosition { get; private set; } 
    [JsonProperty] 
    public string DataSource { get; private set; } 
    [JsonProperty] 
    public string Project { get; private set; } 
} 

फिर Json.NET सही ढंग से एक JsonSerializationException फेंक देते हैं।

बग का कारण निम्नानुसार है। पैरामीटर रहित कन्स्ट्रक्टर के साथ ऑब्जेक्ट बनाते समय, जेसन.नेट पहले ऑब्जेक्ट बनाता है, फिर इसे JsonSerializerInternalReader.PopulateObject() के साथ पॉप्युलेट करता है।

private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id) 
    { 
     bool finished = false; 
     do 
     { 
      switch (reader.TokenType) 
      { 
       case JsonToken.PropertyName: 
       { 
        // Read and process the property. 
       } 
       case JsonToken.EndObject: 
        finished = true; 
        break; 
       case JsonToken.Comment: 
        // ignore 
        break; 
       default: 
        throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); 
      } 
     } while (!finished && reader.Read()); 

     if (!finished) 
     { 
      ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); 
     } 

     return newObject; 
    } 

जैसा कि आप देख सकते हैं, वहाँ की पुष्टि है कि वस्तु वास्तव में बंद कर दिया है तर्क if (!finished) है: यह विधि निम्नलिखित (सरलीकृत) तर्क है।

हालांकि, जब एक पैरामिट्रीकृत निर्माता के साथ एक वस्तु बनाने, गुण से पहले वस्तु का निर्माण किया है पढ़ रहे हैं, JsonSerializerInternalReader.ResolvePropertyAndCreatorValues() का उपयोग कर:

private List<CreatorPropertyContext> ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType) 
    { 
     List<CreatorPropertyContext> propertyValues = new List<CreatorPropertyContext>(); 
     bool exit = false; 
     do 
     { 
      switch (reader.TokenType) 
      { 
       case JsonToken.PropertyName: 
        // Read and process the property. 
        break; 
       case JsonToken.Comment: 
        break; 
       case JsonToken.EndObject: 
        exit = true; 
        break; 
       default: 
        throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); 
      } 
     } while (!exit && reader.Read()); 

     return propertyValues; 
    } 

तुम वहाँ सही किया जा रहा exit के लिए कोई समकक्ष जांच है देख सकते हैं।

इसके लिए एक समस्या Deserializing unclosed object succeeds when the object has a parameterized constructor. #1038 खोला गया था।

+0

@ Łukasz - ठीक है, मैं आगे बढ़ गया और इस मुद्दे की सूचना दी, [जब ऑब्जेक्ट में पैरामीटरयुक्त कन्स्ट्रक्टर होता है तो desclializing unclosed ऑब्जेक्ट सफल होता है। # 1038] (https://github.com/JamesNK/Newtonsoft.Json/issues/1038)। – dbc

+1

ओह, मैं प्रगति पर था, लेकिन मैं तब रुक जाऊंगा। मदद के लिए धन्यवाद –

संबंधित मुद्दे