C# Json.NET Uri(反)序列化错误
我需要使用最新的(4.0.3)库序列化和反序列化包含System.Uri属性的对象 以下代码演示了该问题:C# Json.NET Uri(反)序列化错误,c#,serialization,json.net,deserialization,C#,Serialization,Json.net,Deserialization,我需要使用最新的(4.0.3)库序列化和反序列化包含System.Uri属性的对象 以下代码演示了该问题: string input = "http://test.com/%22foo+bar%22"; Uri uri = new Uri(input); string json = JsonConvert.SerializeObject(uri); Uri output = JsonConvert.DeserializeObject<Uri>(json); 字符串输入=”http:
string input = "http://test.com/%22foo+bar%22";
Uri uri = new Uri(input);
string json = JsonConvert.SerializeObject(uri);
Uri output = JsonConvert.DeserializeObject<Uri>(json);
字符串输入=”http://test.com/%22foo+巴%22”;
Uri=新的Uri(输入);
字符串json=JsonConvert.SerializeObject(uri);
Uri输出=JsonConvert.DeserializeObject(json);
反序列化对象方法抛出一个JsonReaderException。这在4.0.2中运行良好
我已经在codeplex上提交了一个问题,其中包含了修复该问题的测试和补丁,但是作者发布一个修复版本似乎需要一些时间
同时,我能做些什么(使用JsonSettings或其他方法)使最新版本如预期的那样工作吗
到目前为止,我有几个选择:
您可以编写一个helper类,该类绕过通常对
System.Uri
的处理,并使用Uri.OriginalString
属性将其纯粹视为字符串
下面是一个代码示例,它使用一个从Json.Net的JsonConverter
派生的转换器类来实现这一点
需要注意的是,必须更新使用JsonConvert的所有位置,以将helper类作为额外的JsonConverter
参数之一
我还添加了一个使用Uri作为类中成员变量的示例,以演示不必重写类上的属性,尽管这可能对您更方便。如果是这样,您可以使用[JsonConverter(UriConverter)]
作为需要它的成员的属性
using Newtonsoft.Json;
namespace JsonUriSerializeTest
{
class Program
{
public class UriConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.Equals(typeof(Uri));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return new Uri((string)reader.Value);
}
if (reader.TokenType == JsonToken.Null)
{
return null;
}
throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (null == value)
{
writer.WriteNull();
return;
}
if (value is Uri)
{
writer.WriteValue(((Uri)value).OriginalString);
return;
}
throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
}
}
public class UriPair
{
public string label { get; set; }
public Uri first { get; set; }
public Uri second { get; set; }
public void Display()
{
Console.WriteLine(string.Format("label: {0}", label));
Console.WriteLine(string.Format("first: {0}", first));
Console.WriteLine(string.Format("second: {0}", second));
}
}
static void Main(string[] args)
{
string input = "http://test.com/%22foo+bar%22";
Uri uri = new Uri(input);
string json = JsonConvert.SerializeObject(uri, new UriConverter());
Uri output = JsonConvert.DeserializeObject<Uri>(json, new UriConverter());
Console.WriteLine(input);
Console.WriteLine(output.ToString());
Console.WriteLine();
UriPair pair = new UriPair();
pair.label = input;
pair.first = null;
pair.second = new Uri(input);
string jsonPair = JsonConvert.SerializeObject(pair, new UriConverter());
UriPair outputPair = JsonConvert.DeserializeObject<UriPair>(jsonPair, new UriConverter());
outputPair.Display();
Console.WriteLine();
Console.ReadKey();
}
}
}
使用Newtonsoft.Json;
命名空间JsonUriSerializeTest
{
班级计划
{
公共类UriConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType.Equals(typeof(Uri));
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.String)
{
返回新的Uri((字符串)reader.Value);
}
if(reader.TokenType==JsonToken.Null)
{
返回null;
}
抛出新的InvalidOperationException(“UriConverter的未处理案例。检查此转换器是否应用于错误的序列化类型。”);
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
if(null==值)
{
WriteNull();
返回;
}
if(值为Uri)
{
writer.WriteValue(((Uri)值).OriginalString);
返回;
}
抛出新的InvalidOperationException(“UriConverter的未处理案例。检查此转换器是否应用于错误的序列化类型。”);
}
}
公共类对
{
公共字符串标签{get;set;}
公共Uri第一个{get;set;}
公共Uri第二个{get;set;}
公共空间显示()
{
WriteLine(string.Format(“label:{0}”,label));
WriteLine(string.Format(“first:{0}”,first));
WriteLine(string.Format(“second:{0}”,second));
}
}
静态void Main(字符串[]参数)
{
字符串输入=”http://test.com/%22foo+巴%22”;
Uri=新的Uri(输入);
string json=JsonConvert.SerializeObject(uri,new UriConverter());
Uri输出=JsonConvert.DeserializeObject(json,new UriConverter());
控制台写入线(输入);
Console.WriteLine(output.ToString());
Console.WriteLine();
UriPair=新的UriPair();
pair.label=输入;
pair.first=null;
pair.second=新Uri(输入);
字符串jsonPair=JsonConvert.SerializeObject(对,新的UriConverter());
UriPair outputPair=JsonConvert.DeserializeObject(jsonPair,new UriconConverter());
outputPair.Display();
Console.WriteLine();
Console.ReadKey();
}
}
}
谢谢你的回答。Json.NET的作者修复了这个问题,不幸的是,修复只会出现在下一个版本中。在此之前,如果可以,我将坚持使用4.0.2,如果不使用带有自定义转换器的4.0.3