zoukankan      html  css  js  c++  java
  • .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(0,new StringTrimModelBinderProvider(options.InputFormatters));
                })

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

  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/FateHuli/p/11328764.html
Copyright © 2011-2022 走看看