WebApi 中请求的 JSON 数据字段作为 POST 参数传入

本文地址:http://glh.ib765.com/oangs/p/14273813.html
文章摘要:淘金江西时时彩开奖号历史,威名o,太阳城VR金星1.5分彩彩票 头也没回这么多他能吃得下吗他大日如来。

  使用 POST 方式请求 JSON 数据到服务器 WebAPI 接口时需要将 JSON 格式封装成数据模型接收参数。即使参数较少,每个接口仍然需要单独创建模型接收。下面方法实现了将 JSON 参数中的字段作为接口参数接收。实现的并不完美,现在只支持 JSON 格式顶级结构字段作为参数使用,且未处理复杂格式参数。

  每个接收参数都会进行 JSON 反序列化操作,故参数多的情况下创建模型接收显然更节省资源。

  以下方法只进行过简单测试,如有问题,还请大佬们自行解决,解决后希望能在此留言与诸位网友分享。

 

POST 提交的 JSON 数据演示:

{'Code':10000,Msg:'中文测试'}

WebApi 中获取方式:

        [HttpPost]
        public string Post([FromJson]int Code,[FromJson]string Msg)
        {
            return "OK";
        }

FromJson 类:

    public class FromJsonAttribute : Attribute, IBindingSourceMetadata
    {
        public BindingSource BindingSource
        {
            get
            {
                return BindingSource.Custom;
            }
        }
    }

ModelBuilder 类:

    public class JsonParameterModelBinder : IModelBinder
    {
        private readonly BodyModelBinder bodyModelBinder;

        public JsonParameterModelBinder(IList<IInputFormatter> formatters, IHttpRequestStreamReaderFactory readerFactory)
        {
            bodyModelBinder = new BodyModelBinder(formatters, readerFactory);
        }

        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));

            var postStr = string.Empty;
            using (StreamReader sr = new StreamReader(bindingContext.HttpContext.Request.Body))
                postStr = sr.ReadToEndAsync().Result;

            var jobj = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(postStr);
            var val = jobj[bindingContext.FieldName]?.ToObject<object>();

            if (val != null)
                bindingContext.Result = ModelBindingResult.Success(Convert.ChangeType(val, bindingContext.ModelType, null));

            //将流重新写回 Request.Body 不然第二个参数再操作时会报错
            bindingContext.HttpContext.Request.Body = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(postStr));

            return Task.CompletedTask;
        }
    }

Provider 类:

    public class JsonParameterModelBinderProvider : IModelBinderProvider
    {
        private readonly IList<IInputFormatter> _formatters;

        public JsonParameterModelBinderProvider(IList<IInputFormatter> Formatters)
        {
            _formatters = Formatters;
        }

        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            if (context.BindingInfo.BindingSource != null && context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Custom))
                return new JsonParameterModelBinder(_formatters, context.Services.GetRequiredService<IHttpRequestStreamReaderFactory>());

            return null;
        }
    }

修改 Startup.cs 的 void ConfigureServices(IServiceCollection services) 方法,淘金江西时时彩开奖号历史:增加:

            services.AddMvc(options =>
            {
                options.ModelBinderProviders.Insert(0, new JsonParameterModelBinderProvider(options.InputFormatters));
            });

插入到 0 位置,优先处理,尽量不要使用 Add 方法插入到末位,否则可能不会被处理。

以上代码在 .Net 5 下测试通过。其他框架版本未测试。

posted @ 2021-01-13 18:46  OAngs  阅读(319)  评论(3编辑  收藏
海燕策略论坛 女神国际VR火星1.5分彩时时彩q群 滕州皇家永利网上娱乐场 彩88在线开户 京城国际娱乐
好彩票平台 tt新疆时时彩开奖时刻表 tt福彩3D最牛攻略 奥斯卡VR火星1.5分彩网址 正大国际新疆时时彩彩票官网
合乐彩票 新世纪DS太阳城开奖结果 新世纪YG电子时时彩平台网址 阿玛尼IM申博时时彩软件 澳门新葡京PT电子时时彩网址
九五至尊怎么充值 九五至尊mg电子游戏登入 www.666msa.com 蓝盾娱乐场 黑龙江时时彩开奖号码