使用 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 下测试通过。其他框架版本未测试。

WebApi 中请求的 JSON 数据字段作为 POST 参数传入的更多相关文章

  1. 在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法

    在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法 最近在做一个小东西,使用kindeditor上传图片的时候,自己写了一个上传的方法,按照协议规则通过ajax返回json ...

  2. 【VueJS】VueJS开发请求本地json数据的配置

    VueJS开发请求本地json数据的配置,旧版本是build/dev-server.js,新版本是build/webpack.dev.conf.js. VueJS开发请求本地json数据的配置,早期的 ...

  3. Beego框架POST请求接收JSON数据

    原文: https://blog.csdn.net/Aaron_80726/article/details/83870563 ------------------------------------- ...

  4. Swift语言中如何使用JSON数据教程

    这是一篇翻译文章,原文出处:http://www.raywenderlich.com/82706/working-with-json-in-swift-tutorial Swift语言中如何使用JSO ...

  5. WPF:使用Json.NET在TreeView中树形显示JSON数据

    原文 WPF:使用Json.NET在TreeView中树形显示JSON数据 据 读者可以参考这个开源的可以树形显示XML和JSON的工具: Mgen Object 603:XML/JSON树形显示小工 ...

  6. PHP/Post 提交请求获取json数据,并转化为所需要的数组

    /** * Post 提交请求获取json数据,并转化为所需要的数组 */ function request_post($url = '', $param = '') { if (empty($url ...

  7. 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回

    作者:ssslinppp      时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...

  8. Nginx下HTML页面POST请求静态JSON数据返回405状态

    在浏览器访问HTML页面,发现一些静态JSON数据没有显示,F12查看,如下图所示: 可以看到请求方式为POST 将请求链接复制在浏览器地址栏访问,可以正常请求到数据 F12查看,可以看到请求方式为G ...

  9. 手把手教你vue配置请求本地json数据

    本篇文章主要介绍了vue配置请求本地json数据的方法,分享给大家,具体如下:在build文件夹下找到webpack.dev.conf.js文件,在const portfinder = require ...

随机推荐

  1. 痞子衡嵌入式:了解i.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1060系列ROM中串行NOR Flash启动初始化流程优化点. 前段时间痞子衡写了一篇 <深入i.MXRT1050系 ...

  2. js内存泄漏的问题?

    内存泄漏指任何对象在您不再拥有或需要它之后仍然存在. 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量.如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环 ...

  3. 【JVM】类加载器与双亲委派

    类加载器,顾名思义,即是实现类加载的功能模块,负责将Class的字节码形式加载成内存形式的Class对象.字节码文件可来源于磁盘或者jar包中的Class文件,也可以来自网络字节流. 类加载器 在JV ...

  4. 【题解】「CF675A」Infinite Sequence

    我用的是:分类讨论+暴力 其中分类讨论中,我用了一种namespace名命名空间.如果: \(c = 0\) : 当 \(a == b\) 时,输出 \(YES\) 否则 \(NO\) \(c < ...

  5. NOI Online #2 提高组 游戏

    没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...

  6. 题解-Railgun

    题面 Railgun \(T\) 组测试数据,每次给定 \(n,k\),求(\(F(i)\) 为斐波那契数列第 \(i\) 项): \[\sum_{1\le x_i\le n(1\le i\le k) ...

  7. antDesign获取表单组件的值

    子组件中:  getFormValue是在点击确定按钮获取表单值得事件函数,一旦执行就会执行里边的validate()回调函数 返回的数据中有error和value两种,如果存在error那就是其中某 ...

  8. SMART

    SMART原则: S(Specific):目标必须是具体的,要对标特定的工作指标,不能笼统: M(Measurable):目标必须是可衡量的,衡量的指标是数量化或者行为化的,验证这些指标的数据或者信息 ...

  9. ubuntu 16.04 编译安装 python3.9

    下载 python包 wget https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz 解压 tar zxf Python-3.9.1.tgz ...

  10. Spark性能调优篇三之广播方式传输数据

    广播大变量,重复用到的变量 原因见 https://www.jianshu.com/p/2c297b23ebda