首页新闻找找看学习计划

json.net一个bug?

0
悬赏园豆:100 [待解决问题]
public class Entity
	{
		private Dictionary<stringobject> component = new Dictionary<stringobject>();
 
		public void Set(string key, object value)
		{
			this.component[key] = value;
		}
 
		public T Get<T>(string key) where T : class
		{
			if (!this.component.ContainsKey(key))
			{
				return null;
			}
 
			return (T)this.component[key];
		}
 
		public int? Get(string key)
		{
			if (!this.component.ContainsKey(key))
			{
				return null;
			}
 
			return (int)this.component[key];
		}
	}


	public static class JsonHelper
	{
		public static string ToString(object obj)
		{
			return JsonConvert.SerializeObject(obj);
		}
 
		public static T FromString<T>(string str)
		{
			return JsonConvert.DeserializeObject<T>(str);
		}
	}


	var entity = new Entity();
	entity.Set("health", 10);
	string entityString = JsonHelper.ToString(entity);
 
	var entity2 = new Entity();
	JsonHelper.FromString<Entity>(entityString);
	Assert.AreEqual(10, entity2.Get("health"));

居然反序列化后,对象无法还原
唐诗的主页 唐诗 | 初学一级 | 园豆:2
提问于:2013-08-19 19:39
< >
分享
所有回答(3)
0

你的Entity类,都没属性,你让它怎么还原?

可以尝试修改为内部类,别用Dictionary~

幻天芒 | 园豆:36522 (高人七级) | 2013-08-19 19:53
  [JsonObject]
	public class Entity
	{
		public Entity()
		{
			this.Component = new Dictionary<stringobject>();
		}
 
		[JsonProperty]
		public Dictionary<stringobject> Component { getprivate set; }
 
		public void Set(string key, object value)
		{
			this.Component[key] = value;
		}
 
		public T Get<T>(string key) where T : class
		{
			if (!this.Component.ContainsKey(key))
			{
				return null;
			}
 
			return (T)this.Component[key];
		}
 
		public int? Get(string key)
		{
			if (!this.Component.ContainsKey(key))
			{
				return null;
			}
 
			return (int)this.Component[key];
		}
	}

改成这样了,还是不行……
支持(0) 反对(0) 唐诗 | 园豆:2 (初学一级) | 2013-08-19 20:08

好吧,犯了个sb错误

var entity2 = JsonHelper.FromString<Entity>(entityString);
支持(0) 反对(0) 唐诗 | 园豆:2 (初学一级) | 2013-08-19 20:14

@唐诗: 这,能行吗?行的话你就赢了~

支持(0) 反对(0) 幻天芒 | 园豆:36522 (高人七级) | 2013-08-19 20:44
0

试了一下,你的第二个例子是能正确的序列化和反序列化的。序列化的时候将其序列化了为{"component":{"health":10}}这样的字符串,但反序列化的时候对于10这个数字,是将其转换了为int64的这种类型的,然后在Get函数中将int64类型强制转换为int类型抛异常。
下列简化后的代码就能简单的复现这个异常:

    int k = 10;
    var jsonString = JsonHelper.ToString(k);
    Console.WriteLine(jsonString);

    object obj = JsonHelper.FromString<object>(jsonString);
    Console.WriteLine(obj.GetType());
    Console.WriteLine((int)obj);

你的这个例子用xml序列化或二进制序列化都不会有问题,究其原因,并不是json.net的bug,而是json字符串本身携带的信息较少,它并不携带严格的类型信息(你比较一下json序列化的后的字符串和xml序列化后的字符串就清楚了),因此无法保证object类型能够正确反序列化。

对于你这个问题,非要用json来序列化的话,要么把Component 定义为Dictionary<string, int>这样的强类型,要么把Get的返回值改成int64?。

天方 | 园豆:5264 (大侠五级) | 2013-08-19 21:10
0

不建议这样使用。如果用弱类型可以用dynamic。这样直接object 序列化之后 再反序列化类型对应都会出错。也就是楼上的那个问题。

````` | 园豆:14268 (专家六级) | 2013-08-20 14:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册