- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
当我的 API 发回单个对象时,我们将其称为 Item(OData 术语中的 GetEntity),它看起来像这样:
{
"d" : {
"Item" : "123456",
"OldItem" : "78921",
}
}
当我抓取一组相同的对象时,即返回项目列表,我得到:
{
"d":{
"results":[
{
"Item":"343431",
"OldItem":"21314"
},
{
"Item":"341321",
"OldItem":"43563"
}
]
}
}
除了我需要摆脱的明显的“d”基节点之外,我在尝试使用 C# 中的相同类来执行此操作时遇到了麻烦。我有一个 Item 类:
public class Material : IEntity
{
[JsonProperty("Item")]
public string material_number { get; set; }
[JsonProperty("OldItem")]
public string old_material_number { get; set; }
// Methods
public Material() {}
public bool Validate() { throw new NotImplementedException(); }
}
我希望能够调用自定义 JsonConverter
来处理此问题,但我无法获得一些示例,以便让单个对象、数组转换器正常工作。理想情况下,我应该能够调用:
JsonConvert.DeserializeObject<T>
其中 T
是 Material
或 List<Material>
。我如何构建 JsonConverter
来处理这两种情况?
我这样调用 JsonConvert.DeserializeObject<T>
:
if (response.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(JObject.Parse(response.Content.ReadAsStringAsync().Result).SelectToken("d").ToString());
}
else
{
throw new Exception("Service Error");
}
最佳答案
这是一个适合您的情况的 JsonConverter
。请注意,如果您可以收到任何其他未在您的问题中显示的 JSON 格式 - 例如,如果 d
可以具有 null
的值,当没有结果——您可能需要对转换器进行调整。目前,如果遇到意外情况,它会抛出异常,但如果您愿意,您可以让它返回 null 或一个空列表。
public class MaterialArrayConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Object)
{
JToken results = token["results"];
if (results != null && results.Type == JTokenType.Array)
{
// we've got multiple items; deserialize to a list
return results.ToObject<List<Material>>(serializer);
}
else if (results == null)
{
// "results" property not present; return a list of one item
return new List<Material> { token.ToObject<Material>(serializer) };
}
}
// some other format we're not expecting
throw new JsonSerializationException("Unexpected JSON format encountered in MaterialArrayConverter: " + token.ToString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
// CanConvert is not called when [JsonConverter] attribute is used
return false;
}
}
您可以通过创建一个如下所示注释的 RootObject
类来使用它,然后将您的 JSON 反序列化为该类:
public class RootObject
{
[JsonProperty("d")]
[JsonConverter(typeof(MaterialArrayConverter))]
public List<Material> Materials { get; set; }
}
然后:
var root = JsonConvert.DeserializeObject<RootObject>(json);
从那里您可以检索 Material 列表并按您认为合适的方式使用它。
fiddle :https://dotnetfiddle.net/tKb6Ke
关于c# - Json转换器 : Return a single object or a List<Object> based on inbound JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36429749/
我是一名优秀的程序员,十分优秀!