如何让MVC和多层架构和谐并存(二)
上一节说了一些笼统的东西,这节说一些实际的操作。
1.取列表。这是一个新闻列表:
对应MVC的model是:
public class NewsListModel { /// <summary> /// 新闻列表 /// </summary> public List<Model.ToolNewsInfo> NewsList { get; set; }}</span></pre>
ToolNewsInfo是三层中的Model,这样,在Controller里面就可以直接使用BLL中的取列表方法:
[OutputCache(Duration = 600)] public ActionResult NewsList() { var bll = new ToolNews(); var newslist = bll.GetList("select * from ToolNews order by addtime desc "); Models.NewsListModel model = new NewsListModel(); model.NewsList = newslist;</span><span style="color: #0000ff">return</span><span style="color: #000000"> View(model); }</span></pre>
以上没考虑分页,但取列表本质上是一样的。
2.新增、修改数据。
一般MVC里的Model是这个样子:
public class NewsModel { public NewsModel() { } private Guid _id; private string _title; /// <summary> /// /// </summary> public Guid id { set { _id = value; } get { return _id; } } /// <summary> /// 标题 /// </summary> [Required(ErrorMessage = "请添写一个标题")] public string Title { set { _title = value; } get { return _title; } } }
有可能牵涉到数据验证,所以在Controller里面不能使用三层的Model。需要把MVC的Model对应字段值传递给多层的Model:
[HttpPost] [ValidateAntiForgeryToken] [ValidateInput(false)] public ActionResult EditNews(Models.NewsModel model) { if (ModelState.IsValid) { var bll = new ToolNews(); var entity = bll.GetModel(model.id); //多层Model entity.Title = model.Title; bll.Update(entity); //更新到数据库 } return RedirectToAction("News"); }
这样就可以实现数据的传递。
不过,表字段少的,可以一一赋值,如果一个表七八十个字段,还要挨个复制,岂不是太苦逼了?程序员最烦复制了。我们的天职是要简化简化再简化。
仔细观察一下这两种Model,发现有一个共性,就是对应数据表字段的属性,名称都是一样的。感谢万能的反射大神,这样我就可以很简单的把一个类相同的属性值复制给另一个类:
/// <summary> /// 把源类中具有 相同属性名的值 赋予目标类 /// </summary> /// <param name="source"></param> /// <param name="target"></param> public static void CloneSameProperties(object source, object target) { PropertyInfo[] sourceProperties = source.GetType().GetProperties(); foreach (PropertyInfo item in sourceProperties) { PropertyInfo targetProperty = target.GetType().GetProperty(item.Name); if (targetProperty != null) { targetProperty.SetValue(target, item.GetValue(source, null), null); } } }
这样Controller里的代码可以升级为:
[HttpPost] [ValidateAntiForgeryToken] [ValidateInput(false)] public ActionResult EditNews(Models.NewsModel model) { if (ModelState.IsValid) { var bll = new ToolNews(); ToolNewsInfo entity = new ToolNewsInfo(); //多层Model ObjectPlus.CloneSameProperties(model, entity); bll.Update(entity); //更新到数据库 } return RedirectToAction("News"); }
如此,数据操作就都可以走多层来实现。