如何在 Asp.Net Core 模型绑定中区分 JSON 中的空数据和不存在数据?

Ily*_*dik 14 c# model-binding .net-core asp.net-core

我想在 Asp.Net Core 的操作中区分这两个 json 输入:

{
  "field1": null,
  "field2": null
}
Run Code Online (Sandbox Code Playgroud)

和

{
  "field1": null,
}
Run Code Online (Sandbox Code Playgroud)

我在 C# 中有一个这样的普通类:

public class MyData
{
   public string Field1 { get; set;}
   public string Field2 { get; set;}
}
Run Code Online (Sandbox Code Playgroud)

我想运行一个可以接受 null 作为值的对象的部分更新,但是当该字段不在输入中时,这意味着我根本不想更新此字段(将其设置为 null 的其他内容) .

Ily*_*dik 9

这就是我最终所做的,因为所有其他选项似乎都太复杂(例如 jsonpatch、模型绑定)或者无法提供我想要的灵活性。

此解决方案意味着需要为每个属性编写一些样板,但不会太多:

public class UpdateRequest : PatchRequest
{
    public string Name
    {
       get => _name;
       set { _name = value; SetHasProperty(nameof(Name)); }
    }  
}

public abstract class PatchRequest
{
    private readonly HashSet<string> _properties = new HashSet<string>();

    public bool HasProperty(string propertyName) => _properties.Contains(propertyName);

    protected void SetHasProperty(string propertyName) => _properties.Add(propertyName);
}
Run Code Online (Sandbox Code Playgroud)

然后可以这样读取该值:

if (request.HasProperty(nameof(request.Name)) { /* do something with request.Name */ }
Run Code Online (Sandbox Code Playgroud)

这就是如何使用自定义属性对其进行验证:

var patchRequest = (PatchRequest) validationContext.ObjectInstance;
if (patchRequest.HasProperty(validationContext.MemberName) {/* do validation*/}
Run Code Online (Sandbox Code Playgroud)