在json。net中出现"type is interface, cannot be instantiated "反序列化错误尽管我在对象上指定了类型我试图反序列化
private static JsonSerializerSettings settings = new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.Auto };
/// <summary>
/// Returns an object created from the jObject and placed in a stub object
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jObj"></param>
/// <returns></returns>
public static T FromJObject<T>(JToken jObj)
{
if (jObj == null)
{
jObj = new JObject();
}
if (jObj is JValue)
{
return (T)((JValue)jObj).Value;
}
else
{
return (T)JsonConvert.DeserializeObject<T>(jObj.ToString(), settings);
}
}
this is jObj
{
"Id": 2,
"Name": "Name",
"JsonMapEnum": 0,
"Validations": [
{
"Id": 1,
"$type": "JsonMap.Default.JValidation, JsonMap"
}
],
"JSType": 3,
"SubJsonMapEnum": -1,
"$type": "JsonMap.Default.JAttribute, JsonMap"
}
错误
Could not create an instance of type JsonMap.Interfaces.IValidation. Type is an interface or abstract class and cannot be instantated. Path 'Validations[0].Id'
看起来它试图把Id变成一个验证对象。为什么?
这些是由我的类型
实现的接口public interface IJsonMap
{
long Id { get; set; }
String Name { get; set; }
LazyEnum JsonMapEnum { get; set; }
}
public interface IAttribute : IJsonMap
{
IEnumerable<IValidation> Validations { get; set; }
LazyEnum JSType { get; set; }
LazyEnum SubJsonMapEnum { get; set; }
}
public interface IValidation : IJsonMap
{
IEnumerable<IArgument> Arguments { get; set; }
}
这是呼叫
FromJObject<JAttribute>(CreationJObj)
JAttribute实现IAttribute
显然,"$type"必须是String字面值中的第一个属性,以便类型名称处理程序捕获该类型。我想这是因为反序列化器没有检查$type是否存在,它只是使用json字符串阅读器,在找到第一个没有设置类型的属性时,它就失败了。
下面是我创建的确保$type总是优先
的方法 private static JToken ReorderJToken(this JToken jTok)
{
if (jTok is JArray)
{
var jArr = new JArray();
foreach (var token in jTok as JArray)
{
jArr.Add(token.ReorderJToken());
}
return jArr;
}
else if( jTok is JObject)
{
var jObj = new JObject();
foreach(var prop in (jTok as JObject).Properties().OrderBy(x=> x.Name))
{
prop.Value = prop.Value.ReorderJToken();
jObj.Add(prop);
}
return jObj;
}
return jTok;
}
显然,它不能根据您提供给它的参数推断出正确的类型。如果没有更多关于它如何命名的背景,我就无法让你的东西奏效。但是,如果您使用转换为接口类型的对象调用它,则它将不起作用。根据定义,FromObject
必须总是被调用T
是类的类型。首先要做的是确保永远不要尝试调用T
等于typeof(IOneOfMyInterfaces)
的方法,因为这肯定会失败。如果这不能解决问题,我将尝试调用不同版本的反序列化方法;
IMyInterface obj = (IMyInterface)serializer.Deserialize(validatingReader, t);
这适用于validatingReader是JsonReader
, t
是实现IMyInterface
的类对象的Type
。我目前使用它与json模式的通用反序列化验证json的正确性。