在一个.netcore应用程序中,我想提供以下内容(简化):
我很乐意为您翻译这个第二个调用的内容:
这里的问题在于实例看起来是这样的:
// Create a new record, assume it returns an ID=1
https://site/MyController/Save?FirstName=John&LastName=Doe&Status=Active
// Update the record without full state
PUT https://site/MyController/1
{
'DOB': '1/1/1970',
'Status': null
}
我很乐意为您翻译这个第二个调用的内容:
我想将这个第二个调用翻译为:
UPDATE MyModel SET DOB = '1/1/1970' AND Status=NULL WHERE Id = 1
我当然可以在MyController
中编写代码来解析请求(querystring/form/body)中提交的值,并相应地创建 SQL 数据。
然而,我更愿意遵循 MVC 规范并利用 MVC 默认提供的绑定(binding)功能:
public async Task<MyModel> Save(string id, [FromBody]MyModel instance)
{
await _MyRepository.UpdateAsync(id, message);
return message;
}
这里的问题在于实例看起来是这样的:
{
'FirstName': null,
'LastName': null,
'DOB': '1/1/1970',
'Status': null
}
我无法确定在数据库中哪些字段应该设置为空,哪些应该保留不变。
我已经实现了一个包装类,它能够:
- 在反序列化时设置任何“脏”属性
- 在序列化时仅写入脏的属性
这将略微改变我的方法签名,但不会对开发人员造成负担:
public async Task<MyModel> Save(string id, [FromBody]MyWrapper<MyModel> wrapper
{
await _MyRepository.UpdateAsync(id, wrapper.Instance, wrapper.DirtyProperties);
return wrapper.Instance;
}
我的两个问题是:
- 我是否在重新发明已经存在的模式?
- 我能否以优雅的方式拦截MVC反序列化过程?