从WebAPI中的JSON中获取泛型类型
本文关键字:获取 泛型类型 JSON WebAPI 中的 | 更新日期: 2023-09-27 18:03:20
我想创建一个Web Api方法,该方法将接受JSON和具有类型名称的字符串。
到目前为止,我有这样的东西:
public void Write(string typeName, string jsonData)
{
var myType = Type.GetType(typeName);
var fromJsonString = JsonConvert.DeserializeObject<OutgoingEnvelope<myType>>(jsonData);
}
OutgoingEnvelope将定义为:
public class OutgoingEnvelope<T>
{
public string TypeId { get; set; }
public OutgoingEnvelope()
{
Documents = new List<T>();
}
public List<T> Documents { get; set; }
}
当前我得到的消息:
'myType'是一个变量,但被当作类型使用。
我们的最终目标是能够获得JSON数据并动态地将其转换为适当的类。
以这种方式使用泛型时,必须在编译时知道该类型。如果您尝试使用var instance = new myType();
创建myType的新实例,情况也类似,这也会由于相同的原因(或多或少)无法编译。
JsonConvert(参见DeserializeObject)上的反序列化器提供了一个非泛型版本,如果你想的话,你可以稍后强制转换。但这有一些要求。
- 你必须为你的容器定义一个接口和可选的泛型类型参数
- 泛型接口参数必须标记为协变(out关键字)
这是一个执行的自包含示例,唯一缺少的是从字符串中获取Type
,而不是硬编码。
public class SomeController {
public void Write()
{
var objectToSerialize = new OutgoingEnvelope<SomeDocument>()
{
Documents = new List<SomeDocument>() {new SomeDocument() {Name = "Hi"}},
TypeId = "Some type"
};
var json = JsonConvert.SerializeObject(objectToSerialize);
// var myType = Type.GetType(typeName);
var myType = typeof(OutgoingEnvelope<SomeDocument>);
var fromJsonString = JsonConvert.DeserializeObject(json, myType) as IOutgoingEnvelope<IDocumentType>;
if(fromJsonString == null)
throw new NullReferenceException();
}
}
public interface IDocumentType
{
string Name { get; set; }
// known common members in the interface
}
public class SomeDocument : IDocumentType
{
public string Name { get; set; }
}
public interface IOutgoingEnvelope<T> where T : IDocumentType
{
string TypeId { get; set; }
IEnumerable<T> Documents { get; }
}
public class OutgoingEnvelope<T> : IOutgoingEnvelope<T> where T : IDocumentType
{
public string TypeId { get; set; }
public OutgoingEnvelope()
{
Documents = new List<T>();
}
public IEnumerable<T> Documents { get; set; }
}
试试这样:
var myType = Type.GetType(typeName);
var template = typeof(OutgoingEnvelope<>);
var typeToSet = template.MakeGenericType(myType);
var fromJsonString = JsonConvert.DeserializeObject<OutgoingEnvelope<typeToSet>>(jsonData);
应该可以。