加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

rest – 在ASP.NET Core中实现“JSON Merge Patch” – 最好的方

发布时间:2020-12-16 06:34:36 所属栏目:asp.Net 来源:网络整理
导读:我想创建和端点符合“ JSON Merge Patch” https://tools.ietf.org/html/rfc7396 请不要将它与“JavaScript Object Notation(JSON)Patch”混淆 https://tools.ietf.org/html/rfc6902 但是,我在区分请求中的两种情况时遇到了一些问题: 删除属性值,此处删除电
我想创建和端点符合“ JSON Merge Patch” https://tools.ietf.org/html/rfc7396

请不要将它与“JavaScript Object Notation(JSON)Patch”混淆
https://tools.ietf.org/html/rfc6902

但是,我在区分请求中的两种情况时遇到了一些问题:

>删除属性值,此处删除电子邮件值:

{
    surname: "Kowalski"
    email: null
}

>不包括属性,因为客户端根本不想更新它,此处不包含电子邮件,因为它不应更新:

{
    surname: "Kowalski"
}

出现问题的原因是在模型绑定后的两种情况下,电子邮件的值都为null.

您是否有建议如何实施?

解决方法

您需要3种不同的电子邮件状态:

>更新的填充值(例如test@mail.com)
>如果要删除电子邮件,则为null值
>如果不接触电子邮件,则缺少值.

所以问题实际上是如何在模型的字符串属性中表达这3种状态.您不能仅使用原始字符串属性执行此操作,因为空值和缺失值将如您正确描述的那样发生冲突.
解决方案是使用一些标志来指示值是否在请求中提供.您可以将此标志作为模型中的另一个属性,或者在字符串上创建一个简单的包装器,非常类似于Nullable< T>类.
我建议创建简单的通用OptionalValue< T>类:

public class OptionalValue<T>
{
    private T value;
    public T Value
    {
        get => value;

        set
        {
            HasValue = true;
            this.value = value;
        }
    }

    public bool HasValue { get; set; }
}

然后你需要自定义JsonConverter,它可以将通常的json值反序列化为OptionalValue< T>:

class OptionalValueConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(OptionalValue<T>);
    }

    public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
    {
        return new OptionalValue<T>
        {
            Value = (T) reader.Value,};
    }

    public override bool CanWrite => false;

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

你的模型看起来像这样:

public class SomeModel
{
    public string Surname { get; set; }

    [JsonConverter(typeof(OptionalValueConverter<string>))]
    public OptionalValue<string> Email { get; set; } = new OptionalValue<string>();
}

请注意,您使用空OptionalValue< string>()分配电子邮件.如果输入json不包含电子邮件值而不是Email属性,则将其与HasValue设置为false的OptionalValue保持一致.
如果输入json包含一些电子邮件,甚至是null,则OptionalValueConverter将创建OptionalValue的实例,并将HasValue设置为true.

现在,在控制器操作中,您可以确定电子邮件的3种状态:

[HttpPatch]
public void Patch([FromBody]SomeModel data)
{
    if (data.Email.HasValue)
    {
        //  Email presents in Json
        if (data.Email.Value == null)
        {
            //  Email should be removed
        }
        else
        {
            //  Email should be updated
        }
    }
    else
    {
        //  Email does not present in Json and should not be affected
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读