ASP.NET MVC请求参数字符串之区分空与NULL
开发中经常会写增删改查的功能,这里记录下在更新操作时遇到的一个问题。
假设一个模型对应数据库中某一张表,在更新时便需要区分是一次性更新全部字段还是仅更新部分字段。希望能做到传递某个参数时便更新,未传递时不更新。
先定义一个用户模型,如下:
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
服务端以这种方式来接收:
public IActionResult Update(UserModel user)
{
// 执行数据库更新操作
return Content(user.Id + user.Name + user.Address);
}
然后客户端以下面的方式来请求(这里用GET方式):
/user/update?id=1&address=hang&name=Hale
/user/update?id=1&address=hang&name=
/user/update?id=1&address=hang
上面有三种传参方式,一般情况下没有问题,但对于第二种形式,&name= 的方式,原本是希望将name字段更新为空值,但是在Action里接收时会发现,user.Name == null 。这样便无法区分是要将Name更新为空值,还是不做更新。
ModelBinder的方式
默认MVC在构造参数模型时没有区分这两种情况,要实现我们的需求就需要自定义一个ModelBinder。定义一个类,并实现IModelBinder接口即可。
public class StringBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);
if (valueProviderResult == ValueProviderResult.None)
return Task.CompletedTask;
bindingContext.Result = ModelBindingResult.Success(valueProviderResult.FirstValue);
return Task.CompletedTask;
}
}
它提供两个方法来绑定模型,一个同步的一个异步的。我用的 asp.net core 是调用的异步版方法,所以这里仅实现了BindModelAsync。
以这种方式来用这个StringBinder:
public class UserModel
{
public int Id { get; set; }
[ModelBinder(typeof(StringBinder))]
public string Name { get; set; }
[ModelBinder(typeof(StringBinder))]
public string Address { get; set; }
}
这样,再以上面第二种方式传参时,便会发现user.Name == "",而不是 user.Name == null。
这个StringBinder还可以直接用在Action的参数上:
public IActionResult Update(UserModel user, [ModelBinder(typeof(StringBinder))]string v, string v2)
{
return Content(user.Id + user.Name + v + v2);
}
这里参数 v 和 v2,一个指定了Binder一个未指定,以下面方式调用以下即可看出区别:
/user/update?id=1&address=&name=Ingo&v=&v2=
会发现 user.Address == "" ,v == "", v2 == null。
简单的方式
除了自定义ModelBinder的方式,还可以通过直接修改属性的set访问器的办法来区分null和空字符串。
修改下UserModel的代码,新增一个Phone成员:
private string phone;
public string Phone
{
get => phone;
set => phone = string.IsNullOrEmpty(value) ? string.Empty : value;
}
采用与上面相同的方式传值,会发现当传递&phone=时,user.Phone == "", 同样也能区分phone是传递的空字符串还是没传递phone参数。
因为mvc在收到&phone=参数时会调用set访问器,只是value为null。而未收到&phone=xx参数时,不会调用set访问器,所以用这种办法也可以区分空值和null。
ASP.NET MVC请求参数字符串之区分空与NULL的更多相关文章
- 自动化CodeReview - ASP.NET Core请求参数验证
自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 参数验证实现 在做服务端开发 ...
- 如何将ASP.NET MVC所有参数均自动设置为默认
今天看到CSDN上有个问题觉得有点意思:"可不可以ASP.NET MVC所有参数均自动设置为默认" public class HomeController : Controller ...
- Spring3 MVC请求参数获取的几种方法
Spring3 MVC请求参数获取的几种方法 一. 通过@PathVariabl获取路径中的参数 @RequestMapping(value="user/{id}/{name}&q ...
- ASP.NET MVC传送参数至服务端
ASP.NET MVC传送参数至服务端,前端与服务端的写法,你可以参考与采用适合你的需求的.当你只传递一两个参数也许觉得没有什么,如果一个方法中带的参数多的话,可以考虑model,前端可以考虑对象进行 ...
- Spring3 MVC请求参数获取的几种方法[转]
Spring3 MVC请求参数获取的几种方法 Spring3 MVC请求参数获取的几种方法 一. 通过@PathVariabl获取路径中的参数 @RequestMapping(value=& ...
- Asp.net Mvc 请求是如何到达 MvcHandler的——UrlRoutingModule、MvcRouteHandler分析,并造个轮子
这个是转载自:http://www.cnblogs.com/keyindex/archive/2012/08/11/2634005.html(那个比较容易忘记,希望博主不要生气的) 前言 本文假定读者 ...
- 【MVC】ASP.NET MVC 请求生命周期
当一个asp.net mvc应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在asp.net mvc应用程序Http request和Http response 过程中,主要包含8个步骤: ...
- Spring MVC请求参数绑定 自定义类型转化 和获取原声带额servlet request response信息
首先还在我们的框架的基础上建立文件 在domian下建立Account实体类 import org.springframework.stereotype.Controller; import org. ...
- ASP.NET MVC显示HTML字符串
一些html经HtmlEncode后,如“<span>测试数据</span>”.现需要把这些内容正常显示于asp.net mvc的视图内. 举个例子来解决与说明,先创建一个mo ...
随机推荐
- mybatis-generator 插件
首先肯定要有mybatis的依赖 <!--mybatis spring--> <dependency> <groupId>org.mybatis.spring.bo ...
- 查全率(Recall),查准率(Precision),灵敏性(Sensitivity),特异性(Specificity),F1,PR曲线,ROC,AUC的应用场景
之前介绍了这么多分类模型的性能评价指标(<分类模型的性能评价指标(Classification Model Performance Evaluation Metric)>),那么到底应该选 ...
- Theano入门笔记2:scan函数等
1.Theano中的scan函数 目前先弱弱的认为:相当于symbolic的for循环吧,或者说计算图上的for循环,也可以用来替代repeat-until. 与scan相比,scan_checkpo ...
- 计蒜客 39270.Angel's Journey-简单的计算几何 ((The 2019 ACM-ICPC China Shannxi Provincial Programming Contest C.) 2019ICPC西安邀请赛现场赛重现赛
Angel's Journey “Miyane!” This day Hana asks Miyako for help again. Hana plays the part of angel on ...
- 微信小程序轮播组件
在index.wxml中添加以下代码 <view> <swiper indicator-dots="{{indicatorDots}}" autoplay=&qu ...
- python学习笔记二:(python3 logging函数中format说明)
背景,在学习logging时总是遇到无法理解的问题,总结,尝试一下更清晰明了了,让我们开始吧! logging模块常用format格式说明 %(levelno)s: 打印日志级别的数值 %(level ...
- MySQL的ROUND函数
ROUND(X) ROUND(X,D) 返回参数X, 其值接近于最近似的整数.在有两个参数的情况下,返回 X ,其值保留到小数点后D位,而第D位的保留方式为四舍五入.若要接保留X值小数点左边的D 位, ...
- 前后端通信—CORS(支持跨域)
根据前端跨域的那些事这篇文章中的跨域的理解这一块,我们重新创建两个服务,第一个服务使用了test.html const http = require('http') const fs = requir ...
- 四个大点,搞懂 Redis 到底快在哪里
来源:https://mp.weixin.qq.com/s/4kPlBE3C6lTuSvt5mY5hUQ 前言 一. 开发语言 二. 纯内存访问 三. 单线程 四. 非阻塞多路I/O复用机制 前言 R ...
- 2015-2016-2《Java程序设计》团队博客1
项目内容 经过一些讨论之后决定了最终的项目:简易画图板项目设计与开发 目标 制作一个能够画各种图形的画板,并能有多种颜色可以选择:输入文本时也可以选择字体:能够保存,新建,和导入图片 实现计划 十一周 ...