反序列化引用类型参数中字符串名称的类型的 JSON

Las*_*nal 5 c# json

var custsType = Type.GetType("Customers");          
var customers = Json.Deserialize<custsType>(data);
Run Code Online (Sandbox Code Playgroud)

这显然失败了。如何通过字符串名称引用该类,以便在运行时提供它?

另外,我需要能够访问实际的强类型对象,而不是它的字符串表示形式。

Sco*_*nen 6

var custsType = Type.GetType("Customers");          
var customers = JsonConvert.DeserializeObject(data, custsType);
Run Code Online (Sandbox Code Playgroud)

问题是,如果对象的类型不确定,您将很难使用该对象。大概类型名称是一个参数,否则你就完成了

var customers = JsonConvert.DeserializeObject<Customers>(data);
Run Code Online (Sandbox Code Playgroud)

它表明在编译时您不知道您期望返回什么类型。这样做的问题是,如果您在编译时不知道该类型,则不清楚在获得该对象后可以对它做什么。

如果您打算访问对象的任何属性,那么您必须预先对对象的类型做出一些假设。否则,您不会期望反序列化的对象具有该属性。

挑战不在于如何解决问题,而在于如何重新考虑方法,以便从一开始就不会遇到问题。

理想情况下,您想知道编译时期望的类型,这又看起来像这样:

var customers = JsonConvert.DeserializeObject<Customers>(data, custsType);
Run Code Online (Sandbox Code Playgroud)

然后,如果数据无法反序列化为预期类型,则会抛出异常,因为调用者必须传递正确的类型。

如果您发现自己处于 a) 您不知道类型是什么,或者 b) 您必须使用反射来查找属性的情况,则说明出现了问题,最好进行备份,直到您可以修复该问题。


尝试访问这样的属性:

var name = myObject["Name"];
Run Code Online (Sandbox Code Playgroud)

比反射更容易,但最终是一样的

var property = myObject.GetType().GetProperty("Name");
var name = property.GetValue(myObject);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您并不真正知道是否会有“Name”属性。无论将对象解析为 JSON,都只是在幕后使用反射。


Bra*_*ton 0

使用 Json.Net 指定类型名称处理程序:

new JsonSerializerSettings
    {
         TypeNameHandling = TypeNameHandling.Objects,
         TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full
    }
Run Code Online (Sandbox Code Playgroud)

请参阅:https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm