我们正在使用 ASP.NET Web API 2 并希望公开以下列方式部分编辑某些对象的能力:
HTTP PATCH /customers/1
{
"firstName": "John",
"lastName": null
}
... 将 firstName
设置为 "John"
并将 lastName
设置为 null
。
HTTP PATCH /customers/1
{
"firstName": "John"
}
... 只是为了将 firstName
更新为 "John"
而根本不要触摸 lastName
。假设我们有很多属性要用这种语义更新。
这是由 OData 执行的非常方便的行为例如。
问题是在这两种情况下,默认的 JSON 序列化器只会返回 null
,因此无法区分。
我正在寻找某种方法来使用某种包装器(在内部设置/取消设置值和标志)来注释模型,以允许看到这种差异。对此有任何现有的解决方案吗?
最佳答案
我知道已经给出的答案已经涵盖了所有方面,但我只想分享关于我们最终所做的事情以及似乎对我们很有效的事情的简要总结。
创建通用数据协定
[DataContract]
public class RQFieldPatch<T>
{
[DataMember(Name = "value")]
public T Value { get; set; }
}
为补丁请求创建了临时数据协议(protocol)
示例如下。
[DataContract]
public class PatchSomethingRequest
{
[DataMember(Name = "prop1")]
public RQFieldPatch<EnumTypeHere> Prop1 { get; set; }
[DataMember(Name = "prop2")]
public RQFieldPatch<ComplexTypeContractHere> Prop2 { get; set; }
[DataMember(Name = "prop3")]
public RQFieldPatch<string> Prop3 { get; set; }
[DataMember(Name = "prop4")]
public RQFieldPatch<int> Prop4 { get; set; }
[DataMember(Name = "prop5")]
public RQFieldPatch<int?> Prop5 { get; set; }
}
业务逻辑
简单。
if (request.Prop1 != null)
{
// update code for Prop1, the value is stored in request.Prop1.Value
}
Json格式
简单。不像“JSON Patch”标准那么广泛,但涵盖了我们所有的需求。
{
"prop1": null, // will be skipped
// "prop2": null // skipped props also skipped as they will get default (null) value
"prop3": { "value": "test" } // value update requested
}
属性
- 简单的契约,简单的逻辑
- 无序列化定制
- 支持空值赋值
- 涵盖任何类型:值、引用、复杂的自定义类型等等
关于c# - ASP.NET Web API 2 和部分更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44928074/