gpt4 book ai didi

c# - Json转换器 : Return a single object or a List based on inbound JSON
转载 作者:太空宇宙 更新时间:2023-11-03 12:48:36 25 4
gpt4 key购买 nike

当我的 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> 其中 TMaterialList<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/

25 4 0