• 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:

    复制代码
     1 <ModelConfiguration>
     2     <views>
     3       <view name="Roles" title="首页">
     4         <models>
     5           <model type="GridModel" name="AjaxGrid1" >
     6             <attributes>
     7               <add name="Table" value="RBAC_Roles" />
     8               <add name="JsonHeader" value="[{'N':'序号','W':'30','I':'false'},{'N':'操作','W':'80','I':'false'},{'N':'主键','W':'280'},{'N':'角色名'},{'N':'可用','W':'80'}]" />
     9               <add name="JsonField" value="[{'N':'RowNumber'},{'I':'false','N':'@Edit=编辑'},{'N':'PKey'},{'N':'RoleName'},{'N':'Enable'}]" />
    10               <add name="Where" value=" 1=1 " />
    11               <add name="Order" value="PKey" />
    12               <add name="PageSize" value="10" />
    13               <add name="Key" value="PKey" />
    14             </attributes>
    15           </model>
    16         </models>
    17       </view>
    18     </views>
    19   </ModelConfiguration>
    复制代码

    根据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.
     
  • 相关阅读:
    大规模扩展casbin的一种方案
    casbin 性能优化的几点建议
    使用casbin进行应用访问控制
    使用xid 生成 唯一id
    jcsabin FilteredAdapter 逻辑处理问题
    jcasbin redis watcher 一些修改
    cube.js 0.27.31 一些新特性
    sdkman Stop! maven is not a valid candidate 类似问题解决
    lakefs 类似git 的文件对象存储
    readme.so docker 镜像
  • 原文地址:https://www.cnblogs.com/webenh/p/6046757.html
Copyright © 2020-2023  润新知