.net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二)

.net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (一)

上一篇主要是以Form键值对提交的数据,转为Json方式处理,有时我们直接以Body字串提交,我们要解决以下两种方式提交的取值问题:

JObject

$('#btn_add').click(function (e) {
var a = $('#tb_departments').bootstrapTable('getSelections');
var post = "{'str1':'foovalue', 'str2':'barvalue'}";// JSON.stringify(a);
$.ajax({
type: "POST",
url: "/Home/bout",
contentType: "application/json",//必须有
dataType: "json", //表示返回值类型,不必须
data: post,//相当于 //data: "{'str1':'foovalue', 'str2':'barvalue'}",
success: function (data) {
//获取数据ok
alert(JSON.toString(data));
}
});
});

JArray

 $('#btn_delete').click(function (e) {
var a = $('#tb_departments').bootstrapTable('getSelections');
var post = JSON.stringify(a);
$.ajax({
type: "POST",
url: "/Home/About",
contentType: "application/json",//必须有
dataType: "json", //表示返回值类型,不必须
data: post,//相当于 //data: "{[{'str1':'foovalue', 'str2':'barvalue'},{'str1':'foovalue', 'str2':'barvalue'}]}",
success: function (data) {
//获取数据ok
alert(data.id + "--" +data.userName);
}
});
});

在.net core 中没有用于取Body值的ValueProvider,编一个,这是基于工厂模式的ValueProvider,先上代码 实现IValueProviderFactory接口:

 public class JObjectValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext controllerContext)
{
if (controllerContext == null) throw new ArgumentNullException("controllerContext");
if (controllerContext.ActionContext.HttpContext.Request.ContentType == null) { return Task.CompletedTask; } ; if (!controllerContext.ActionContext.HttpContext.Request.ContentType.
StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
return Task.CompletedTask;//不是"application/json"类型不处理交给原有的
}
var bodyText = string.Empty;
using (var reader = new StreamReader(controllerContext.ActionContext.HttpContext.Request.Body))
{
bodyText = reader.ReadToEnd().Trim();//取得Body
}
if (string.IsNullOrEmpty(bodyText)) { return Task.CompletedTask; }//为空不处理
else
{//添加JObject一ValueProviders以便处理值
controllerContext.ValueProviders.Add(
new JObjectValueProvider(bodyText.EndsWith("]}") ?//是不是组
JArray.Parse(bodyText) as JContainer ://是Jarray
JObject.Parse(bodyText) as JContainer));// JObject
}
return Task.CompletedTask;
}
}

对应的IValueProvider:

 internal class JObjectValueProvider : IValueProvider
{
private JContainer _jcontainer;
public JObjectValueProvider(JContainer jcontainer)
{
_jcontainer = jcontainer;
}
public bool ContainsPrefix(string prefix)
{
// return _jcontainer.SelectToken(prefix) != null;
return true;
}
public ValueProviderResult GetValue(string key)
{
var jtoken = _jcontainer.SelectToken("");
if (jtoken == null) return ValueProviderResult.None;
return new ValueProviderResult( jtoken.ToString(), CultureInfo.CurrentCulture);
}
}

在Startup中注册:

 services.AddMvc(options =>
{
options.ValueProviderFactories.Add(new JObjectValueProviderFactory());//取值
options.ModelBinderProviders.Insert(0, new JObjectModelBinderProvider());//加入Jobject绑定
});

由于新增//Jarray类型对.net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (一) JObjectModelBinderProvider做了改动

 public class JObjectModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (context.Metadata.ModelType == (typeof(JObject)))//同时支Body持数据JObject,和Form键值对
{
return new JObjectModelBinder(context.Metadata.ModelType);
}
if (context.Metadata.ModelType == (typeof(JArray)))//Jarray支持
{
return new JObjectModelBinder(context.Metadata.ModelType);
}
return null;
}
}

同样也必须对JObjectModelBinder相应修改以增加对JObject,JArray支持,当然也可以另外写

 public class JObjectModelBinder : IModelBinder
{
public JObjectModelBinder(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null) throw new ArgumentNullException("bindingContext");
ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);//调用取值 ValueProvider
try
{
if (bindingContext.ModelType == typeof(JObject))
{
JObject obj = new JObject();
if (bindingContext.ActionContext.HttpContext.Request.ContentType == "application/json")//json
{
if (result.ToString().StartsWith("["))//是否是组?
{
obj =(JObject) JArray.Parse(result.ToString()).First;//取首值。
bindingContext.Result = (ModelBindingResult.Success(obj));
return Task.CompletedTask;
}
else
{
obj = JObject.Parse(result.ToString());//不是组直接取值
}
}
else //form
{
foreach (var item in bindingContext.ActionContext.HttpContext.Request.Form)
{
obj.Add(new JProperty(item.Key.ToString(), item.Value.ToString()));
}
}
if ((obj.Count == 0))
{
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(result.ToString()));
return Task.CompletedTask;
}
bindingContext.Result = (ModelBindingResult.Success(obj));
return Task.CompletedTask;
}
if (bindingContext.ModelType == typeof(JArray ))
{
JArray obj = new JArray();
if (bindingContext.ActionContext.HttpContext.Request.ContentType.
StartsWith("application/json", StringComparison.OrdinalIgnoreCase))//json
{
if (result.ToString().StartsWith("["))//是否是组?
{
JArray array = new JArray();
array = JArray.Parse(result.ToString());//取首值。
bindingContext.Result = (ModelBindingResult.Success(array));
return Task.CompletedTask;
}
}
if ((obj.Count == 0))
{
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(result.ToString()));
return Task.CompletedTask;
}
bindingContext.Result = (ModelBindingResult.Success(obj));
return Task.CompletedTask;
}
return Task.CompletedTask;
}
catch (Exception exception)
{
if (!(exception is FormatException) && (exception.InnerException != null))
{
exception = ExceptionDispatchInfo.Capture(exception.InnerException).SourceException;
}
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, exception, bindingContext.ModelMetadata);
return Task.CompletedTask;
}
}
}

控制器写法Form键值对、JObject、Jarry方式一样   public IActionResult bout(JArray data)

在客户客户端有区别,JObject、Jarry数据必须指定: contentType: "application/json",//必须有

当以json内容为数组时提交,控制器接收类型为JObject,只取第一个JObject。

.net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二)的更多相关文章

  1. .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (一)

    .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二) Json是WEB交互常见的数据,.net core 处理方式是转为强类型,没有对应的强类型会被抛弃,有时 ...

  2. 8.Yii2.0框架控制器接收get.post数据

    8.Yii2.0框架控制器接收get.post数据 一.get传参 <?php /** * Created by Haima. * Author:Haima * QQ:228654416 * D ...

  3. Spring MVC同时接收一个对象与List集合对象

    原:https://blog.csdn.net/u011781521/article/details/77586688/ Spring MVC同时接收一个对象与List集合对象 2017年08月25日 ...

  4. mvc控制器接收ajax传送的数据

    视图层中ajax传数据 $.ajax({ type: "post",//提交方式 data: { complay_arry: complay_arry, site_arry: si ...

  5. .net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象

    原文地址:http://www.cnblogs.com/fannyatg/archive/2012/04/16/2451611.html ------------------------------- ...

  6. 2016 系统设计第一期 (档案一)MVC 控制器接收表单数据

    1.FormCollection collection   user.UserId =Convert.ToInt32(collection["UserId"]); /// < ...

  7. Spring MVC rest接收json中文格式数据显示乱码

    1.解决方法其中之一 在web.xml下添加配置: <!-- 编码配置 --> <filter> <filter-name>CharacterEncodingFil ...

  8. 接收JSON类型转成对象

    写个小例子吧: public String getJsonTest(String jsonString){} 参数是json 参数长这样  ===> {  'puser' : {'id' : ' ...

  9. ASP.NET Core MVC 控制器创建与依赖注入

    本文翻译自<Controller activation and dependency injection in ASP.NET Core MVC>,由于水平有限,故无法保证翻译完全准确,欢 ...

随机推荐

  1. Java [leetcode 16] 3Sum Closest

    题目描述: Given an array S of n integers, find three integers in S such that the sum is closest to a giv ...

  2. android应用分析之apk文件结构

            实际上,一个APK文件就是一个.zip格式的压缩包,我们可以用解压缩工具打开任何一个APK文件,由于代码混淆和加密,通过普通解压缩工具打开里面的文件或目录会看到各种乱码.一个典型的ap ...

  3. jQuery树叶掉落特效代码

    代码使用方法 1.将index.html源文件中的JS设置代码插入到你的网页中 2.将style.css文件内容合并到你的页面样式表中 3.将jquery文件加载到你的页面中,请注意,这不是通用的jq ...

  4. 一滴一点vim(学习+备忘)

    普通模式: h j k l 分别是左下上右方式移动: :w 保存修改 :q 推出 :wq 保存修改并退出 :q! 放弃修改强制推出 x 删除光标所在位置字符 i 在光标所以位置插入字符 删除类命令: ...

  5. 我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp)

    我的Modbus Slave/Client开发历程(Rtu/AscII/Tcp) 分类: [自动化]2007-07-19 10:04 34038人阅读 评论(38) 收藏 举报 vb嵌入式dostcp ...

  6. JS注入操作页面对象

    在用selenium webdriver 编写web页面的自动化测试代码时,有时对页面对象的操作需要通过js语句去执行,selenium本身就支持执行js,我们在代码中import org.openq ...

  7. SVN server 安装 并创建用户访问

    1. 下载svn   官网https://www.visualsvn.com/server/download/ 或者其他网站都行,下载是VisualSVN-Server-3.5.6.msi. 2.安装 ...

  8. Linux Oracle碰到错误:ORA-27101: shared memory realm does not exist

    从ITPUB上摘抄并已验证 1.实例没有启动 sqlplus /nologconnect / as sysdbastartup

  9. wuzhicms 模块开发

    首先,模块开发需要了解五指cms的目录结构: 然后,我们需要新增加一个模块目录: 再app下面创建 如:content 下面包含文件: 前台文件的创建: 看下 index.php 的内容: <? ...

  10. Project: Individual Project - Word frequency program----11061192zmx

    Description & Requirements http://www.cnblogs.com/jiel/p/3311400.html 项目时间估计 理解项目要求: 1小时 构建项目逻辑: ...