我想创建一个Web Api方法,该方法将接受JSON和一个名称为Type的字符串。
到目前为止,我有这样的事情:
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数据并将其动态转换为适当的类。
答案 0 :(得分:0)
尝试这样的事情:
var myType = Type.GetType(typeName);
var template = typeof(OutgoingEnvelope<>);
var typeToSet = template.MakeGenericType(myType);
var fromJsonString = JsonConvert.DeserializeObject<OutgoingEnvelope<typeToSet>>(jsonData);
它应该有用。
答案 1 :(得分:0)
以这种方式使用泛型时,必须在编译时知道类型。如果你试图使用var instance = new myType();
创建一个新的myType实例,它会是类似的,这也不会因为相同的原因(或多或少)而编译。
JsonConvert上的反序列化器(请参阅DeserializeObject)提供了一个非泛型版本,如果您愿意,可以稍后再投射。这有一些要求。
这是一个执行的自包含示例,唯一缺少的是从字符串中获取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; }
}