使用 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. AGC039D 题解

    题目描述 给定在笛卡尔坐标系的单位圆上的\(N\)个点(圆心为\((0, 0)\)).第\(i\)个点的坐标为\((cos(\frac{2 \pi T_i}{L}), sin(\frac{2 \pi ...

  2. http请求user_agent字段解析

    浏览器的常见User Agent 各字段的解释 浏览器的User Agent字段令人迷惑,例如:某一版本的Chrome访问网络时,User Agent字段如下: Mozilla/5.0 (Window ...

  3. oracle修改数据文件目录

    一.停库修改数据文件目录.文件名 1.当前数据文件目录 SQL> select file_name from dba_data_files; FILE_NAME ---------------- ...

  4. 2020-2021-1 20209307 《Linux内核原理与分析》第十一周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第十一周作业> 这个作业的目标 ...

  5. Shiro实现Basic认证

    前言 今天跟小伙伴们分享一个实战内容,使用Spring Boot+Shiro实现一个简单的Http认证. 场景是这样的,我们平时的工作中可能会对外提供一些接口,如果这些接口不做一些安全认证,什么人都可 ...

  6. [日常摸鱼]bzoj4802 欧拉函数-PollardRho大整数分解算法

    啊居然要特判,卡了好久QAQ (好像Windows下的rand和Linux下的不一样? QwQ一些东西参考了喵铃的这篇blog:http://www.cnblogs.com/meowww/p/6400 ...

  7. Python中的”黑魔法“与”骚操作“

    本文主要介绍Python的高级特性:列表推导式.迭代器和生成器,是面试中经常会被问到的特性.因为生成器实现了迭代器协议,可由列表推导式来生成,所有,这三个概念作为一章来介绍,是最便于大家理解的,现在看 ...

  8. Python将word文档批量转PDF

    前面有一篇<Python批量创建word文档(2)- 加图片和表格>的文章,利用这篇文章创建的word文档来批量转PDF文档.代码: 1 ''' 2 #python批量将word文档转换成 ...

  9. C# 7-zip 压缩和解压缩

    using System; using System.Collections.Generic; using System.Text; using SevenZip; using System.IO; ...

  10. 使用 transmittable-thread-local 组件解决 ThreadLocal 父子线程数据传递问题

    在某个项目中,需要使用mybatis-plus多租户功能以便数据隔离,前端将租户id传到后端,后端通过拦截器将该租户id设置到ThreadLocal以便后续使用,代码大体上如下所示: ThreadLo ...