ajax modelbinder,.NET Core 使用ModelBinder去掉所有参数的空格

一.前言

通过各种姿势搜索都没搜到这方面的,唯一找到一个比较符合的,但是只适合简单类型,而且代码还没贴全,心累。。

然后查看官网和源码之后,发现继承并实现 IModelBinder和IModelBinderProvider 即可。

我这里是WebApi,所以要区分绑定属性[FromBody]、[FromForm]等。不同的绑定方法要实现不同的IModelBinder。

二:正文

api主要设计到的就是[FromBody]和[FromQuery],我这里也只实现了这两种,其余的方式没测试过。

public class StringTrimModelBinderProvider : IModelBinderProvider

{

private readonly IList _formatters;

public StringTrimModelBinderProvider(IList 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());

}

//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 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));

})

记录成长中的点点滴滴。。

ASP.NET Core WebApi 返回统一格式参数(Json 中 Null 替换为空字符串)

相关博文:ASP.NET Core WebApi 返回统一格式参数 业务场景: 统一返回格式参数中,如果包含 Null 值,调用方会不太好处理,需要替换为空字符串,示例: { "respon ...

解决.NET Core Ajax请求后台传送参数过大请求失败问题

解决.NET Core Ajax请求后台传送参数过大请求失败问题 今天在项目上遇到一个坑, 在.Net Core中通过ajax向mvc的controller传递对象时,控制器(controller)的 ...

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]]方法只是去掉左右 ...

【代码笔记】iOS-请求去掉url中的空格

一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, ...

随机推荐

C#程序

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

POJ 3041 匈牙利算法模板题

一开始预习是百度的算法 然后学习了一下 然后找到了学长的ppt 又学习了一下.. 发现..居然不一样... 找了模板题试了试..百度的不好用 反正就是wa了..果然还是应当跟着学长混.. 图两边的点分 ...

URL重写以后发布到IIS找不到页面

1.读取必须勾选,否则无法加载资源文件(img,css等) c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll

[ Java面试题 ]算法篇

1.堆和栈在内存中的区别是什么? 概念: 栈(stack)是为执行线程留出的内存空间.当函数被调用的时候,栈顶为局部变量和一些 bookkeeping 数据预留块.当函数执行完毕,块就没有用了,可能在 ...

Docker镜像存储-overlayfs

一.概述 Docker中的镜像采用分层构建设计,每个层可以称之为“layer”,这些layer被存放在了/var/lib/docker//目录下,这里的st ...

HTTP max-age与Expires的分别

主要重点在于我们要明白一个相对(Expires)一个绝对(max-age). 分别 max-agemax-age是HTTP/1.1中,他是指我们的web中的文件被用户访问(请求)后的存活时间,是个相对 ...

CSS常用

1.CSS3新增特性,目前主流浏览器都支持 -webkit-user-select: none;  /* Chrome all / Safari all /opera15+*/  -moz-user- ...

Unity3D使用EasyMovieTexture插件播放视频

Unity3D对于视频的播放兼容个人感觉很差劲,之前写过一篇使用Unity3D自己自带的一些功能去播放视频,链接如下: http://www.cnblogs.com/xiaoyulong/p/8627 ...

hdu 6125 状压dp+分组

一道玄学题... 其实一开始想的是对的,优化一下就好了 首先我们会发现,乘积不能被完全平方数整除等价于所有因子的每个质因子个数和都至多为1 可是500以内的质数很多,全找出来会爆炸的 可我们会发现,如 ...

两种简单实现菜单高亮显示的JS类(转载)

两种简单实现菜单高亮显示的JS类   近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web ...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Aswing入门教程 1.6 颜色和填充

Aswing入门教程 1.6 颜色和填充作者:胡矿,iiley,Bill著作权所有,请勿转载www.flashseer.orgGoogle Dochttp://docs.google.com/Doc?iddnp8gdz_16d63xzwGraphics2D允许你利用刷子对象(Bursh)来进行颜色填充…

学习10:Python重要知识

Python易忽略知识 (1)print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end"": (2)isinstance 和 type 的区别在于:type()不会认为子类是一种父类类型。isinstance()会认为…

mc服务器word文件夹,我的世界服务器创建:MC个人服务器创建流程

:缺防盗等等乏的级高能功合:适友之间朋联机bkkuti务器服优点功:齐能全,插件样缺点多配置非常:复杂mi,encarft级升时的候能不步同新更适合:专服业务器第步、三硬配置件的世我服界器务建创首要具先备相不当的错络带宽网&…

mysql outfile csv_sql-MySQL导出到outfile:CSV转义字符

我有时间表的数据库表,其中包含一些常用字段。id, client_id, project_id, task_id, description, time, date还有更多,但这就是要点。我在该表上将导出导出到CSV文件过夜,以便为用户提供其数据的备份。 它也用作带有某些自定义报告的宏Excel…

悲观锁,乐观锁

乐观锁与悲观锁 北京这两天天气不好,时晴时阴,最近有有点累,所以在家里休息了两天,看了一下乐观锁与悲观锁,虽然没有茅塞顿开,但是也有点收获。 先想一想为什么要使用锁? 在用户访问你的网站时&…

求生之路2浩方联机开始显示服务器,求生之路2怎么联机_求生之路2浩方联机教程_快吧单机游戏...

今天为大家带来《求生之路2》浩方联机教程,和大家分享下求生之路2怎么联机,希望大家游戏愉快!温馨提示:求生之路2最好玩的当然是多人联机进行游戏,目前比较不错的平台为浩方平台,在HF联机最重要的一点是必须…

5位数的数字黑洞是多少_每日一题[491]数字黑洞--Kaprekar常数

定义$\overline{abc}$是一个三位数,其中各数位上的数字$a,b,c\in \{ 0,1,2,3,4,5,6,7,8,9 \}$且不全相同.定义如下运算$f$:把$\overline{abc}$的三个数字$a,b,c$自左到右分别由大到小排列和由小到大排列(若非零数字不足三位则在前面补$0$)&am…

发布博客

使用Word发表博客园博文 Word绑定博客园账号 Step1. 打开Word2016,依次点击"新建" -> "博客文章"。注:如果没有"博客文章"项,可以在模板搜索框进行搜索。 Step2. 进入博客页后,依次点击"…

营业收入的3个数据

1)营收,用于公司公开报表,经过客户确认的营业收入,例如合同额100万,明确4阶段付款,每阶段付款25%,现取得客户确认(盖章)的第一阶段评审通过说明书,则该合同目…

all()是python内置函数吗_Python内置函数all(),python

内置函数 all()1、描述:all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 True,否则返回 False。元素除了是 0、空、None、False外都算 True。等价于函数:def all(iterable):for element in iterable:if not element:retur…

今天梦幻诛仙服务器维护多久,《梦幻诛仙》6月10日体验服务器维护公告

亲爱的玩家:6月10日《梦幻诛仙》体验服务器将进行停机维护,此次维护我们将会发布更新补丁,版本序号为Ver 1.0.6021。维护时间预计为8:00-10:00点。如遇特殊情况,开机时间将会顺延。请玩家及时更新客户端&am…

10.类的构造(1)

1. 默认情况下,int为“0”;string为空; public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { …

c# mysql app.config_60. C# -- 读取 appconfig文件配置数据库连接的方法

APP.config配置如下:主要是数据库操作:方法一: string _connectionString System.Configuration.ConfigurationManager.ConnectionStrings["strCon"].ToString();方法二: string _connectionSt…

(转)SQL Server:在 SQL Server 2005 中配置数据库邮件,发送邮件

SQL Server:在 SQL Server 2005 中配置数据库邮件,发送邮件 [作/译者]:鹏城万里 [日期]:2008-07-24 [来源]:本站原创 [查看]: 2031 【鹏城万里】 发表于 www.sqlstudy.com SQL Server:在 SQL Ser…

关于2017届学长制作分享软件share(失物招领)的使用体验和需改进的内容

使用体验 1.注册界面 注册界面提示明显,提示用户输入什么类型的密码,而且输入什么样的用户名不限,注册界面色调比较单一,注册内容比较少,而且比较简单,体验感比较好,但注册界面色调和设计全无&a…