.Net Core 迁移之坑一 《WebAPI Get请求参数传入输入带有[]不识别问题》

在Framwork 体系下 WebAPI项目 会有很多默认特性,例如:Get查询竟然支持三种数组查询方式

1.https://localhost:44390/api/values?status=1&status=2

2.https://localhost:44390/api/values?status[]=1&status[]=2

3.https://localhost:44390/api/values?status[0]=1&status[1]=2

直到客户端同鞋找到我,才发现第二种在.net core webapi 默认竟然不支持

于是google了好久加上询问大牛,才找到一个解决方案,就是通过 Conventions 解决

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Primitives;
using System;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;

namespace WebApplication
{
    public class ArraryHandleQueryConvention : IParameterModelConvention
    {
        public void Apply(ParameterModel parameter)
        {
            if (parameter.ParameterType.IsArray || parameter.Attributes.OfType<FromQueryAttribute>().Any())
                parameter.Action.Filters.Add(new ArrayQueryStringAttribute(parameter.ParameterName));
        }
    }
    public class ArrayQueryStringValueProvider : QueryStringValueProvider
    {
        private readonly string _key;
        private readonly IQueryCollection _values;

        public ArrayQueryStringValueProvider(IQueryCollection values)
            : this(null, values)
        {
        }

        public ArrayQueryStringValueProvider(string key, IQueryCollection values)
            : base(BindingSource.Query, values, CultureInfo.InvariantCulture)
        {
            _key = key;
            _values = values;
        }

        public override ValueProviderResult GetValue(string key)
        {
            var result = base.GetValue(key + "[]");

            if (_key != null && _key != key)
            {
                return result;
            }
            if (result != ValueProviderResult.None)
            {
                var splitValues = new StringValues(result.Values.ToArray());
                return new ValueProviderResult(splitValues, result.Culture);
            }
            return result;
        }
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class ArrayQueryStringAttribute : Attribute, IResourceFilter
    {
        private readonly ArrayQueryStringValueProviderFactory _factory;

        public ArrayQueryStringAttribute(string key)
        {
            _factory = new ArrayQueryStringValueProviderFactory();
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
        }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            context.ValueProviderFactories.Insert(0, _factory);
        }
    }
    public class ArrayQueryStringValueProviderFactory : IValueProviderFactory
    {
        private readonly string _key;

        public ArrayQueryStringValueProviderFactory() 
        {
        }

        public ArrayQueryStringValueProviderFactory(string key)
        {
            _key = key;
        }

        public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
        {
            context.ValueProviders.Insert(0, new ArrayQueryStringValueProvider(_key, context.ActionContext.HttpContext.Request.Query));
            return Task.CompletedTask;
        }
    }
}
View Code

StartUp 里面添加就行了如图

说者无意听者有心,后来大牛找到我说其实还有第二种方式 就是 JQueryQueryStringValueProviderFactory

1行代码就解决了有木有

看下结果大功告成

 

posted @ 2018-07-15 17:18  布洛克菲勒  阅读(2717)  评论(6编辑  收藏  举报