學習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只是多了個路由功能,可憐那幫小伙伴還在被蹂躪中。
