2017-01-10 2 views
1

Я ошеломлен - но, возможно, потому, что я несведущий - что JsonConvert.Deserialize<>() будет разбирать этот искаженный JSON без жалобы:JSON.NET позволяет искаженной JSON во время десериализации

{"Items": ["hello" "goodbye",]} 

Оказывается использовать некоторый набор эвристики для сделайте эту работу, и в этом случае я думаю, что «правильно». Но тот факт, что он сделал это беззвучно, касается совершенно, поскольку я не знаю, чему я могу доверять поведению.

Старые версии JSON.NET (6.x) вызывают ошибку, но более новые версии (9.x) НЕ. Кроме того, просто использование универсальной версии Deserialize() будет жаловаться на синтаксическую ошибку - это просто общий, который этого не делает.

Я попытался опубликовать репродукцию на dotnetfiddle, но это не работает, потому что dotnetfiddle всегда загружает версию 6.x JSON.NET, даже если вы запрашиваете другую версию. (См. https://dotnetfiddle.uservoice.com/forums/228764--net-fiddle-ideas/suggestions/10782315-load-the-specified-version-of-json-net-rather-than).

Итак, вот полный реестр (включая код, который выводит версию используемой версии Netwonsoft.Json.Dll). Он печатает 2 (потому что он «успешно» анализирует JSON) под 9x версиями JSON.NET. Под 6.x они выдают ошибку (как мне кажется, она должна).

using System; 
using Newtonsoft.Json; 

public class Program 
{ 
    public static void Main() 
    { 

     Console.WriteLine(typeof(JsonConvert).Assembly.GlobalAssemblyCache); 
     Console.WriteLine(typeof(JsonConvert).Assembly.FullName); 

     // I think this JSON is invalid because (1) it is missing a comma between the two values and (2) there is an extra comma at the end 
     string json = @"{""Items"": [""hello"" ""goodbye"",]}"; 

     // This deserialize is successful and produces an object with two values for Items 
     Container result = JsonConvert.DeserializeObject<Container>(json); 

     Console.WriteLine(result.Items.Length + " items"); 
    } 
} 


public class Container 
{ 
    public string[] Items { get; set; } 
} 

Является ли это поведение документированным и/или распространенной практикой?

Есть ли способ заставить ошибки в этом случае?

+1

Я не могу воспроизвести проблему - см. Https://dotnetfiddle.net/cVrpPp. Если я попытаюсь десериализовать свой JSON, я увижу '[Newtonsoft.Json.JsonReaderException: после разбора значения произошел неожиданный символ:« Путь »полей [2]», строка 6, позиция 3.], что и было бы ожидайте. Какую версию Json.NET вы используете? – dbc

+2

Я не могу реплицировать эту проблему, даже вернуться к 5.0.8. Недействительно JSON и, если ваша реализация позволяет это, она не соответствует «стандарту». единственный способ, которым я могу думать, что это * может * работать, - это если вы добавили в свой код разные, но похожие кавычки (например, U + 2033). – paxdiablo

+0

Возможно, пример JSON плох, и OP действительно хочет знать, как поймать [конечная запятая] (https://stackoverflow.com/questions/25209757/how-can-i-detect-invalid-json-containing-a-trailing-comma-with-c)? – dbc

ответ

0

I asked about this issue в проекте JSON.NET GitHub. Оказывается, это по дизайну. Ответ от Джеймса Ньютона-короля:

JsonTextReader принимает запятые. Невозможно изменить его, но вы можете использовать свою собственную более строгую реализацию JsonReader.