我正在工作一个rest API,有2种类型的响应对象。例如,如果status为success,则返回一个json对象,其中包含一些字段;如果不是,则返回字符串:),如ERROR_MESSAGE_HERE"错误响应没有封装成类或字符串。
我想处理这个,但是,我使用的是我们公司开发的http客户端。本http客户端还采用了。net http客户端,它拥有一些方法。当我添加属于API的成功对象时,它期望我的响应对象类,如果响应不成功,它返回反序列化异常。
我知道我可以使用try catch来处理这个问题,但我不喜欢first。有什么有效的方法来处理这些反应吗?
您可以采用两种主要方法。假设您正在使用System.Text.Json
(但同样可以使用Newtonsoft Json.NET):
-
使用一个DOM选项来动态处理数据。例如,通过
JsonNode
API -您将JsonNode
作为类型传递给HTTP客户端包装器,然后处理反序列化:// var js_str = """{"pr":1}"""; var js_str = ""error_here""; var deserialize = System.Text.Json.JsonSerializer.Deserialize<JsonNode>(js_str); if (deserialize is JsonValue { } jval) { var value = jval.GetValue<string>(); } else { var myClass = deserialize.Deserialize<MyClass>(); }
-
使用分析节点类型的自定义转换器创建自定义类型。让您开始(可以大大改进,例如通过使其泛型和使用工厂方法):
[JsonConverter(typeof(ErrorOrDataConverter))] class StringOrData { public string? StringValue { get; set; } public MyClass? Data { get; set; } public bool IsString { get; set; } } class ErrorOrDataConverter : System.Text.Json.Serialization.JsonConverter<StringOrData> { public override StringOrData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { return new StringOrData { StringValue = reader.GetString()!, IsString = true }; } return new StringOrData { Data = System.Text.Json.JsonSerializer.Deserialize<MyClass>(ref reader, options)! }; } public override void Write(Utf8JsonWriter writer, StringOrData value, JsonSerializerOptions options) { throw new NotImplementedException(); } }
注:
我认为更好的方法可能是在库端处理这个问题,在那里你可以分析响应状态来选择正确的类型来反序列化。例如,您可以添加带有2个泛型参数的重载,并返回类似OneOf
或Either
的内容。
使用"try catch"是最实用的方法。