博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET Core 使用ModelBinder去掉所有参数的空格
阅读量:5313 次
发布时间:2019-06-14

本文共 5270 字,大约阅读时间需要 17 分钟。

一.前言

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

然后查看官网和源码之后,发现继承并实现 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(0,new StringTrimModelBinderProvider(options.InputFormatters));            })

 

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

 

转载于:https://www.cnblogs.com/FateHuli/p/11328764.html

你可能感兴趣的文章
AndroidArchitecture
查看>>
原生JavaScript第六篇
查看>>
JS基础学习3
查看>>
Tennis Championship
查看>>
SQL
查看>>
JavaScript基础-var
查看>>
javascript 进阶篇1 正则表达式,cookie管理,userData
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
用WebClinet实现SharePoint上文档库中文件的上传与下载
查看>>
Silverlight和javascript的相互调用
查看>>
SQL Server 2005 Express 附加数据库只读 解决方案
查看>>
opencv中的Bayes分类器应用实例
查看>>
大数据学习
查看>>
[BZOJ2982]combination
查看>>
简单工厂模式
查看>>
Delphi7编译的程序自动中Win32.Induc.a病毒的解决办法
查看>>
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>