C# 如何将JSON动态转换为正确的DTO类?
我有JSON数据,我想转换成正确的类型,然后处理它。我正在使用MONO和NewtonSoft的JSON库。也就是说,JSON和object必须匹配属性1:1才能转换为正确的DTO。DTO始终具有独特的属性 Activator.CreateInstance()和Convert.ChangeType()似乎都未编译 DTO: 服务器:C# 如何将JSON动态转换为正确的DTO类?,c#,casting,mono,type-conversion,dynamic-data,C#,Casting,Mono,Type Conversion,Dynamic Data,我有JSON数据,我想转换成正确的类型,然后处理它。我正在使用MONO和NewtonSoft的JSON库。也就是说,JSON和object必须匹配属性1:1才能转换为正确的DTO。DTO始终具有独特的属性 Activator.CreateInstance()和Convert.ChangeType()似乎都未编译 DTO: 服务器: using System; using System.Collections.Generic; using System.Linq; using System.Thr
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Newtonsoft.Json;
class Server
{
protected static List<JSONDTO> DTOList;
static void Main()
{
DTOList = new List<JSONDTO>();
DTOList.Add(new JSONProfileDTO());
DTOList.Add(new JSONCommandDTO());
DTOList.Add(new JSONMessageDTO());
// ...
}
protected static void OnMessage (string message)
{
dynamic rawObject;
try
{
// Or try to convert to right DTO here somehow?
rawObject = JsonConvert.DeserializeObject<dynamic>(message);
} catch (JsonReaderException ex) {
// Invalid JSON
return;
}
int dtoCount = DTOList.ToArray().Length;
int errCount = 0;
JSONDTO DTOObject;
foreach (var dto in DTOList.ToList()) {
try {
// Doesn't compile:
// DTOObject = Activator.CreateInstance(dto.GetType(), rawObject);
// DTOObject = Convert.ChangeType(rawObject, dto.GetType());
break; // Match found!
} catch (Exception ex) {
// Didn't match
errCount++;
}
}
if (errCount == dtoCount) {
// Right DTO was not found
return;
}
if (DTOObject is JSONProfileDTO) {
AssignProfile((JSONProfileDTO) DTOObject);
}
else if (DTOObject is JSONCommandDTO)
{
RunCommand((JSONCommandDTO) DTOObject);
}
// etc ..
}
protected static void RunCommand (JSONCommandDTO command)
{
string cmd = command.cmd;
Console.WriteLine("command == " + cmd);
}
protected static void AssignProfile(JSONProfileDTO profile)
{
Console.WriteLine("got profile!");
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统线程;
使用Newtonsoft.Json;
类服务器
{
受保护的静态列表数据列表;
静态void Main()
{
DTOList=新列表();
Add(新的JSONProfileDTO());
Add(新的JSONCommandDTO());
Add(新的JSONMessageDTO());
// ...
}
受保护的静态无效消息(字符串消息)
{
动态对象;
尝试
{
//或者试着在这里转换成正确的DTO?
rawObject=JsonConvert.DeserializeObject(消息);
}捕获(JsonReaderException ex){
//无效的JSON
返回;
}
int dtoCount=DTOList.ToArray().Length;
int errCount=0;
JSONDTO对象;
foreach(DTOList.ToList()中的变量dto){
试一试{
//不编译:
//DTOObject=Activator.CreateInstance(dto.GetType(),rawObject);
//DTOObject=Convert.ChangeType(rawObject,dto.GetType());
break;//找到匹配项!
}捕获(例外情况除外){
//不匹配
errCount++;
}
}
if(errCount==dtoCount){
//找不到正确的DTO
返回;
}
if(DTOObject是JSONProfileDTO){
AssignProfile((JSONProfileDTO)DTOObject);
}
else if(DTOObject是JSONCommandDTO)
{
RunCommand((JSONCommandDTO)DTOObject);
}
//等等。。
}
受保护的静态void RunCommand(JSONCommandDTO命令)
{
字符串cmd=command.cmd;
Console.WriteLine(“command==”+cmd);
}
受保护的静态配置文件(JSONProfileDTO配置文件)
{
控制台。WriteLine(“获得配置文件!”);
}
}
}我假设您自己没有从DTO类创建序列化数据,因为在这种情况下,您可以让它在输出中包含类型信息。有了这些信息,反序列化程序将能够自动重新创建正确的实例 由于这很可能不是您的情况,您需要解决以下问题:
// match is the DTO type to create
var dto = match.TryCreateInstance( json );
TryCreateInstance是另一个Fasterflect助手-它将自动找到一个构造函数来调用和复制任何剩余的匹配属性
我希望这为您指明了正确的方向。我成功了。我必须添加带有MissingMemberHandling.Error的JSONSerializerSetting,以便在JSON不适合对象时引发异常。我还缺少Microsoft.CSharp参考
class Server
{
protected static List<Type> DTOList = new List<Type>();
static void Main()
{
DTOList.Add(typeof(JSONProfileDTO));
DTOList.Add(typeof(JSONCommandDTO));
DTOList.Add(typeof(JSONMessageDTO));
}
protected static void OnMessage (string rawString)
{
dynamic jsonObject = null;
int DTOCount = DTOList.Count;
int errors = 0;
var settings = new JsonSerializerSettings ();
// This was important
// Now exception is thrown when creating invalid instance in the loop
settings.MissingMemberHandling = MissingMemberHandling.Error;
foreach (Type DTOType in DTOList) {
try {
jsonObject = JsonConvert.DeserializeObject (rawString, DTOType, settings);
break;
} catch (Exception ex) {
errors++;
}
}
if (null == jsonObject) {
return;
}
if (errors == DTOCount) {
return;
}
if (jsonObject is JSONProfileDTO) {
AssignProfile((JSONProfileDTO) jsonObject);
}
else if (jsonObject is JSONCommandDTO)
{
RunCommand((JSONCommandDTO) jsonObject);
}
}
}
类服务器
{
受保护的静态列表DTOList=新列表();
静态void Main()
{
添加(typeof(JSONProfileDTO));
添加(typeof(JSONCommandDTO));
Add(typeof(JSONMessageDTO));
}
受保护的静态void OnMessage(字符串rawString)
{
动态jsonObject=null;
int DTOCount=DTOList.Count;
整数误差=0;
var settings=newjsonserializersettings();
//这很重要
//现在,在循环中创建无效实例时引发异常
settings.MissingMemberHandling=MissingMemberHandling.Error;
foreach(在DTOList中键入DTOType){
试一试{
jsonObject=JsonConvert.DeserializeObject(原始字符串、数据类型、设置);
打破
}捕获(例外情况除外){
错误++;
}
}
if(null==jsonObject){
返回;
}
如果(错误==DTOCount){
返回;
}
if(jsonObject是JSONProfileDTO){
AssignProfile((JSONProfileDTO)jsonObject);
}
else if(jsonObject是JSONCOMMANDTO)
{
RunCommand((JSONCommandDTO)jsonObject);
}
}
}
// match is the DTO type to create
var dto = match.TryCreateInstance( json );
class Server
{
protected static List<Type> DTOList = new List<Type>();
static void Main()
{
DTOList.Add(typeof(JSONProfileDTO));
DTOList.Add(typeof(JSONCommandDTO));
DTOList.Add(typeof(JSONMessageDTO));
}
protected static void OnMessage (string rawString)
{
dynamic jsonObject = null;
int DTOCount = DTOList.Count;
int errors = 0;
var settings = new JsonSerializerSettings ();
// This was important
// Now exception is thrown when creating invalid instance in the loop
settings.MissingMemberHandling = MissingMemberHandling.Error;
foreach (Type DTOType in DTOList) {
try {
jsonObject = JsonConvert.DeserializeObject (rawString, DTOType, settings);
break;
} catch (Exception ex) {
errors++;
}
}
if (null == jsonObject) {
return;
}
if (errors == DTOCount) {
return;
}
if (jsonObject is JSONProfileDTO) {
AssignProfile((JSONProfileDTO) jsonObject);
}
else if (jsonObject is JSONCommandDTO)
{
RunCommand((JSONCommandDTO) jsonObject);
}
}
}