微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – .NetCore MVC反序列化

@H_502_2@
在.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中编写我的Create方法来解析提交值的请求(querystring / form / body),并相应地创建我的sql.

但是,我更喜欢遵循MVC约定并利用MVC提供的绑定:

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
}

此时我无法确定Db中哪些字段应为NULL,哪些字段应保持不变.

我已经实现了一个包装类:

>在反序列化时,设置任何“脏”属性,并且
>序列化时,只写脏属性

这会稍微改变我的方法签名,但不会给开发人员带来负担:

public async Task<MyModel> Save(string id,[FromBody]MyWrapper<MyModel> wrapper
{
  await _MyRepository.UpdateAsync(id,wrapper.Instance,wrapper.DirtyProperties);
  return wrapper.Instance;
}

我的两个问题是:

>我是否正在重新发明既定模式?
>我可以拦截MVC反序列化(以优雅的方式)吗?

@H_502_2@

解决方法

您可以查看自定义模型绑定.

>创建自己的模型绑定器:实现IModelBinder接口的类:

/// <summary>
/// Defines an interface for model binders.
/// </summary>
public interface IModelBinder
{
   /// <summary>
   /// Attempts to bind a model.
   /// </summary>
   /// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param>
   /// <returns>
   /// <para>
   /// A <see cref="Task"/> which will complete when the model binding process completes.
   /// </para>
   /// <para>
   /// If model binding was successful,the <see cref="ModelBindingContext.Result"/> should have
   /// <see cref="ModelBindingResult.IsModelSet"/> set to <c>true</c>.
   /// </para>
   /// <para>
   /// A model binder that completes successfully should set <see cref="ModelBindingContext.Result"/> to
   /// a value returned from <see cref="ModelBindingResult.Success"/>. 
   /// </para>
   /// </returns>
   Task BindModelAsync(ModelBindingContext bindingContext);
 }

>注册您的活页夹:

services.AddMvc().Services.Configure<Mvcoptions>(options => {
    options.ModelBinders.Insert(0,new YourCustomModelBinder());
});

MVC github repo和“Custom Model Binding文章可能有所帮助:

@H_502_2@ @H_502_2@
@H_502_2@
@H_502_2@

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐