.NET Core 使用ModelBinder去掉所有参数的空格
一.前言
通过各种姿势搜索都没搜到这方面的,唯一找到一个比较符合的,但是只适合简单类型,而且代码还没贴全,心累。。
然后查看官网和源码之后,发现继承并实现 IModelBinder和IModelBinderProvider 即可。
我这里是WebApi,所以要区分绑定属性[FromBody]、[FromForm]等。不同的绑定方法要实现不同的IModelBinder。
二:正文
api主要设计到的就是[FromBody]和[FromQuery],我这里也只实现了这两种,其余的方式没测试过。
public class StringTrimModelBinderProvider : IModelBinderProvider
{
private readonly IList<IInputFormatter> _formatters; public StringTrimModelBinderProvider(IList<IInputFormatter> formatters)
{
_formatters = formatters;
} public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context)); if (!context.Metadata.IsComplexType && context.Metadata.ModelType == typeof(string))
{
//简单类型
var loggerFactory = (ILoggerFactory)context.Services.GetService(typeof(ILoggerFactory));
return new SimpleStringTrimModelBinder(context.Metadata.ModelType);
}
else if (context.BindingInfo.BindingSource != null &&
context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Body))
{
//通过[FromBody]绑定的
return new BodyStringTrimModelBinder(_formatters, context.Services.GetRequiredService<IHttpRequestStreamReaderFactory>());
}
//else
//if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType)
//{
// //复杂类型
// var propertyBinders = context.Metadata.Properties
// .ToDictionary(modelProperty => modelProperty, modelProperty => context.CreateBinder(modelProperty));
// var loggerFactory = (ILoggerFactory)context.Services.GetService(typeof(ILoggerFactory));
// return new AComplexTypeModelBinder(propertyBinders);
//} return null;
}
}
下面的是实现IModelBinder
public class SimpleStringTrimModelBinder : IModelBinder
{
private readonly Type _type; public SimpleStringTrimModelBinder(Type type)
{
_type = type;
} public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var valueProvider = bindingContext.ValueProvider;
var modelName = bindingContext.ModelName;
var valueProviderResult = valueProvider.GetValue(modelName); if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
string value = valueProviderResult.FirstValue.Trim();
//bindingContext.ModelState.SetModelValue(modelName, new ValueProviderResult(value));
//替换原有ValueProvider
bindingContext.ValueProvider = new CompositeValueProvider
{
new ElementalValueProvider(modelName, value, valueProviderResult.Culture),
bindingContext.ValueProvider
};
//调用默认系统绑定
SimpleTypeModelBinder simpleTypeModelBinder = new SimpleTypeModelBinder(_type, (ILoggerFactory)bindingContext.HttpContext.RequestServices.GetService(typeof(ILoggerFactory)));
simpleTypeModelBinder.BindModelAsync(bindingContext);
//bindingContext.Result = ModelBindingResult.Success(value);
return Task.CompletedTask;
}
}
public class BodyStringTrimModelBinder : IModelBinder
{
private readonly BodyModelBinder bodyModelBinder; public BodyStringTrimModelBinder(IList<IInputFormatter> formatters, IHttpRequestStreamReaderFactory readerFactory)
{
bodyModelBinder = new BodyModelBinder(formatters,readerFactory);
} public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
//调用原始body绑定数据
bodyModelBinder.BindModelAsync(bindingContext);
//判断是否设置了值
if (!bindingContext.Result.IsModelSet)
{
return Task.CompletedTask;
}
//获取绑定对象
var model = bindingContext.Result.Model; /*通过反射修改值,
也可以实现 IInputFormatter接口里面的ReadAsync方法,自己从Request.Body里面获取数据进行处理,但是那样考虑的比较多也比较复杂,原谅我能力有限。。*/
var stringPropertyInfo = model.GetType().GetProperties().Where(c=>c.PropertyType == typeof(string));
foreach (PropertyInfo property in stringPropertyInfo)
{
string value = property.GetValue(model)?.ToString()?.Trim();
property.SetValue(model, value);
}
//bindingContext.Result = ModelBindingResult.Success(value);
return Task.CompletedTask;
}
}
最后,需要将我们自定义的在Startup注册进去,
services.AddMvc(options =>
{
//需要插入到第一条,内置默认是匹配到合适的Provider就不会在向下继续绑定;如果添加到末尾,即不会调用到我们实现的
options.ModelBinderProviders.Insert(,new StringTrimModelBinderProvider(options.InputFormatters));
})
记录成长中的点点滴滴。。
.NET Core 使用ModelBinder去掉所有参数的空格的更多相关文章
- ASP.NET Core WebApi 返回统一格式参数(Json 中 Null 替换为空字符串)
相关博文:ASP.NET Core WebApi 返回统一格式参数 业务场景: 统一返回格式参数中,如果包含 Null 值,调用方会不太好处理,需要替换为空字符串,示例: { "respon ...
- 解决.NET Core Ajax请求后台传送参数过大请求失败问题
解决.NET Core Ajax请求后台传送参数过大请求失败问题 今天在项目上遇到一个坑, 在.Net Core中通过ajax向mvc的controller传递对象时,控制器(controller)的 ...
- 地址栏url中去掉所有参数
1.地址栏url中去掉所有参数,这个是纯前端解决,很多时候页面跳转时候会选择在url后面带参数过去,(使用?&),方便传也方便取,但是我们要做的是不要让页面的一些请求参数暴露在外面 正常项目工 ...
- C++去掉字符串中首尾空格和所有空格
c++去掉首尾空格是参考一篇文章的,但是忘记文章出处了,就略过吧. 去掉首尾空格的代码如下: void trim(string &s) { if( !s.empty() ) { s.erase ...
- php中利用正则去掉中文全角空格
一开始用$temp = trim($temp, " "); 这种方法,导致trim后的中文字符有乱码 最后 $str = " 广东君孺律师事务所 "; $str ...
- C# 调用命令行,参数有空格
在程序中调用cmd命令打开一个文件,而文件路径带有空格,如果直接把路径传给cmd,那么cmd就会把路径空格前面的部分当做是一个参数,空格后当做另一个参数,命令行执行把后边截掉了,导致程序出错,会弹出了 ...
- 关于一些url中传递参数有空格问题
1.关于一些url中传递参数有空格问题: url.replace(/ /g, "%20") 从上面的例子中可以看到可以用:replace(/ /g, "%20" ...
- as3中去掉字符串两边的空格,换行符
as3 去掉字符串两边的空格,换行符,方法一 ActionScript Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 pub ...
- ios 去掉字符串中的空格 和指定的字符
[问题分析] .使用NSString中的stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]方法只是去掉左右 ...
随机推荐
- windows2012域控
此次主要是使用服务器搭建域控制器,我主要是用于使用office web apps 和office online server搭建在线Word预览编辑! 一.准备工作 首先准备1台比较干净的服务器,推荐 ...
- Somatic hypermutation (or SHM) is a cellular mechanism by which the immune system adapts to the new foreign elements that confront it (e.g. microbes), as seen during class switching. Somatic hypermut
Somatic hypermutation (or SHM) is a cellular mechanism by which the immune system adapts to the new ...
- Oracle数据库的坑
Oracle数据库爬过的坑 ORA-00918 未定义明确列 ORA-01861: 文字与格式字符串不匹配 DPI-1005 : unable to acquire Oracle environmen ...
- QSplitter的使用案例
#include <QApplication> #include <QSplitter> #include <QTextEdit> #include <QTe ...
- LeetCode_35. Search Insert Position
35. Search Insert Position Easy Given a sorted array and a target value, return the index if the tar ...
- (CVE-2016-5195)脏牛本地提权
简要分析 该漏洞具体为,get_user_page内核函数在处理Copy-on-Write(以下使用COW表示)的过程中,可能产出竞态条件造成COW过程被破坏, 导致出现写数据到进程地址空间内只读内存 ...
- 白嫖百度 Tesla V100 笔记(在 AI Studio 上使用 tensorflow 和 pytorch 的方法)
登陆百度 AI Studio 并按照教程创建新项目 启动项目并进入控制台 下载 Anaconda3/Miniconda3 安装脚本 安装在 ~/work/*conda3 目录 输入命令 source ...
- (生鲜项目)06. django的view实现商品列表页
使用原始的django的View来返回json格式的商品列表 目的是回顾一些django的基础知识, 好与后面的RESTful做对比 goods.views_base.py from django.v ...
- PL/SQL链接Oracle数据库 导出表结构和表数据
打开pl/sql客户端(导出数据表结构) 在左侧 点击tabales 2 Tools-->Export User Objects,导出sql格式的文件 3 红色1 是你要选择导出的表,红色2 是 ...
- Ubuntu18.04命令行安装mysql未提示输入密码,修改mysql默认密码
Ubuntu18.04命令行安装mysql未提示输入密码,修改mysql默认密码 mysql默认密码为空 但是使用mysql -uroot -p 命令连接mysql时,报错ERROR 1045 (28 ...