惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
D
Docker
GbyAI
GbyAI
Y
Y Combinator Blog
C
Check Point Blog
M
MIT News - Artificial intelligence
Martin Fowler
Martin Fowler
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Blog — PlanetScale
Blog — PlanetScale
P
Palo Alto Networks Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V
Vulnerabilities – Threatpost
I
InfoQ
Simon Willison's Weblog
Simon Willison's Weblog
博客园_首页
T
Threat Research - Cisco Blogs
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Register - Security
The Register - Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
阮一峰的网络日志
阮一峰的网络日志
O
OpenAI News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Announcements
Recent Announcements
Forbes - Security
Forbes - Security
AWS News Blog
AWS News Blog
雷峰网
雷峰网
博客园 - 三生石上(FineUI控件)
S
Security Affairs
H
Heimdal Security Blog
Engineering at Meta
Engineering at Meta
T
Troy Hunt's Blog
T
Tenable Blog
MongoDB | Blog
MongoDB | Blog
H
Hacker News: Front Page
IT之家
IT之家
N
News and Events Feed by Topic
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
S
Secure Thoughts
U
Unit 42
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Last Watchdog
The Last Watchdog
S
Security @ Cisco Blogs
NISL@THU
NISL@THU
T
The Blog of Author Tim Ferriss

博客园 - YbSoftwareFactory

YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法 YbSoftwareFactory 代码生成插件【二十四】:MVC中实现动态自定义路由 YbSoftwareFactory 代码生成插件【二十三】:集成强大的公文流转系统 YbSoftwareFactory 代码生成插件【二十二】:CMS基础功能的实现 YbSoftwareFactory 代码生成插件【二十一】:Web Api及MVC性能提升的几个小技巧 YbSoftwareFactory 代码生成插件【十九】:实体类配合数据库表字段进行属性扩展的小技巧 YbSoftwareFactory 代码生成插件【十八】:树形结构下的查询排序的数据库设计 YbSoftwareFactory 代码生成插件【十七】:先进的权限模型体系设计 YbSoftwareFactory 代码生成插件【十六】:Web 下灵活、强大的审批流程实现(含流程控制组件、流程设计器和表单设计器) YbSoftwareFactory 代码生成插件【十五】:Show 一下最新的动态属性扩展功能与键值生成器功能 YbSoftwareFactory 代码生成插件【十四】:通过 DynamicLinq 简单实现 N-Tier 部署下的服务端数据库通用分页 YbSoftwareFactory 代码生成插件【十三】:Web API 的安全性 YbSoftwareFactory 代码生成插件【十二】:超级灵活方便的应用程序设置管理API YbSoftwareFactory 代码生成插件【十一】:ASP.NET WebApi MVC下组织机构管理和菜单权限管理的实现 YbSoftwareFactory 代码生成插件【十】:ASP.NET WebApi MVC下审计、缓存和导出功能的实现 YbSoftwareFactory 代码生成插件【九】:基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析 YbSoftwareFactory 代码生成插件【八】:基于JQuery EasyUI、Web Api的 ASP.NET MVC 代码生成插件 YbSoftwareFactory 代码生成插件【七】:YbRapidSolution for WinForm 插件生成项目总体架构介绍 YbSoftwareFactory 代码生成插件【六】:WinForm 完美解决方案的代码生成插件
YbSoftwareFactory 代码生成插件【二十】:DynamicObject的序列化
YbSoftwareFactory · 2014-10-13 · via 博客园 - YbSoftwareFactory

    DynamicObject 是 .NET 4.0以来才支持的一个类,但该类在.NET 4.0下未被标记为[Serializable] Attribute,而在.NET 4.5下则被标记了[Serializable] Attribute。需要注意的是,如果你使用需要进行XML序列化等操作(例如WCF中),部署到未安装.NET 4.5的环境中通常会报错并提示异常,而不管你编译时使用的目标平台是.NET 4.0 还是 .NET 4.5。通常这个错误在安装了.NET 4.5环境的开发机上通常没有问题,即使你创建的项目是基于.NET 4.0的,但实际调用的还是 .NET 4.5的库。因此通常在使用 DynamicObject 并需要进行序列化的情景下需要谨慎(特别是WCF环境下),除非你实现了你自定义的序列化操作。在此提醒广大开发人员注意,否则到你正式部署至不能安装.NET 4.5的环境中将折腾你够呛(例如Windows Server 2003等环境)。

    在前文:“实体类配合数据库表字段进行属性扩展” 一文中介绍了如何使用 DynamicObject 进行属性的扩展,但该类在MVC下进行JSON序列化时其序列化的结果并不友好。本文主要讨论的是如何友好地对 DynamicObject 继承类进行JSON序列化。

    要对 DynamicObject 对象实现JSON的序列化,其实只需在 DynamicObject 的继承类中实现 IDictionary<string,object> 接口即可,因为 JavaScriptSerializer 和 Json.NET 均支持对 IDictionary<string,object> 的序列化,该接口主要对 DynamicObject 对象的属性和值进行管理。前文所述的ExtensionObject类就继承自DynamicObject类,并实现了 IDynamicMetaObjectProvider 和 IDictionary<string,object> 接口。

    在MVC中原生态的 JavascrioptSerializer 序列化时会使用 IDictionary<string,object> 的实现方法 System.Collections.IEnumerable.GetEnumerator() 来获取要序列化的属性名。

    而Json.NET则调用 IDictionary<string,object> 的实现方法 IEnumerable<KeyValuePair<string, object>>.GetEnumerator() 来获取属性及其值。

    但二者最大的区别是,使用JavascrioptSerializer将序列化成如下的JSON格式:

{{"Key":"Code","Value":"4"},{"Key":"ID","Value":"d8ea26b06d9d4c7e85ccc43da71320ac"},{"Key":"LongName","Value":"null"},           {"Key":"FCode","Value":"/51/5100/4"},{"Key":"NodeLevel","Value":"3"}}

    而使用Json.NET则序列化为:{"ID": "d8ea26b06d9d4c7e85ccc43da71320ac","Code": "4","LongName": null,"FCode": "/51/5100/4","NodeLevel": 3}

    毫无疑问,使用Json.NET进行序列化更符合实际的情况和需要,而且速度还更快。当然,在WebApi下,因为已使用了Json.NET作为默认的序列化组件,并不存在上述问题,因此本文将主要对MVC中对DynamicObject的Json.NET序列化的实现进行说明。

    一、MVC下使用Json.NET序列化

    1、实现自定义ActionResult,继承自JsonResult类,代码如下:

using System;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace YbRapidSolution.Presenter.JsonNet
{
    public class JsonNetResult : JsonResult
    {
        public JsonSerializerSettings SerializerSettings { get; set; }
        public JsonNetResult()
            : base()
        {
            // create serializer settings
            this.SerializerSettings = new JsonSerializerSettings();
            // 阻止属性循环引用的情况下出现的异常
            this.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            // setup default serializer settings
            this.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
        }
        public JsonNetResult(string contentType)
            : this()
        {
            ContentType = contentType;
        }
        public JsonNetResult(string contentType, System.Text.Encoding contentEncoding)
            : this(contentType)
        {
            ContentEncoding = contentEncoding;
        }
        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
                String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("Json request GET not allowed");
            }
            // 获取当前 http context response
            var response = context.HttpContext.Response;
            // 设置 content type
            response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
            // 设置 encoding
            if (ContentEncoding != null)
                response.ContentEncoding = this.ContentEncoding;
            if (Data != null)
            {
                // 使用 JSON.Net 把对象序列化为 JSON 
                string jsonText = JsonConvert.SerializeObject(this.Data, Formatting.Indented, this.SerializerSettings);
                // write the response
                response.Write(jsonText);
            }
        }
    }
}

    2、对Controller进行方法的扩展

using System.Dynamic;
using System.Web.Mvc;
using YbRapidSolution.Presenter.Controllers;

namespace YbRapidSolution.Presenter.JsonNet
{
    public static class JsonNetControllerExtensions
    {
        public static JsonNetResult JsonNet(this Controller controller, object data)
        {
            return new JsonNetResult() { Data = data };
        }
        public static JsonNetResult JsonNet(this Controller controller, object data,string contentType)
        {
            return new JsonNetResult(contentType) { Data = data };
        }
    }
}

    3、调用方式的Demo如下:

/// <summary>
        /// 查找当前登录用户的当前岗位对本模块所具有的动作权限集合
        /// </summary>
        /// <param name="orgFId">当前登录用户所使用的岗位(人员成员)的标识全路径</param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [YbMvcAuthorize(PermissionKeys = PERMISSIONKEY)]
        public JsonResult FindAllowActionsFor(string orgFId)
        {
            try
            {
                var curMessage = new EasyUIMessage(true, "权限项加载成功");
                //查询类型为按钮或右键菜单的动作
                var actions = _permissionService
                    .FindControlsForOrgByKeyAndOrgFId(PERMISSIONKEY,orgFId);
                
                curMessage.data = actions;
                return this.JsonNet(curMessage);
            }
            catch (Exception er)
            {
                var curMessage = new EasyUIMessage(false, string.Format("权限项加载失败:{0}", er.Message));
                return this.JsonNet(curMessage);
            }
        }

    二、Web Api下使用Json.NET序列化

    Web Api因为使用Json.NET作为默认的JSON序列化实现框架,通常需在 WebApiConfig 类的 Register 中写如下的代码进行配置即可:

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
                = ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
                = PreserveReferencesHandling.Objects; 

    如需了解更多请点击:权限模型+流程专家 Demo

    附一:ExtensionObject源码

    附二:YbSoftwareFactory操作手册

    附三:YbSoftwareFactory底层组件帮助文档

    下一章将分享WebApi和MVC下的提升性能的一些经验。