学习mvc半月有余,趁几天假期,没事做就动手做一个完整的网站玩玩,顺便和上家公司的方法做个比较。页面引擎采用mvc自带的功能,建立视图,交给.net自带渲染出页面(对比:上家公司采用的第三方组件渲染的);前台和后台通过ajax方式交互(对比:基于ashx+配置文件,采用反射来实现,比较繁琐);orm采用自带的EF6(对比:采用Dbcommand封装,datatable和model之间采用反射实现自动绑定,不支持add一个对象,比较低端),吸取上家大牛的方法,可自定义数据库配置,比如定义sql以及使用什么数据库,只是使用起来比较蹩脚,大牛勿喷;页面模板之前使用template.js,现在尝试了razor语法。功能:权限部分基本实现完整,后续有时间继续完善了。通过此次实践:积累一些心得是,很多看似简单的东西,如果动手起来,还是有不少细节去注意,这期间可能就是一种体验,一种经验的积累,各种滋味只有自己尝试了才会有所获。
环境:vs2015+ sql server 2008+ EF6+ easyui.备注是支持MySQL的,采用EF,稍微封装了一下。
权限控制,MVC下真的很方便,可控制页面菜单,可控制操作级别的,点赞。下面是抄袭网上的。
public class AuthorizeManageAttribute : AuthorizeAttribute { private int _a, _b; private bool yes; public AuthorizeManageAttribute(int a, int b) { _a = a; _b = b; } //首先被执行的方法 protected override bool AuthorizeCore(HttpContextBase httpContext) { yes = _a > _b; return yes; } //尽在authorizecore方法返回false时执行 protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); if (filterContext == null) { throw new ArgumentNullException("filterContext"); } else { filterContext.HttpContext.Response.Redirect("/HtmlPage1.html"); } } }
EF,一个蹩脚的封装:
namespace FrameWrok.Common { internal class DataCommandContext<TContext> where TContext :DbContext,new() { public void Dispose() { } public static TContext GetContext() { return new TContext(); } } } public class DataCommand<TContext> where TContext : DbContext, new() { private readonly string _cmdKey; private readonly string _server; private IDictionary<string, SqlCmdModel> _dictCmd = new Dictionary<string, SqlCmdModel>(); /// <summary> /// xml中,sqlcmd 的name属性 /// </summary> public string CmdKey { get { return _cmdKey; } } /// <summary> /// 数据库类型:支持sql server /// </summary> public string Server { get { return _server; } } /// <summary> /// 当前sql语句 /// </summary> public string CurCmdLine => _dictCmd.Keys.Any() == false ? string.Empty : _dictCmd[_cmdKey].CmdLine; public DataCommand() { } public DataCommand(string server, string sqlCmdName) { _server = server; _cmdKey = sqlCmdName; ReadCmmdConfig(); } /// <summary> /// sql语句参数,采用简单的字符串替换,因此在sql字符串中不能用重复的关键字出现(对比:采用setparameter更加严谨) /// </summary> /// <param name="param"></param> /// <param name="val"></param> public void SetParameters(string param, string val) { if(_dictCmd.Keys.Any()==false) throw new SqlNotFilledException(); var targetCmd = _dictCmd[_cmdKey].CmdLine; _dictCmd[_cmdKey].CmdLine = targetCmd.Replace(param, val); } /// <summary> /// 自定义sql /// </summary> /// <typeparam name="T">根据输出的sql字段定义类</typeparam> /// <returns>可以返回null</returns> public List<T> ExecuteSql<T>() { if (string.IsNullOrEmpty(CurCmdLine)) return null; using (var db = DataCommandContext<TContext>.GetContext()) { var sql = CurCmdLine; var res = db.Database.SqlQuery<T>(sql).ToList(); return res; } } public void ExecuteNoReturn() { if (string.IsNullOrEmpty(CurCmdLine)) return ; using (var db = DataCommandContext<TContext>.GetContext()) { var sql = CurCmdLine; db.Database.ExecuteSqlCommand(sql); } } /// <summary> /// 添加基本表内容 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> public static bool Add<T>(T obj) where T:class { using (var db = DataCommandContext<TContext>.GetContext()) { db.Entry(obj).State=EntityState.Added; db.SaveChanges(); return true; } } public static DbContext GetCurContext() { return DataCommandContext<TContext>.GetContext(); } private void ReadCmmdConfig() { var dir=new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory+"config"); if(dir==null) throw new InvalidOperationException(); var fileList=dir.GetFiles("*.xml"); foreach (var fileInfo in fileList) { ParseXml(fileInfo.FullName); if (_dictCmd.Keys.Count > 0) return; } } private void ParseXml(string path) { SqlRoot root; using (var stream = new StreamReader(path)) { var xmlSeri = new XmlSerializer(typeof(SqlRoot)); root = (SqlRoot)xmlSeri.Deserialize(stream); } if (!root.SqlCmdList.Any()) throw new SqlNullValueException(); var serverFound =root.SqlCmdList.Where(x => x.Name.Equals(_server)).ToList(); if(!serverFound.Any()) throw new SqlNullValueException(); var cmdFound = serverFound[0].SqlCmd.Where(x => x.Name.Equals(_cmdKey)).ToList(); if(!cmdFound.Any()) throw new SqlNotFilledException(); _dictCmd.Add(_cmdKey,cmdFound[0]); } } [XmlRoot("SqlRoot")] public class SqlRoot { [XmlElement("SqlList")] public List<SqlList> SqlCmdList; } [XmlRoot("SqlList")] public class SqlList { [XmlAttribute("name")] public string Name { get; set; } [XmlElement("SqlCmd")] public List<SqlCmdModel> SqlCmd { get; set; } } [XmlRoot("SqlCmd")] public class SqlCmdModel { [XmlElement("param")] public List<Params> Param { get; set; } [XmlElement("CmdLine")] public string CmdLine { get; set; } [XmlAttribute("name")] public string Name { get; set; } } [XmlRoot] public class Params { [XmlAttribute("name")] public string Name { get; set;} [XmlAttribute("type")] public string Type { get; set; } }
当你想自定义sql,不想使用linq to sql时,可以在配置文件中定义结构,将获取的sql传递EF执行,xml结构:
<?xml version="1.0" encoding="utf-8" ?> <SqlRoot> <SqlList name="sqlServer"> <SqlCmd name="DeleteRolesById"> <CmdLine> <![CDATA[ delete from tb_usergroup where id in(@roles) ]]> </CmdLine> <param name="@roles" type="string"/> </SqlCmd> <SqlCmd name="DeleteUserById"> <CmdLine> <![CDATA[ delete from tb_user where id in(@roles) ]]> </CmdLine> <param name="@roles" type="string"/> </SqlCmd> <SqlCmd name="GetBlogAll"> <CmdLine> <![CDATA[ select * from blogs --where blogid=@BlogId ]]> </CmdLine> </SqlCmd> <SqlCmd name="GetBlogTitle"> <CmdLine> <![CDATA[ select p.PostId, p.Title,b.Name from Posts p left join Blogs b on p.BlogId=b.BlogId ]]> </CmdLine> </SqlCmd> </SqlList> <SqlList name="mySql"> </SqlList> <SqlList name="oracle"> </SqlList> </SqlRoot>
之前没做过mvc,使用公司封装的框架,但是通过一路做下来,查资料,很多原理或者基本是相通的,从页面渲染处理,前端和后端交互,后台权限控制方法、orm数据层,采用mvc似乎更加方便,mvc只是多了个路由功能,可怜那帮小伙伴还在被蹂躏中。