

WebApi 中请求的 JSON 数据字段作为 POST 参数传入
以下为 快照 页面,建议前往来源网站查看,会有更好的阅读体验。
原文链接: http://www.cnblogs.com/oangs/p/14273813.html
使用 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 下测试通过。其他框架版本未测试。
猜你喜欢
-
2
linux C语言多线程编程,如何传入参数,如何获得返回值 发表于 2018-08-07 2...
-
0
c++传入参数的问题 | ascotbeint tex (int a,int b)值传递:有一个形参向函数所属的栈拷贝数据的过程,如果值传递的对象是类对象或是大的结构体对象,将耗费一定的时间和空间。 int tex(int *a,int *b)指针传递:同样...
-
84
http://www.cnblogs.com/wupeiqi/articles/6144178.htmlDjango的内置字段如下:Fieldrequired=True#请求不能为空widget=None#HTML插件label=None#用于生成lable标签或显示内容initial=None#初始值help_text=''#帮助信息(在标签旁边显示)error_messages=None#(错...
-
32
-
2
为何condition_variable不设计成传入BaseLockable? - 知乎登录一下,更多精彩内容等你发现贡献精彩回答,参与评论互动查看全部 3 个回答
-
1
现在有个需求就是 有张表,表的字段 有时候会增加 或者减少, 用大数据的话 采用什么方式合理。我想过用HBASE,但是考虑到后续需要对这些数据进行数据分析,HBASE在数据分析这块儿 又没有什么优势。所以有些顾虑,不知道朋友有什么好的方法没 。有知道的朋友还
-
31
springmvc 的请求流程,相信大家已经很熟悉了,不熟悉的同学可以参考下资料! 有了整体流程的概念,是否对其中的实现细节就很清楚呢?我觉得不一定,比如:单是参数解析这块,就是个大学问呢? 首先,我们从最靠近请求末...
-
52
通过Feign包装rpc的调用姿势,在使用的版本中发现一个奇怪的bug,大部分场景下请求正常,少数情况下请求返回400,记录下原因 场景复现 1. 环境相关版本 Spring版本如 <...
-
34
内网通过K8S搭建多个分支测试环境,可是如果外网需要访问而且域名都是一致的情况下,这个时候变得麻烦了。如何通过不同的请求参数访问不同的后端环境呢,答案是可以的,通过lua可以达到。入口:http://fengwan.blog.51cto.com/?envs=branches#branches环境http://fe...
-
23
在日常使用 SpringMVC 进行开发的时候,有可能遇到前端各种类型的请求参数,这里做一次相对全面的总结。 SpringMVC 中处理控制器参数的接口是 HandlerMethodArgumentResolver ,此接口有众多子类...
关于极客头条
聚合每日国内外有价值,有趣的链接。