我认为我在这里有一个非常独特的问题,我需要利用的API开发人员做了一件我不太了解的事情。但我必须处理它。
最好通过展示一个例子来解释这个问题:
type
我们正在处理一个非常普通的REST API,其中响应是一个json字符串 - 没什么特别的。由于API中有一些抽象,每个响应中都有value
和type
字段。 value
具有不同的结构化内容,具体取决于value
。也没什么特别的。
现在的问题是JsonConvert.DeserializeObject<TargetType>(jsonString)
字段中的内容不仅仅是普通的json对象,而是包含 json对象的字符串。因此,json.net
的反序列化失败,异常
Newtonsoft.Json.JsonSerializationException:转换值时出错 &#34; {&#39; propA&#39;:&#39;类型 - 特定元素&#39;,&#39; propA2&#39;:&#39;另一种类型A 特定元素&#39;}&#34;输入&#39; My.Project.TargetType&#39;。
value
库中是否有任何可靠的内置支持来解决这个问题,或者我是否必须采用手动路由并以其他方式修复json或反序列化?
编辑:以提供更多上下文:API确实尝试使用相同的请求和响应来抽象其接口,但我仍然能够在我的代码中请求非常具体的响应。因此,我使用包含公共属性的泛型类和public class Response<TValue>
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("value")]
public TValue Value { get; set; }
}
的泛型类型,如下所示:
type
事实上,type
对我来说甚至不相关,因为我事先知道value
我将收到哪些回复(由于我的具体要求)。因此,我也能够确定JsonConvert.DeserializeObject<Response<TargetType>>(jsonString)
的响应类型。我的实际反序列化看起来像value
。
然而,我没有找到一种简洁的方法来解析Response
和{{1}}对象。任何建议都非常感谢。
答案 0 :(得分:1)
不,在您的情况下,您只需要两个步骤:
public class RootObject
{
public string type {get;set;}
public string value {get;set;}
}
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
然后,根据类型,反序列化另一个对象:
if (r.type == "typeA")
{
TypeA t = JsonConvert.DeserializeObject<TypeA>(r.value);
}
如果所有类型共享一些公共属性,则可以将它们放在接口或基类中。这也可以简化重复使用反序列化的类。
答案 1 :(得分:1)
我自己解决了这个问题,使用了一个在对象本身反序列化后调用方法的内置函数。
public class Response<TValue>
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("value")]
private string ValueString { get; set; }
public TValue Value { get; set; }
[OnDeserialized]
internal void DeserializeValue(StreamingContext context)
{
Value = JsonConvert.DeserializeObject<TValue>(ValueString);
}
}
这样我就可以简单地调用JsonConvert.DeserializeObject<Response<TargetType>>(json)
,它会首先反序列化Response
,然后将value
属性反序列化为TargetType
。