c# - 我可以使用 set 方法代替 Json 属性吗?

标签 c# json api .net-core serialization

我正在使用它来反序列化来自 Api 的 Json 响应。

var apiResponse = await GetAsync<MyResponseModel>(request);

在我的响应模型中,有一个 int 属性,但 api 由于某种原因将其格式化为 float。 所以它看起来像这样:

{
"Quantity": 6.000
}

现在我用这个技巧解析它:

[JsonProperty("Quantity")]
private float QuantityFloat {
    set => Quantity = IsInt(value) ? (int) value: throw new ArgumentException("Tried to parse number to Quantity that is not an int.");
}

public int Quantity { get; set; }

private static bool IsInt(float value)
{
    var x = (int) value;
    var temp2 = value - x;
    return temp2 <= 0;
}

我的 linter 现在提示:“只有 setter 的属性令人困惑且违反直觉。相反,如果可能的话,应该添加属性 getter,或者应该用 setter 方法替换该属性。” 所以我问自己是否有更好更优雅的方法来做到这一点。

最佳答案

我建议创建一个 JsonConverter<int>可以处理整数和小数格式的值:

(此解决方案适用于 System.Text.Json)

public class IntConverter : JsonConverter<int>
{
    public override int Read(ref Utf8JsonReader reader, System.Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TryGetInt32(out var intVal))
        {
            return intVal;
        }
        // customize this part as necessary to satisfactorily deserialize
        // the float value as int, or throw exception, etc.
        float floatValue = reader.GetSingle();
        return (int)floatValue;
    }

    public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

然后你就可以用 [JsonConverter(typeof(IntConverter))] 来装饰你的属性(property)了这将导致在序列化期间使用转换器:

public class Model
{
    [JsonConverter(typeof(IntConverter))]
    public int Quantity { get; set; }
}

像这样处理它就不需要任何额外的属性,从而简化您的解决方案。如果您必须在多个地方处理这种情况,则尤其如此。

Try it online


JSON.NET 解决方案:

public class IntConverter : JsonConverter<int>
{
    public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Float)
        {
            // customize this part as necessary to satisfactorily deserialize
            // the float value as int, or throw exception, etc.
            double value = (double)reader.Value;
            return (int)value;
        }
        long intVal = (long)reader.Value;
        return (int)intVal;
    }

    public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

具有以下模型:

public class Model
{
    [JsonConverter(typeof(IntConverter))]
    public int Quantity { get; set; }
}

Try it online

关于c# - 我可以使用 set 方法代替 Json 属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70122638/

相关文章:

C# 获取打开的Word文档列表

c# - WM 5 SDK 符号

javascript - 我无法在 javascript 中从 firebase 中获取数据

java - 如何使用 Spring RestTemplate 表示为 JSON 的查询参数?

javascript - 如何在查找 id 数组的 api 中等待循环完成?风 sails Js

python - 我如何恢复 telethon telegram 中旧的 session 并再次连接(无需再次发送代码))

c# - 将通用类型检查(工厂式模式)改进为更面向 SOLID?

c# - 我在 docker 容器上的源代码在哪里

javascript - 从嵌套响应中获取 json 值

api - REST 模式创建、更新和删除相同的端点