.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. Bootstrap 源码解析(转)

    1.Bootstrap的作用域 2.Bootstrap的类定义 3.Bootstrap的插件定义 4.Bootstrap的事件代理 5.Bootstrap的对象数据缓存 6.Bootstrap的防冲突 ...

  2. 【转】Windows环境下Android NDK环境搭建

    原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员 ...

  3. angularjs filter 详解

    系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter.如果对smarty比较熟悉的话,学习angularjs会比较容易一点.这 ...

  4. SharePoint Designer定制MOSS/WSS表单页面

    转:http://blog.csdn.net/yl_99/article/details/7087897 方法一.使用SharePoint Designer配合enderingTemplate文件来定 ...

  5. Asp.Net 高性能框架 SqlSugar.ORM 2.3

    一.前言 SqlSugar从去年到现在已经一年了,版本从1.0升到了现在的2.3 ,这是一个稳定版本 ,有数家公司已经项目上线,在这里我将SqlSugar的功能重新整理成一篇新的贴子,希望大家喜欢. ...

  6. android:installLocation简析

    在Froyo(android 2.2,API Level:8)中引入了android:installLocation.通过设置该属性可以使得开发者以及用户决定程序的安装位置. android:inst ...

  7. 【工具类】如何通过代码安装一个apk文件

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Android UI -- 的基础知识。

    在介绍基础知识之前先明确几个基本的概念 View 视图是所有可视组件的基类,所有的UI控件包括布局类都是从View派生出来的. ViewGroup ViewGroup是View的扩展,可以放置多个Vi ...

  9. MMU(why)

    在ARM中,MMU几个主要作用: 1. I/D Cache 管理      -> 大幅提高代码运行效率. 2. PA/VA 重映射        -> 实现多进程内存空间映射. 3. 内存 ...

  10. MariaDB-5.5.32源码编译安装

    MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:Oracle公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分 ...