背景前提:
1、在命名空间ModelA、ModelB下,都有完全相同的类定义ClassX、ClassY、ClassZ ;
2、ClassBase是父类,它的子类有:ClassX、ClassY、ClassZ
3、在ModelB下不能访问ModelA;
4、有大量文件,每个文件里都是ModelA下的ClassX、ClassY、ClassZ中某些类型的数据(格式是json);
要求目标:
读取这些文件的数据后,完全赋值给ModelB下对应的类
处理思路:
读取文件json字符串后替换$type标记的数据类型,再将json反序列化赋值给ModelB对应的类对象
//step1先进行反射,得到ModelA下的所有类型
static bool GetTypeByString(out List<Type> types)
{
string dll = AppDomain.CurrentDomain.BaseDirectory + $"\\ModelA.dll";
Assembly assembly = Assembly.LoadFrom(dll);
types = assembly.GetTypes().Where(x => x.FullName.StartsWith("ModelA ")).ToList();
return types.Count > 0;
}
//step2 将json替换成JObject对象
JObject jObject = JObject.Parse(json);
foreach (JProperty property in jObject.Properties())
{
if (property.Value.Type == JTokenType.Object)
{
ModifyTypeProperty(property.Value as JObject);
}
else if (property.Value.Type == JTokenType.Array)
{
foreach (JObject itemJobect in (property.Value as JArray).Children<JObject>())
{
ModifyTypeProperty(itemJobect);
}
}
}
//step3 替换JObject对象的$type属性对应的信息
static void ModifyTypeProperty(JObject jsonObject)
{
JProperty property = jsonObject.Property("$type");
if (property != null)
{
string originalTypeName = property.Value.ToString();
//完整的限定名,程序集的简单名称或完整名称
string[] arr = originalTypeName.Split(',');
string typename = arr[0].Substring(arr[0].LastIndexOf('.') + 1);
var findType = types.Find(x => x.Name == typename);
if (findType == null)
{
throw new Exception($"没有找到类型:{typename}");
}
string modifiedType = $"{findType.FullName},{findType.Assembly.GetName().Name}";
property.Value = modifiedType;
}
foreach (JProperty jProperty in jsonObject.Properties())
{
if (jProperty.Value.Type == JTokenType.Object)
{
ModifyTypeProperty(jProperty.Value as JObject);
}
}
}
//step4 处理过的jObject对象,转回Json字符串
var newJson = jObject.ToString();
//step5 对新得到的json字符串,反序列化到ModelB下的类对象
JsonSerializerSettings setting = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
};
var inpara = new { FGuid = Guid.Empty, listTc = new List<ClassX>(), listTm = new List<ClassY>() };
inpara = JsonConvert.DeserializeAnonymousType(newJson, inpara, setting);