You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.8 KiB
132 lines
4.8 KiB
7 years ago
|
using System;
|
||
12 years ago
|
using System.IO;
|
||
5 years ago
|
using System.Reflection;
|
||
12 years ago
|
using Newtonsoft.Json;
|
||
|
using Newtonsoft.Json.Converters;
|
||
|
using Newtonsoft.Json.Serialization;
|
||
|
|
||
|
namespace NzbDrone.Common.Serializer
|
||
|
{
|
||
|
public static class Json
|
||
|
{
|
||
11 years ago
|
private static readonly JsonSerializer Serializer;
|
||
7 years ago
|
private static readonly JsonSerializerSettings SerializerSettings;
|
||
12 years ago
|
|
||
|
static Json()
|
||
|
{
|
||
7 years ago
|
SerializerSettings = GetSerializerSettings();
|
||
|
Serializer = JsonSerializer.Create(SerializerSettings);
|
||
|
}
|
||
11 years ago
|
|
||
7 years ago
|
public static JsonSerializerSettings GetSerializerSettings()
|
||
|
{
|
||
|
var serializerSettings = new JsonSerializerSettings
|
||
|
{
|
||
|
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
|
||
|
NullValueHandling = NullValueHandling.Ignore,
|
||
|
Formatting = Formatting.Indented,
|
||
|
DefaultValueHandling = DefaultValueHandling.Include,
|
||
|
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||
|
};
|
||
11 years ago
|
|
||
5 years ago
|
serializerSettings.Converters.Add(new StringEnumConverter { NamingStrategy = new CamelCaseNamingStrategy() });
|
||
7 years ago
|
serializerSettings.Converters.Add(new VersionConverter());
|
||
|
serializerSettings.Converters.Add(new HttpUriConverter());
|
||
11 years ago
|
|
||
7 years ago
|
return serializerSettings;
|
||
12 years ago
|
}
|
||
|
|
||
5 years ago
|
public static T Deserialize<T>(string json)
|
||
|
where T : new()
|
||
12 years ago
|
{
|
||
5 years ago
|
try
|
||
|
{
|
||
|
return JsonConvert.DeserializeObject<T>(json, SerializerSettings);
|
||
|
}
|
||
|
catch (JsonReaderException ex)
|
||
|
{
|
||
|
throw DetailedJsonReaderException(ex, json);
|
||
|
}
|
||
12 years ago
|
}
|
||
|
|
||
|
public static object Deserialize(string json, Type type)
|
||
|
{
|
||
5 years ago
|
try
|
||
|
{
|
||
|
return JsonConvert.DeserializeObject(json, type, SerializerSettings);
|
||
|
}
|
||
|
catch (JsonReaderException ex)
|
||
|
{
|
||
|
throw DetailedJsonReaderException(ex, json);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static JsonReaderException DetailedJsonReaderException(JsonReaderException ex, string json)
|
||
|
{
|
||
|
var lineNumber = ex.LineNumber == 0 ? 0 : (ex.LineNumber - 1);
|
||
|
var linePosition = ex.LinePosition;
|
||
|
|
||
|
var lines = json.Split('\n');
|
||
|
if (lineNumber >= 0 && lineNumber < lines.Length &&
|
||
|
linePosition >= 0 && linePosition < lines[lineNumber].Length)
|
||
|
{
|
||
|
var line = lines[lineNumber];
|
||
|
var start = Math.Max(0, linePosition - 20);
|
||
|
var end = Math.Min(line.Length, linePosition + 20);
|
||
|
|
||
|
var snippetBefore = line.Substring(start, linePosition - start);
|
||
|
var snippetAfter = line.Substring(linePosition, end - linePosition);
|
||
|
var message = ex.Message + " (Json snippet '" + snippetBefore + "<--error-->" + snippetAfter + "')";
|
||
|
|
||
|
// Not risking updating JSON.net from 9.x to 10.x just to get this as public ctor.
|
||
|
var ctor = typeof(JsonReaderException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(Exception), typeof(string), typeof(int), typeof(int) }, null);
|
||
|
if (ctor != null)
|
||
|
{
|
||
|
return (JsonReaderException)ctor.Invoke(new object[] { message, ex, ex.Path, ex.LineNumber, linePosition });
|
||
|
}
|
||
|
|
||
|
// JSON.net 10.x ctor in case we update later.
|
||
|
ctor = typeof(JsonReaderException).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string), typeof(int), typeof(int), typeof(Exception) }, null);
|
||
|
if (ctor != null)
|
||
|
{
|
||
|
return (JsonReaderException)ctor.Invoke(new object[] { message, ex.Path, ex.LineNumber, linePosition, ex });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ex;
|
||
12 years ago
|
}
|
||
|
|
||
5 years ago
|
public static bool TryDeserialize<T>(string json, out T result)
|
||
|
where T : new()
|
||
11 years ago
|
{
|
||
|
try
|
||
|
{
|
||
11 years ago
|
result = Deserialize<T>(json);
|
||
|
return true;
|
||
11 years ago
|
}
|
||
10 years ago
|
catch (JsonReaderException)
|
||
11 years ago
|
{
|
||
11 years ago
|
result = default(T);
|
||
|
return false;
|
||
|
}
|
||
10 years ago
|
catch (JsonSerializationException)
|
||
11 years ago
|
{
|
||
|
result = default(T);
|
||
|
return false;
|
||
11 years ago
|
}
|
||
|
}
|
||
|
|
||
11 years ago
|
public static string ToJson(this object obj)
|
||
12 years ago
|
{
|
||
7 years ago
|
return JsonConvert.SerializeObject(obj, SerializerSettings);
|
||
12 years ago
|
}
|
||
|
|
||
|
public static void Serialize<TModel>(TModel model, TextWriter outputStream)
|
||
|
{
|
||
|
var jsonTextWriter = new JsonTextWriter(outputStream);
|
||
11 years ago
|
Serializer.Serialize(jsonTextWriter, model);
|
||
12 years ago
|
jsonTextWriter.Flush();
|
||
|
}
|
||
|
}
|
||
7 years ago
|
}
|