.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. git参考书籍

    Pro GIt 简体中文版 http://iissnan.com/progit/

  2. 【转】angular学习笔记(十四)-$watch(1)

    本篇主要介绍$watch的基本概念: $watch是所有控制器的$scope中内置的方法: $scope.$watch(watchObj,watchCallback,ifDeep) watchObj: ...

  3. 用VisualSVN做项目版本控制

    一.SVN服务端 1.VisualSVN Server下载: http://download.csdn.net/detail/jiminull/4448874 或 http://www.visuals ...

  4. HDU 5699 货物运输 二分判定

    转自:http://blog.csdn.net/jtjy568805874/article/details/51480479 #include <cstdio> #include < ...

  5. HDU4612 Warm up 边双(重边)缩点+树的直径

    题意:一个连通无向图,问你增加一条边后,让原图桥边最少 分析:先边双缩点,因为连通,所以消环变树,每一个树边都是桥,现在让你增加一条边,让桥变少(即形成环) 所以我们选择一条树上最长的路径,连接两端, ...

  6. 在FOR中使用close window,循环次数大于1就会报异常

    在FOR循环中执行以下动作: 场景:1.打开页面A,    2.点击A中的链接打开新的window, 3.将driver切换到新window, 4.close window 5.再切换到页面A 时出异 ...

  7. Ubuntu上搭建Watir-Webdriver与Cucumber环境

    本文主要演示如何在Ubuntu上搭建Watir-Webdriver与Cucumber环境,用于自动化测试. 1. Ubuntu环境 A. 安装 因为我的工作机是Windows,所以采用虚拟机的方式使用 ...

  8. 富文本HTML编辑器UEditor

    Baidu百度开源富文本HTML编辑器UEditor JS代码网 发表于: 2013-10-30 分类:HTML编辑器  点击:2133  UEditor是由百度web前端研发部开发所见即所得富文本H ...

  9. Spring talk简单配置

    XMl文件 <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://w ...

  10. Stm32外围模块编程初始化步骤

    Stm32外围模块编程初始化步骤: 一.外部中断 1)初始化 IO 口为输入. 这一步设置你要作为外部中断输入的 IO 口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要 ...