在运行时将JObject转换为类型

13
我正在编写一个简单的事件分发器,其中我的事件以对象形式出现,包括clr类型名称和表示原始事件的json对象(在将byte[]处理为jobject之后触发)。如果有人想知道具体细节,我正在使用GetEventStore。
我想要利用这个clr类型做两件事:
1.查找实现IHandles接口的类;
2.调用该类上的Consume(clr type)方法。
我已经成功地使用以下代码完成了第一部分:
     var processedEvent = ProcessRawEvent(@event);
     var t = Type.GetType(processedEvent.EventClrTypeName);

     var type = typeof(IHandlesEvent<>).MakeGenericType(t);

     var allHandlers = container.ResolveAll(type);


     foreach (var allHandler in allHandlers)
     {
         var method = allHandler.GetType().GetMethod("Consume", new[] { t });
         method.Invoke(allHandler, new[] { processedEvent.Data });
     }

问题在于 processedEvent.Data 是一个 JObject 类型 - 我知道它的类型是因为我在它上面定义了 t。

如何将 JObject 解析为类型 t 而又不进行任何不必要的类型名称判断?


1
你尝试过使用DeserializeObject吗? - cynic
是的 - 现在感觉有点傻 :) - user156888
3个回答

18
使用 ToObject
var data = processedEvent.Data.ToObject(t);

或者,如果您有已知的类型,则:

MyObject data = processedEvent.Data.ToObject<MyObject>();

1
.ToObject(Type...) 只在 JSON.NET 4.5 或更高版本中可用,如果因为某种原因你被困在旧版本中,则无法使用。 - drzaus
JObjectToObject都出现在同一个Json.net版本中(版本:7.0.0.0)。 http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_ToObject.htm - Amir Popovich
1
是的,因为版本7在v4.5之后,这正是我的评论所指的--它在2012年11月被添加(https://github.com/JamesNK/Newtonsoft.Json/commit/a8249e38df8c3f55cf3f22585222f245741e05d5#diff-8e0fcadcdad86fae606e713cf8279c59L1174),即版本4.5.11。 - drzaus
这是不正确的。首先,json.net与.net框架版本无关。你是否声称在2012年11月之后添加的任何内容都只能在4.5.11上运行? 其次,我打开了一个.net 3.5框架,并从nuget获取了json.net包,能够调用JObject.ToObject。 - Amir Popovich
1
我觉得你误解了我的意思 - 我谈论的是 Newtonsoft Json.NET package 的 4.5 版本,而不是 .NET framework。你的回答完全没问题,我只提到这个(相当荒谬的)警告,以防其他人陷入跟我一样的境地(被限制使用旧版包)。 - drzaus
谢谢,@drzaus,这正是我的情况,我使用的是JSON.NET 3.5.0.0 :( - tsul

0

这个其实很简单:

method.Invoke(allHandler, new[] { JsonConvert.DeserializeObject(processedEvent.Data.ToString(), t) });

0

如果出于某种原因你被困在旧版的Newtonsoft Json.NET(4.5.11及以前版本 约为2012年)上,并且没有访问已提到的 JToken.ToObject(Type)的权限,你可以重复使用它内部所做的工作

var someJObject = ...; // wherever it came from; actually a JToken
var type = typeof(MyExpectedType);

MyExpectedType myObject;
using (var jsonReader = new JTokenReader(someJObject))
    myObject = serializer.Deserialize(jsonReader, type);

我提到这个只是因为我曾经在一个项目上工作,无法将Json.NET的Nuget包更新到最新版本。此外,这与.NET框架版本无关。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接