WebApi 中请求的 JSON 数据字段作为 POST 参数传入
使用 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 参数传入的更多相关文章
- 在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法
在使用Ajax请求返回json数据的时候IE浏览器弹出下载保存对话框的解决方法 最近在做一个小东西,使用kindeditor上传图片的时候,自己写了一个上传的方法,按照协议规则通过ajax返回json ...
- 【VueJS】VueJS开发请求本地json数据的配置
VueJS开发请求本地json数据的配置,旧版本是build/dev-server.js,新版本是build/webpack.dev.conf.js. VueJS开发请求本地json数据的配置,早期的 ...
- Beego框架POST请求接收JSON数据
原文: https://blog.csdn.net/Aaron_80726/article/details/83870563 ------------------------------------- ...
- Swift语言中如何使用JSON数据教程
这是一篇翻译文章,原文出处:http://www.raywenderlich.com/82706/working-with-json-in-swift-tutorial Swift语言中如何使用JSO ...
- WPF:使用Json.NET在TreeView中树形显示JSON数据
原文 WPF:使用Json.NET在TreeView中树形显示JSON数据 据 读者可以参考这个开源的可以树形显示XML和JSON的工具: Mgen Object 603:XML/JSON树形显示小工 ...
- PHP/Post 提交请求获取json数据,并转化为所需要的数组
/** * Post 提交请求获取json数据,并转化为所需要的数组 */ function request_post($url = '', $param = '') { if (empty($url ...
- 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回
作者:ssslinppp 时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...
- Nginx下HTML页面POST请求静态JSON数据返回405状态
在浏览器访问HTML页面,发现一些静态JSON数据没有显示,F12查看,如下图所示: 可以看到请求方式为POST 将请求链接复制在浏览器地址栏访问,可以正常请求到数据 F12查看,可以看到请求方式为G ...
- 手把手教你vue配置请求本地json数据
本篇文章主要介绍了vue配置请求本地json数据的方法,分享给大家,具体如下:在build文件夹下找到webpack.dev.conf.js文件,在const portfinder = require ...
随机推荐
- AGC039D 题解
题目描述 给定在笛卡尔坐标系的单位圆上的\(N\)个点(圆心为\((0, 0)\)).第\(i\)个点的坐标为\((cos(\frac{2 \pi T_i}{L}), sin(\frac{2 \pi ...
- http请求user_agent字段解析
浏览器的常见User Agent 各字段的解释 浏览器的User Agent字段令人迷惑,例如:某一版本的Chrome访问网络时,User Agent字段如下: Mozilla/5.0 (Window ...
- oracle修改数据文件目录
一.停库修改数据文件目录.文件名 1.当前数据文件目录 SQL> select file_name from dba_data_files; FILE_NAME ---------------- ...
- 2020-2021-1 20209307 《Linux内核原理与分析》第十一周作业
这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第十一周作业> 这个作业的目标 ...
- Shiro实现Basic认证
前言 今天跟小伙伴们分享一个实战内容,使用Spring Boot+Shiro实现一个简单的Http认证. 场景是这样的,我们平时的工作中可能会对外提供一些接口,如果这些接口不做一些安全认证,什么人都可 ...
- [日常摸鱼]bzoj4802 欧拉函数-PollardRho大整数分解算法
啊居然要特判,卡了好久QAQ (好像Windows下的rand和Linux下的不一样? QwQ一些东西参考了喵铃的这篇blog:http://www.cnblogs.com/meowww/p/6400 ...
- Python中的”黑魔法“与”骚操作“
本文主要介绍Python的高级特性:列表推导式.迭代器和生成器,是面试中经常会被问到的特性.因为生成器实现了迭代器协议,可由列表推导式来生成,所有,这三个概念作为一章来介绍,是最便于大家理解的,现在看 ...
- Python将word文档批量转PDF
前面有一篇<Python批量创建word文档(2)- 加图片和表格>的文章,利用这篇文章创建的word文档来批量转PDF文档.代码: 1 ''' 2 #python批量将word文档转换成 ...
- C# 7-zip 压缩和解压缩
using System; using System.Collections.Generic; using System.Text; using SevenZip; using System.IO; ...
- 使用 transmittable-thread-local 组件解决 ThreadLocal 父子线程数据传递问题
在某个项目中,需要使用mybatis-plus多租户功能以便数据隔离,前端将租户id传到后端,后端通过拦截器将该租户id设置到ThreadLocal以便后续使用,代码大体上如下所示: ThreadLo ...