[转载]iOS开发笔记3:XML/JSON数据解析 - colinhou - 博客园

mikel阅读(820)

来源: [转载]iOS开发笔记3:XML/JSON数据解析 – colinhou – 博客园

这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法。XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSerialization。

    1.XML解析之NSXMLParser

NSXMLParser是iOS原生的XML解析方式,采用SAX方式进行解析,特点是解析的时候从根元素开始,按顺序依次对每一个元素进行解析。

以下图所示XML文档为例进行解析

(1)首先是实例化一个NSXMLParser,设置代理监听解析过程,开始解析

(2)通过NSXMLParser代理方法对XML文档进行解析

(3)解析效果

    2.XML解析之GDataXML

GDataXML是谷歌制作的一个解析XML数据的类库,基于libxml2,特点是以DOM方式解析,会把XML文档数据一次性加载到内存中,再对数据进行解析。

下载地址:https://github.com/neonichu/GDataXML

还是使用上一节用到的XML文档为例,使用前需要进行配置

(1)设置头文件路径

 

(2)设置链接参数

(3)设置编译参数(GDataXML是非arc的)

加载整个XML文档,对元素进行遍历解析即可  

    3.JSON解析之NSJSONSerialization

JSON数据格式有如下要求,故得到数据后进行对应解析即可,在开发中常用的是将JSON解析为Foundation对象

拿到JSON数据直接使用NSJSONSerialization解析即可

对于JSON字符串最外层既不是NSArray也不是NSDictionary时,option选择NSJSONReadingAllowFragments即可

难得休息

mikel阅读(882)

天天瞎忙,都不知道忙啥!

偶然人家问起自己有啥爱好?都回答不上来了!真的是没时间整啥爱好!除了程序就是程序!除了项目就是项目!

好在选了个自己喜欢的职业,不至于每天干自己不喜欢的事儿了。

有些时候,真的应该让自己慢下来,离开程序离开代码,放下虚拟世界的一切,回归现实过真实的生活。

要想规范化,要学会说不

mikel阅读(1006)

一个初创公司没有规范化的流程、产品报价、产品功能说明、公司管理制度等等,就和一盘散沙没有什么区别,只有公司老板一个人苦逼的拼命跑业务做技术,那不是创业,那是找死。

要想规范化,要学会说不!

很多时候初创公司头疼的是人,没有效益的时候没有激情和斗志,都是很吃等死,和行尸走肉没什么区别;项目效益不错,激情澎湃各个只要给钱就卖,根本不顾及成本和日后的开支;老板看到的是每日的进账和开销,只要进账多就好,这是典型的No Zuo No Die!进账多未必是好事儿,要看这些进账是不是透支了未来的人工成本。

没业务愁,有业务更愁。项目接了不少,各个都说能让公司的踏上一个新的台阶儿,可哪个是靠谱的,都没进行过成本核算,就匆匆上面,人力物力都投入进去了,才发现原来是个南柯一梦,水太深,人太少,估计不足,导致半途而废的常常有。

人来了不出活儿,愁!人来人往本来就是公司的正常情况,但是太频繁或者太慢都不是好事儿,人员青黄不接,有能力的留不住,没能力的赖着不走,然后招人又后继乏力,招不到合适的,公司没人就好比赛车手没有维修工和教练,什么时候能开出个名次,只能听天由命,指着老板一个人累得粗骨扬灰了,都回天无术。

总而言之,麻雀虽小五脏俱全,不要以为哥几个创业开公司全靠兄弟义气,啥管理不管理,规范不规范的,有活大家做,挣钱大家分。学不会说不,就别提规范化,挨不过哥们义气,“不”字说不出口,于人于己都不利。买卖是买卖,交情是交情。

[转载]基于SpringMVC与jquery的ajax提交表单的若干情况详解 - lx_hust - 博客园

mikel阅读(851)

来源: [转载]基于SpringMVC与jquery的ajax提交表单的若干情况详解 – lx_hust – 博客园

在日常的业务中,我们往往使用的是ajax提交页面数据,而不用form的action来提交整个表单。现在我来分享一下我在日常工作中遇到的一些问题。

一、$.post、$.get、$.ajax三者的区别:

顾名思义,$.post和$.get分别是采用post方式和get方式向服务器发送请求。两者的不同是,get请求的参数是在url直接以 url?name1=value1&name2=value2的形式拼接而成,而post请求的参数会以请求正文的形式传送到服务器,这个学习过 javaweb知识的应该都知道,在此也不赘述。

在这里主要想讲的是关于同异步发送请求的。$.post和$.get默认是采用异步的形式向服务器发送请求,但我们的需求中很多情况需要得到服务器的返回值来判断下一步的操作,这个时候就需要用到$.ajax了。

<div class="container">
<div class="line number1 index0 alt2"><code class="javascript keyword">var</code> <code class="javascript plain">flag=</code><code class="javascript keyword">false</code><code class="javascript plain">;</code></div>
<div class="line number2 index1 alt1"><code class="javascript plain">$.ajax({</code></div>
<div class="line number3 index2 alt2"><code class="javascript spaces">             </code><code class="javascript plain">type: </code><code class="javascript string">"get"</code><code class="javascript plain">,</code></div>
<div class="line number4 index3 alt1"><code class="javascript spaces">             </code><code class="javascript plain">url: </code><code class="javascript string">"xxxxxx"</code><code class="javascript plain">,</code></div>
<div class="line number5 index4 alt2"><code class="javascript spaces">             </code><code class="javascript plain">async:</code><code class="javascript keyword">false</code><code class="javascript plain">,</code></div>
<div class="line number6 index5 alt1"><code class="javascript spaces">             </code><code class="javascript plain">data: {username:name, password:pwd},</code></div>
<div class="line number7 index6 alt2"><code class="javascript spaces">             </code><code class="javascript plain">dataType: </code><code class="javascript string">"json"</code><code class="javascript plain">,</code></div>
<div class="line number8 index7 alt1"><code class="javascript spaces">             </code><code class="javascript plain">success: </code><code class="javascript keyword">function</code><code class="javascript plain">(data){</code></div>
<div class="line number9 index8 alt2"><code class="javascript spaces">                                   </code><code class="javascript keyword">if</code><code class="javascript plain">(data&gt;0){</code></div>
<div class="line number10 index9 alt1"><code class="javascript spaces">                                        </code><code class="javascript plain">flag=</code><code class="javascript keyword">true</code><code class="javascript plain">;</code></div>
<div class="line number11 index10 alt2"><code class="javascript spaces">                                   </code><code class="javascript plain">}</code></div>
<div class="line number12 index11 alt1"><code class="javascript spaces">                      </code><code class="javascript plain">}</code></div>
<div class="line number13 index12 alt2"><code class="javascript spaces">         </code><code class="javascript plain">});</code></div>
<div class="line number13 index12 alt2">

  如以上代码,type来设置请求方式,async则设置的是同步或者异步,默认为true异步的,此时设置为false。如果用通常的$.post和$.get的话,flag的值是不会随着返回值data的值发生改变的。

二、文件上传

ajax上传文件一直都是一个比较头疼的问题,在这里我用的是JQuery的一个扩展框架,JQuery.form.js,此包提供了一 个$ajaxSubmit方法,很好的解决了springmvc下文件上传的问题,当然,form表单的method为post,type为 multipart/form-data,示例代码如下:


$(#id).ajaxSubmit({
type: 'post',
url: 'xxxxxx',
data: {
uername: name,
content: content
},
success: function(data) {
//回调函数
}
});

此时,表单数据和文件数据会保存在request中传入服务器。后台获取代码如下:

<pre>MutlipartHttpServletRequest  multipart =(MutlipartHttpServletRequest )request;
//把request转为上传文件专用的request
Map&lt;String,String[]&gt; dataMap = request.getParameterMap();
//获取普通表单数的&lt;name,value&gt;键值对
Map&lt;String,Multipart&gt; fileMap = request.getFileMap();
//获取上传文件的键值对,当未上传文件时,这个键值对会以普通数据存在于dataMap中而不是fieMap中

暂时这么多把,想起来了再加。

开发要做的就是绑架客户

mikel阅读(943)

最近的项目大费周折的开发出来,结果到了交付日期,到客户那发现和客户的需求出入不小,还得调整,主要还是细节,客户看到的是一个二维的表格,根本不知道怎么把表格做成系统,他们习惯了excel记录数据和操作,突然一下从二维四维变成关联性很强的数据表格,一下子提不出合理的方案,只能引导客户挤牙膏般的才能出来真是需求。

很多开发项目都是匆匆调研后,就开始做了,结果往往浪费了最宝贵的时间在修改上。所以说开发首先要做的就是要绑架客户,让客户随时随地在你的身边,然后开发的过程也是个不断迭代的过程,包括界面的设计和功能的开发,都需要先出测试版让客户确认,再进行,否则你就等着交付延期面对无止境的修改吧。

这样客户对你的开发过程也有了解,不至于不知道产生误解,认为这么简单的功能,这么长时间还没做出来,随着你的开发过程的客户全程参与,这样再次开发新的功能,客户也就习惯了你的开发节奏和工作方式,他会自然而然很配合的和你探讨功能需求,这样不至于你不了解业务,客户不了解你的开发流程,导致双方驴唇不对马嘴的抱怨了。

当 IDENTITY_INSERT 设置为 OFF 时,不能为表中的标识列插入显式值

mikel阅读(846)

  • {“当 IDENTITY_INSERT 设置为 OFF 时,不能向表 ‘OrderList’ 中的标识列插入显式值”}

    对于这个异常可以从两个角度来处理:A:数据库执行语句  B:直接修改NHibernate中持久化类映射配置文件id节点

    A数据库执行语句:

    问题描述:当在数据库表主键设计为 (Orderid  int identity primary key),相对这个主键IDENTITY_INSERT默认设置为OFF,就是不能够显示插入主键id的值,例子如下:

    insert into OrderList(id,OrderName) values(4520,’电子传票订单’)

    执行上面语句会提示一个错误:

    服务器: 消息 544,级别 16,状态 1,行 1
    当 IDENTITY_INSERT 设置为 OFF 时,不能向表 ‘OrderList’ 中的标识列插入显式值。

    其中关于主键一条记录,当我们想把这条记录的id设置成我们自定义的4520时出现上面的错误,如果我们添加一些设置,修改方法如下:

    –允许将显式值插入表的标识列中 ON-允许  OFF-不允许
    set identity_insert OrderList ON–打开

    insert into OrderList(id,ordername,createdate)
    values(4520,’set’,getdate())

    set identity_insert OrderList OFF–关闭

    在执行这个插入语句时多了一个设置,该设置的语法是

    –设置语法:

    SET IDENTITY_INSERT database.[ owner.] table ON OFF 
    允许将显式值插入表的标识列中

    参数说明:
    database:针对数据库
    table:针对某张表

    ON:允许插入显式值插入 标识列
    OFF:不允许

    注意:

    当 <wbr>IDENTITY_INSERT <wbr>设置为 <wbr>OFF <wbr>时,不能为表中的标识列插入显式值
    –问题注意

    (1)任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表

    (2)如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用

    (3)SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置

    上面执行语句中:把要执行的语句前后加上该设置,当然上面针对事一条记录插入操作,在这条记录插入操作后,如果再次插入数据时,没有启用该设置,Orderid主键列会根据上面自定义表示4520,自动增长到4521.这个操作很灵活关键看个人怎么利用.

    B:修改配置文件

    我们通过直接修改配置文件来处理这个问题,

    出错时文件配置:

    –hibernate持久化类配置 注意id中Generator子节点设置Class属性为:assigned自动增长
    <hibernate-mapping xmlns=”urn:nhibernate-mapping-2.2″>
        <class name=”TestHibernateExpre.Entities.OrderListModel,TestHibernateExpre” table=”OrderList”>
            <id name=”Orderid” column=”id” type=”int”>
                <!–id中参数的设置问:native/assigned/foreign/increment–>
                <generator class=”assigned”></generator>
            </id>
        </class>

    修改后文件配置:

    –Hibernate中关于持久化类的配置  注意id下Generator子节点 class属性配置为native
    <hibernate-mapping xmlns=”urn:nhibernate-mapping-2.2″>
        <class name=”TestHibernateExpre.Entities.OrderListModel,TestHibernateExpre” table=”OrderList”>
            <id name=”Orderid” column=”id” type=”int”>
                <!–id中参数的设置问:native/assigned/foreign/increment–>
                <generator class=”native”></generator>
            </id>
          </class>

时间都去哪儿了 转眼间就老了?

mikel阅读(1928)

刚刚在闺女的幼儿园给她过完生日,有点儿小激动,一帮孩子突然唱起了《时间都去哪儿了》,一下子被戳中了,感动了。

转眼间闺女都这么大了,自己能不老吗?!时间过得真快!自己还是没好好珍惜,不过还有机会,有梦想就大胆的去追吧!万一实现了呢!

时间催人老,时间不等人,时不我待的互联网+大潮同样是一蹉而就的机会,抓住了也就抓住了,错失了就永远的没有机会了!

SNF快速开发平台3.0之BS页面展示和九大优点-部分页面显示效果-Asp.net+MVC4.0+WebAPI+EasyUI+Knockout - 王春天 - 博客园

mikel阅读(1684)

来源: SNF快速开发平台3.0之BS页面展示和九大优点-部分页面显示效果-Asp.net+MVC4.0+WebAPI+EasyUI+Knockout – 王春天 – 博客园

一)经过多年的实践不断优化、精心维护、运行稳定、功能完善

能经得起不同实施策略下客户的折腾,能满足各种情况下客户的复杂需求。

二)编码实现简单易懂、符合设计模式等理念

上手快,见效快、方便维护,能控制软件项目后期维护风险。

三)有严谨的分层理念、完全符合主流的SOA理念架构

程序可以采用不同的实施策略、架构需求,方便维护、方便扩展。

四)符合RBAC的权限理念、同时也能满足国内小型软件项目的灵活性需求

不仅符合国际通用标准,又能满足国内的小型软件项目的灵活设置需求。

五)不仅支持多数据库也支持多种开发语言、多语言界面

支持B/S、C/S系统,可以支持Java语言开发项目的接口功能WebService,SQLServer、Oracle数据库等。

六)提供全部的设计文档、源码实现、配套说明文档

相关设计文档、配套资料可以在不同软件项目中反复使用,提高工作效率。

七)完全支持最终用户的个性化2次开发实际需求

开放接口、开放源码、开放数据库结构设计。

八)技术优点:

基于 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发

采用MVC的框架模式,具有耦合性低、重用性高、生命周期成本低、可维护性高、有利软件工程化管理等优点

采用WebAPI,客户端完全摆脱了代理和管道来直接进行交互

采用EasyUI前台UI界面插件,可轻松的打造出功能丰富并且美观的UI界面

采用Knockout,提供了一个数据模型与用户UI界面进行关联的高层次方式(采用行为驱动开发)

九)封装了大部分比较实用的控件和组件:

如自动完成控件、拼音模糊输入控件、日期控件、导出组件、下拉组件(单多选)、弹出窗口组件(单多选)、用户选择组件(单多选)、组织机构选择、角色选择等

下面就展示一下已经完成的页面效果:

登录页面:

主页:

菜单管理页面:

组织机构:

权限:

日志页面:

异常页面:

控件展示:

作者:王春天 2014-12-02

作者Blog:http://www.cnblogs.com/spring_wang

原文:http://www.cnblogs.com/spring_wang/p/4138492.html

如果觉得还不错,欢迎转载。

 

本系列文章列表如下:

基于MVC4.0+WebAPI+EasyUI+Knockout的Web开发框架的系列文章:

SNF快速开发平台3.0之–完美的代码生成器SNF.CodeGenerator-快速开发者的利器

基于MVC4+EasyUI的Web开发框架–Spring.Net.FrameworkV3.0总体介绍

SNF快速开发平台3.0之MVC通用控件库展示-Asp.net+MVC4.0+WebAPI+EasyUI+Knockout

SNF快速开发平台3.0之BS页面展示和九大优点-部分页面显示效果-Asp.net+MVC4.0+WebAPI+EasyUI +Knockout

SNF快速开发平台3.0之-界面个性化配置+10种皮肤+7种菜单-Asp.net+MVC4.0+WebAPI+EasyUI+Knockout

SNF快速开发平台3.0之-CS页面-Asp.net+Spring.Net.Framework

SNF快速开发平台3.0之–系统里广播的作用–迅速及时、简明扼要的把信息发送给接收者

SNF快速开发平台3.0之–asp.net mvc4 强大的导出和不需要上传文件的批量导入EXCEL

SNF快速开发平台3.0之–文件批量上传-统一附件管理器-在线预览文件(有互联网和没有两种)

SNF快速开发平台3.0之– MVC 打印解决方案

作者: 王春天
出处: http://www.cnblogs.com/spring_wang/
Email: spring_best@yeah.net
QQ交流:903639067 
QQ群:322581894
关于作者:高级工程师。专注于微软平台项目架构、管理和企业解决方案,多年项目开发与管理经验,精通DotNet,DB(SqlServer、Oracle等)技术。熟悉Java、VB及PB开发语言。在面向对象、面向服务以及数据库领域有一定的造诣。现从事项目实施、开发、架构等工作。并从事用友软件产品U8、U9、PLM 客开工作。
如有问题或建议,请多多赐教!
本文版权归作者和CNBLOGS博客共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过邮箱或QQ 联系我,非常感谢。

 

Asp.Net MVC 自定义的MVC框架(非EF操作数据库) - 二进制小男人 - 博客园

mikel阅读(920)

来源: Asp.Net MVC 自定义的MVC框架(非EF操作数据库) – 二进制小男人 – 博客园

  一些废话:在 北京辞职回家不知不觉中已经半年多了,这半年中有过很多的彷徨,困惑,还有些小小难受。半年时间算是我人生以来遇到过的最困苦的时候。理想的工作跟我擦肩 而过,驾照也没有考过,年后这一改革…,毕竟遇到多大的阻力就有多大的成长,感觉这半年自己也成长了不少,不是刚出校门桀骜不驯的牛犊,也不是在北京 每个月拿4000多块,然后月光的毕业生。自始至终,我对于技术的追求也并没有松懈过,最近一段时间也根据自己小小的想法,与以前公司的一个框架原理,通 过ASP.NET MVC为基础半实现(为什么是半实现?因为还没写完!汗!。为什么没用“开发”一词,感觉自己技术还没到。)了一个小小的框架,希望我这以小小的瓦片能引 出您的珍珠碗。

我所希望的:这框架其实想法有想法到现在基础的实现,已经有三个月了,由于断断续续的coding,到现在才写成博客。写成博客的目的,不是在此炫耀,也不是在此哗众取宠,而是真心的希望各位大牛,给小菜批评佐证,可以说是欢迎来拍砖,但是把您宝贵的意见留下,小菜在此跪谢!以下言归正传。

    一.框架的目的与原理:

目的:根据ASP.NET MVC框架原理为基础,实现基于配置的MVC应用框架,最终以框架为基础,快速高效的应用与BS的开发。一个新的业务不需要构建C#的代码,不写

Controller与Action,只需要配置View与Mod.Config.而View的显示只可以根据已定义的分布视图,或是完全自定的View界面实现。实现高效的开发。

原理:众所周知ASP.NET MVC 框架根据用户的URL找到Controller并通过Action调用加载数据,并返回View。该框架的原理,是通过一个带参数的固定的Controller

动态解析,传入的URL,并根据URL参数,动态的创建出数据库操作实例,根据Mod.config文件,动态的加载每个Action的数据实例,返回以数据实例显示View,而View中的数

据显示啊,操作等通过分部页功能实现。

二.框架的架构

具体的操作请求实例:

下面通过一个请求,具体的解析一下怎样定位一个请求操作。

程序的主界面是自定义编译过的Ext只保留布局功能(Ext-all.js,Ext-base.js,+css总共大小280K左右,比原版的800K压缩了不少),以下是图:

以角色管理为例子:传入的URL 为解析后为

可以看到URL中并没有RBAC 的 Controller 也没有 Roles的 Action,所有Controller与Action都是通过BaseController与Load Action来加载,根据url参数创建出操作数据库实体类,并通过Url参数找到对应的View下面的文件目录,将每个Action与View使用的数 据存入Mod.config文件中,每次访问一个Action时都回去Mod.config取出数据的实例,Mod.config是自定义的 ConfigSection,就以“角色管理为例子”它配置了一个GridView分页需要使用的数据,Code:

Mod.Config

根据Mod.config的配置信息,生成数据模型,利用反射与缓存,加载数据信息,Code:

复制代码
   ViewElement viewModels = GetCachedViewElement(filePath, actionName);
            if (viewModels != null)
            {
                foreach (ModelElement model in viewModels.Models)
                {
                    object virtualModel = new object();
                    virtualModel = Assembly.Load(modelAssembly).CreateInstance(modelAssembly + "." + model.Type);
                    foreach (AttributeElement attribute in model.Attributes)
                    {
                        AttributeReflecter.SetPropertyValue(virtualModel, attribute.Name, attribute.Value);
                    }
                    Database a = DatabaseFactory.CreateDatabase("Sys");
                    (virtualModel as IExecute).Execute(a);
                    ViewData[model.Name] = virtualModel;
                }
            }
复制代码

返回视图:

所使用的分部页:

复制代码
@using Binary.MVC.Library.Extends
@model Binary.MVC.Library.Model.GridModel
           
<table id="GridView">
    <thead>
        <tr>
            @foreach (Binary.MVC.Library.Model.HeaderModel header in Model.HeaderMC)
            {
                <th width="@header.W">@header.N@if(header.I){<img align="absmiddle" src="@Url.Content("http://www.cnblogs.com/Content/Images/rarrow.gif")" title="单击此处以排序" />}</th>
            }
        </tr>
    </thead>
    <tbody>
        @foreach (Binary.MVC.Library.Model.GridRow row in Model.Rows)
        {
            <tr>
                @foreach (Binary.MVC.Library.Model.FieldModel field in Model.FieldMC)
                {
                    if (field.I)
                    {
                    <td>@row[field.N]</td>
                    }
                    else
                    {
                     <td>@Html.RenderGridAction(row.PKey,field.N)</td>   
                    }
                }
            </tr>
        }
        @if (Model.ShowEmpty)
        {
            for (int i = 0; i < Model.PageSize - Model.PageCount; i++)
             {
                <tr>
                @foreach(Binary.MVC.Library.Model.FieldModel field in Model.FieldMC)
                {
                    <td>&nbsp</td>
                }
                </tr>
             }
        }
    </tbody>
    <tfoot>
    <tr><td colspan="@Model.FieldMC.Count">
    <table id="GridView-footer"><tr>
      <td align="left">
        <a title="第一页"><img src="http://www.cnblogs.com/http://www.cnblogs.com/Content/Images/pg-first.gif"/></a>
        <a title="前一页"><img src="http://www.cnblogs.com/http://www.cnblogs.com/Content/Images/pg-prev.gif"/></a>
        <a title="后一页"><img src="http://www.cnblogs.com/http://www.cnblogs.com/Content/Images/pg-next.gif"/></a>
        <a title="最后页"><img src="http://www.cnblogs.com/http://www.cnblogs.com/Content/Images/pg-last.gif"/></a>
        <a title="最后页"><img src="http://www.cnblogs.com/http://www.cnblogs.com/Content/Images/excel.png"/></a>
      </td>
    </tr></table></td></tr>
    </tfoot>
</table>
复制代码

这样一个类似于 GridView的分部页就实现了。以此来加载每个Action 所需的 Model。

最后的啰嗦:

这篇文章写的很笼统,旨在阐述清楚框架的基本原理。其实里面有很多巧妙的实现。由于我跟人有点强迫症,所以对代码的质量要求比较高,这个给我自己带来了很大的工作量。现在有几个问题,希望大家一起 讨论一下,更希望得到大牛的帮助:

1. 由于我的设计中Controller与Action是通过固定的LoadAction来解析的,请问有没有什么办法直接根据一个URL来用一个方法来解析,而并非是根据具体的Controller

中的Action才可以解析得到,ASP.NET MVC 中是要根据URL找到Controller中Action才会返回视图,现在是根据URL做统一的处理,所以每次不必要创建Controller与

Action。请问大牛们还有更好的实现方式不?

2. 由于使用了IO操作与反射,第一加载的时候性能会有所下降,请问还有更好的办法没有?

 

 

 

博客不易,转载请注明出处。Binarysoft.

Asp.net MVC 插件式应用框架 - Mobwiz - 博客园

mikel阅读(1127)

来源: Asp.net MVC 插件式应用框架 – Mobwiz – 博客园

这几年来做了很多个网站系统,一直坚持使用ASP.NET mvc建站,每次都从头开始做Layout,CSS,做权限管理等等,有点恼火,将这几年的代码好好整理了一下,准备搭建一个框架。

一、目标

0)面向领域:网站后台管理系统、MIS等结构相对规范的管理类应用;

a)基于ASP.NET MVC 4搭建系统框架

b)集成RBAC基于角色的权限管理机制,能够控制到控件级别

c)集成一些基础服务:数据字典、日志记录等

d)使用AJAX特性(使用JQuery与MVC的Partiview等实现)

e)插件机制:框架搭建完毕之后,新开发的功能模块能够直接以插件的形式安装到系统框架中运行

f)使用EF Codefirst

二、系统设计

A)基于RBAC的权限管理系统

参考了园子里一些权限管理系统,使用了  模块->资源->操作 作为最基础的权限元素,[资源,操作]作为 基本的权限原子,将权限原子赋给“角色”

为了配合RBAC的使用,继承 AuthorizeAttribute 来修饰Action

B)菜单框架

此应用框架主要面向管理系统,所以导航菜单设计为两级,顶部导航为一级菜单,左侧 边为二级菜单,菜单能与权限进行关联,配置权限时可影响到菜单;如图所示,Menu2根据所选择Menu1发生变化;

C)Ajax框架

此应用框架中,Content Area为Ajax更新内容,使用JQuery的 $.get 操作访问 Action,在Action中返回 PartialView,然后更新到 ContentArea中;

全部使用Ajax来载入,带来一个问题,无法使用前进、后退、还有刷新等操作,借鉴网上一些资料,使用了 “JQuery.bbq.js”的插件,通过url的hashchange使系统能够在浏览器中保持状态,能够使用 “前进“,”后退“,”刷新“等操作;通过将真实的请求代码加入到URL”#”后,来载入所需要的内容,JS代码如下:

复制代码
$(window).bind('hashchange', function (e) {
            var hash = window.location.hash || '';
            if (oldHash == '') {
                // 需要选择默认菜单
            }
            if (hash != '' && hash != oldHash) {
                if (hash == "#top") {
                    //TODO, Load the index page!!!!
                    return;
                }

                $('#contentPanel').html('<div class="wp"><img src="@Url.Content("~/Content/loading.gif")" border="0" /> &nbsp;载入中...</div>');
                oldHash = hash;

                $.get(hash.substr(1, hash.length - 1), {}, function (data, status) {
                    if (status == "success") {
                        if (data.substr(0, 7) == '"logon"') {
                            window.location = "/Home/Login";
                        } else {
                            $('#contentPanel').html(data);
                        }
                        //}
                    } else {
                        $('#contentPanel').html('error.. - ' + status);
                    }
                }, "html");
            }
        });
        $(window).trigger('hashchange');
复制代码

 

在这样的框架中,只需要关注Content Area中的部分视图即可,在该Content Area中还可以使用Ajax + JSON的方式实现更多的功能;

表单的处理

由于采用了上面的AJAX机制,不能再使用以往的表单提交方式,在本框架中,使用下面几种方式:

1)使用  $.post(url, $(‘#form’).serialize(), callback, “html”) 的方式,将返回值更新到 Content Area中;

2)使用  $.post(url, {‘field1′,’value1’} , callback, “json”) 的方式,根据结果,再通过JavaScript进行页面跳转;

D)配套的若干Helper

ajaxMenu,ajaxPager等:由于使用了上面的机制来载入部分视图,所有的URL都要以 /Home#/Real/Url?para1=value1 的方式来请求,所以写了一个Helper来完成该功能;分页也需要做同样的处理。

E)IoC Container

本例使用了Unity Block作为IoC容器,无他,因为这个比较熟悉;同时将MVC与Unity Container做了整合;

F)表单验证

由于使用了AJAX框架,unobtrusive扩展的验证大部分失效,所以直接使用 jQuery.validate进行客户端验证

G)插件机制

定义IPlugin接口,其中有Initialize方法,在系统启动时进行初始化,例如初始化Unity Container,MapRoute等等;

插件的使用:直接将插件复制到框架中的插件目录,并将插件所需要使用的Views文件复制到框架中的Views目录中。(暂无更好的解决方案,就这样搞定。考虑复制到插件目录,重写MVC中的视图引擎的代码来实现在插件目录中查找视图)

工作原理:系统启动时,通过反射载入插件中的Dll,并查找IPlugin接口,调用其初始化方法,插件在Unity容器中注册所需要使用的控制器,这样框架中就可以调用到所需要的控制器以及视图;

插件格式:插件也采用ASP.NET MVC 4 Web APP来写,最后只使用编译出的DLL与部分必要的View视图,其他资源均使用框架中的资源;

三、系统实现

1)数据库:采用了EntityFramework(Version 5.0) – CodeFirst完成,使用Enable Migrations;

2)数据访问层:定义仓储模式,IRepository实现基本的增删查改功能,

3)数据服务层:根据需要进行定义;

4)Portal:采用了ASP.NET MVC 4,Razor视图引擎,jQueryjQuery UI, JQuery.Validate, jquery.bbq, Jquery BlockUI 等;

5)为面向内容管理,集成了CkEditor与CkFinder

——————-

目前系统代码还比较乱,先发个截图