【发布时间】:2020-12-08 11:27:41
【问题描述】:
我正在使用我无法更改的第三方 API,它有时会返回标准 JSON 结构,而有时则不会。我怀疑原因是第 3 方应用程序中的数据在 UI 中是可选的。如果数据存在,它将如下所示:
{
"contactID": "1234",
:
<some other attributes>
:
"Websites": {
"ContactWebsite": {
"url": "www.foo.com"
}
}
}
当它不存在时,它看起来像这样......
{
"id": "1234",
:
<some other attributes>
:
"Websites": ""
}
我的代码看起来像...
using System;
using System.Text.Json;
namespace TestJsonError
{
class Program
{
static void Main(string[] args)
{
string content = "{ \"contactID\": \"217\", \"custom\": \"\", \"noEmail\": \"true\", \"noPhone\": \"true\", \"noMail\": \"true\", \"Websites\": \"\", \"timeStamp\": \"2020-10-13T19:21:38+00:00\" }";
Console.WriteLine($"{content}");
var response = JsonSerializer.Deserialize<ContactResponse>(content);
Console.WriteLine($"contactID={response.contactID}");
}
}
public class ContactResponse
{
public string contactID { get; set; }
public string custom { get; set; }
public string noEmail { get; set; }
public string noPhone { get; set; }
public string noMail { get; set; }
public WebsitesResponse Websites { get; set; }
public DateTime timeStamp { get; set; }
}
public class WebsitesResponse
{
public ContactWebsiteResponse ContactWebsite { get; set; }
}
public class ContactWebsiteResponse
{
public string url { get; set; }
}
}
我收到以下错误...
> System.Text.Json.JsonException HResult=0x80131500 Message=The JSON
> value could not be converted to TestJsonError.WebsitesResponse. Path:
> $.Websites | LineNumber: 0 | BytePositionInLine: 106.
> Source=System.Text.Json StackTrace: at
> System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type
> propertyType) at
> System.Text.Json.JsonPropertyInfoNotNullable`4.OnRead(ReadStack&
> state, Utf8JsonReader& reader) at
> System.Text.Json.JsonPropertyInfo.Read(JsonTokenType tokenType,
> ReadStack& state, Utf8JsonReader& reader) at
> System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions
> options, Utf8JsonReader& reader, ReadStack& readStack) at
> System.Text.Json.JsonSerializer.ReadCore(Type returnType,
> JsonSerializerOptions options, Utf8JsonReader& reader) at
> System.Text.Json.JsonSerializer.Deserialize(String json, Type
> returnType, JsonSerializerOptions options) at
> System.Text.Json.JsonSerializer.Deserialize[TValue](String json,
> JsonSerializerOptions options) at
> TestJsonError.Program.Main(String[] args) in
> C:\Users\simon\source\repos\TestJsonError\TestJsonError\Program.cs:line
> 14
>
> This exception was originally thrown at this call stack:
> [External Code]
> TestJsonError.Program.Main(string[]) in Program.cs
有什么建议吗?
编辑...
对于 DavidG 下面的优雅回应,我有点不好意思提出这种替代方法,但为了完整起见,我想我会分享。请注意...它很脏但有点自相矛盾。
似乎我正在调用的API,当它没有数据要返回时,它会发回一个空字符串(“”)。我在其他 API 中观察到,当出现这种情况时,API 返回 null。
如果我将"Websites": "" 替换为"Websites": null,然后再替换为JsonSerializer.Deserialize,它会很有效。我应该使用这种方法吗?好吧,我知道这很脏,但是因为我必须在 Json 类中添加很多行来适应这种情况,实际上代码似乎更容易理解。我预计会有性能开销,但我不会处理大量事务,所以在我的情况下可能没问题。
乐于接受其他意见。
【问题讨论】:
-
看起来您可能需要custom converter。当然,问题在于“网站”可以具有类型字符串或类型对象,您无法使用 C# 对象模型对其进行编码
-
在转换之前删除额外的
: -
@canton7...谢谢。作为比较,我尝试使用 Newtonsoft.Json... 没有问题。我的偏好是使用 Microsoft 的 System.Text.Json,但我没有时间了解自定义转换器......面对需要获得业务功能的情况。 :-(
-
问题是“WebsitesResponse”是一个对象,但您发送的是字符串“”,想知道这个 JSON 是如何创建的,显然它不能是空字符串。要么修复你的模型或 json,写转换会产生更多的复杂性。
-
@MichaelMao...你指的是哪个额外的
:?
标签: c# json .net-core deserialization