• MVC3快速搭建Web应用(一)


    最近随着项目接近尾声,感觉有必要把自己”拼凑”的这一套基于asp.net mvc 3的Web应用快速开发模式分享出来。顺便给此项目做个总结。

    关键词:Razor、easyui、Entityframework、T4 、Linq to Entity、Json

    1)Razor:ASP.NET MVC3引入了一个新的View引擎.

    2)easyui:基于jquery的一个ui界面框架

    3)Entityframework:微软的数据库关系映射框架

    4)T4:代码生成的模版语法 。MVC中添加控制器和添加视图对话框执行使用在幕后的 T4 模板的代码生成。

     先来几个效果图:

     此图中左边的菜单栏是通过数据库配置动态生成,并且与权限挂钩,权限粒度控制到按钮级别,即可指派某个角色是否拥有增加、删除某记录的权限

     图中列表的header全部都是通过自动生成完成,设备详细信息页面经由改造mvc3的details生成。

    此编辑界面也是由T4模版自动生成。甚至包括中文label(提取自Powerdesigner中的字段注释),包括下拉列表,日期选择框,都是根据判断数据库类型自动添加。

    一、使用PowerDesigner搭建数据模型

    在EntityFramework中,有两种开发模式,代码优先(Code First)与普通的先生成数据库然后再开发,本项目采用的是后一种。

    个人习惯直接搭建概念模型,需求初步敲定后,为物理模型添加细节,在这个期间,给每个字段添加注释是非常重要的,因为后期你需要根据这些中文注释来生成界面上的文字。本人使用了一个Powerdesigner中的自动修改脚本来将Name转换为Commet

    Option Explicit
    ValidationMode = True
    InteractiveMode = im_Batch
    
    Dim mdl 'the current model
    
    'get the current active model
    Set mdl = ActiveModel
    If (mdl Is Nothing) Then
    MsgBox "There is no current Model"
    ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then
    MsgBox "The current model is not an Physical Data model."
    Else
    ProcessFolder mdl
    End If
    
    'This routine copy name into code for each table, each column and each view
    'of the current folder
    Private sub ProcessFolder(folder)
    Dim Tab 'running table
    for each Tab in folder.tables
    if not Tab.isShortcut then
    if Tab.Comment ="" then
    Tab.Comment = tab.name
    else
    Tab.comment=Tab.name &"," &Tab.comment
    End if
    Dim col 'running column
    for each col in tab.columns
    if col.comment ="" then
    col.comment= col.name
    else
    col.comment=col.name & "," &col.comment
    end if
    next
    end if
    next
    
    Dim view 'running view
    for each view in folder.Views
    if not view.isShortcut then
    view.comment = view.name
    end if
    next
    
    'go into the sub-packages
    Dim f 'running folder
    For Each f In folder.Packages
    if not f.IsShortcut then
    ProcessFolder f
    end if
    Next
    end sub

    上图为本项目物理模型的缩略图。

    在业务比较复杂的情况下,设计数据库时,其中数据字段冗余与处理逻辑简化之间的权衡最为关键。最常见是业务域中对象的继承与组合关系。例如,某些种类的设备拥有特殊信息,而大部分设备的字段都是通用的,这个时候就该权衡是放在多个表还是一个表拥有多个冗余字段,在本案例中,采用一个父表“设备”(包含有所有设备通用的字段),多个种类子表(存储特殊字段)的设计,减少字段冗余,提高系统扩充性。当然这是针对这个项目的特殊性来设计的,设备的种类变化不会很大。

    另外设置一些公共表也是非常有必要的,在本案例中,有一个公共照片表,包含字段有

    这样的话可以给任何信息表添加照片,信息表中包含的数据表记录编号存的是某个表的主键id,表编号存的是对应的信息表。

    数据库设计完毕,利用PowerDesigner直接生成到数据库。本项目采用的是SQL Server 2008,因为EntityFramework目前只支持微软自家的东西。

     在生成数据库的过程中,如果你的SQL Server是2005以上,你必须解决:

    二、给项目添加Entity Framework 支持

    假定你的vs2010已经安装mvc3。

    解决方案中只有两个项目:Domain与WebUI,顾名思义,Domain中涉及的是域模型相关数据访问,在本项目中也就是Entityframework生成的实体数据模型,WebUI里存放控制器与视图.

    图中的edmx文件就是我们的实体数据模型。你可以在新建该文件后通过右键,添加或刷新数据库,以便更新当前的实体模型与数据库匹配。

    当你按下保存键时,微软牛逼的T4模版在后台悄悄地给你生成了一大堆实体类。你可以展开edmx文件查看到它们:

    大概是一个这样的结构:上下文与实体,其中上下文继承自ObjectContext,姑且可以把它当作三层架构中的数据访问层,实体类 即三层架构中的实体层。

    如果你想深入这个自动生成过程,例如想修改生成后的实体名字,你可以修改edmx的属性--自定义工具。但我觉得太蛋疼了,所以保持默认的生成方式:EntityModelCodeGenerator,结果我的所有实体类名称全部都是T_前缀(我数据库中的表全都以T_开头)。

    至此,你的数据工作准备完毕,注意,你不需要写一句SQL。并且,将来你对数据库的任何更改将随着你在edmx文件上潇洒的右击刷新自动同步到你的项目中,一切是辣么的舒服,自然

     三、修改T4模版

    这是最为关键的一步,貌似也是整个项目中相对于其他步骤来说稍微有技术含量的一步。因为你得了解T4模版语法,你得事先编写一个完整的增删改页面(页面内容包含Razor语法,easyui,ajax等技术)。

    但是当这一步完成后,你的项目就完成70%的工作了。对,没错!完成一大半了!

    首先来感觉一下T4语法,如果你VS是默认路径,辣么你可以在这个路径下找到我们语法非常坑爹的模版(因为至今没有太智能的编辑器能编辑它们,只能凭感觉手写了)

    C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 3\CodeTemplates

    其中AddController就是你在VS中右键添加控制器时执行的模版,AddView是添加视图时执行的模版。为什么要修改他们?因为我们想要加入jquery,加入easyui,加入Json,想要有更好的页面体验与异步处理。

    AddController文件夹下有两个:我们需要修改的是ControllerWithContext.tt,下面会提供下载.内容就不细述了。举两个例子就OK了,详细大家下载后再讨论:(cnblogs的编辑器没有T4的语法着色。只能勉强看了)

    public JsonResult List(int page,int rows)
            {
                
                var q = from e in db.<#= entitySetName #> orderby e.<#=primaryKey.Name#>
                        select new
                        {
    <#int i=0;
        foreach (ModelProperty property in GetModelProperties(Model.ModelType)) {#>
                            <#=property.Name #> = e.<#=property.Name #><#if(i!=GetModelProperties(Model.ModelType).Count-1){#>,
    <#}#>
                            <#   i++; }#>
                        };
                        
                var result = q.Skip((page - 1)*rows).Take(rows).ToList();
                Dictionary<string, object> json = new Dictionary<string, object>();
                json.Add("total", q.ToList().Count);
                json.Add("rows", result);
                
                return Json(json, JsonRequestBehavior.AllowGet);
            }

    上面这个方法是给控制器增加了一个返回jsonresult的列表方法。众所周知,数据库表操作无非就是增删改查,这个List就是用来支持列表的。参数page与rows是用来支持easyui的grid分页的。

    [HttpPost]
            public JsonResult Create(<#= modelName #> <#= modelVariable #>)
            {
                JsonResult json=new JsonResult();
                json.Data=true;
                try{
    <# if(isObjectContext) { #>
                    db.<#= entitySetName #>.AddObject(<#= modelVariable #>);
    <# } else { #>
                    db.<#= entitySetName #>.Add(<#= modelVariable #>);
    <# } #>
                    db.SaveChanges();
                }
                catch(Exception ee)
                {
                    json.Data=ee.Message;
                }
                
                return json;
            }

    Create是为了支持新建。成功返回json格式的true,失败返回失败原因。

    本项目中非常多的控制器httpPost方法是返回jsonresult 。目的有两个:

    一:为了支持easyui;

    二:本项目还有一个客户端是android平板,控制器当作它的一个远程数据源,给平板上的应用提供json格式数据。

     关于T4模版,你可以参考这里

    好,先写到这。马上回来。

    我的自定义模版下载

  • 相关阅读:
    quora 中有关angular与emberjs的精彩辩论
    迷你MVVM框架 avalonjs 0.94发布
    重写自己,减少判断 ---- 引发的思考
    JSON数据的优化
    记录全局错误
    Bat相关的项目应用
    C#中如何实现json转化时只处理部分属性
    JSON数据的处理中的特殊字符
    C# .net中json字符串和对象之间的转化方法
    VS调试 ---- 监视窗口、即时窗口、输出窗口
  • 原文地址:https://www.cnblogs.com/limlee/p/rapid_dev_use_mvc_1.html
Copyright © 2020-2023  润新知