zoukankan      html  css  js  c++  java
  • 我喜欢ASP.NET的MVC因为它牛逼的9大理由(转载)

     

    我很早就关注ASP.NET的mvc的,因为最开始是学了Java的MVC,由于工作的原因一直在做.Net开发,最近的几个新项目我采用了MVC做了,我个一直都非常喜欢.Net的MVC。我们为什么使用MVC而不是用WebForm呢?下面就来说说MVC的亮点。由于我最近使用都是MVC5.0和EF6.1,所以下面的所有实例都是基于这两个版本的。

    1、创建项目内置了Bootsrap

    Bootsrap是一个响应式的UI界面库,能快速的搭建响应式界面,如果没有美工,对界面要求不是很高的话完全可以直接作用,很方便。

    Bootsrap的推荐网站

    http://getbootstrap.com/

    http://www.bootcss.com/

    2、url路由控制灵活,对seo友好

    1. public class RouteConfig
    2. {
    3. public static void RegisterRoutes(RouteCollection routes)
    4. {
    5. routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    6. routes.MapRoute(
    7. name: "Default",
    8. url: "{controller}/{action}/{id}",
    9. defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    10. );
    11. }
    12. }

    这个是RouteConfig注册默认路由。这个类的静态方法RegisterRoutes是在网站启动的时候调用的。

    MVC不像webform那样,一个动态url地址是对应到一个本地的一个aspx文件,而mvc是对应一个Controller(控制器)的里面的一个Action(public方法)。mvc是对应的”/Home/About“对应的就是HomeController的名字为About的Action。这种url地址到Controller的Action的对应关系你完全可以按照你的要求设置,甚至可以配置成.html结尾的伪静态

    我之前写的一篇文章可以看一下”自定义route路由机制

    3、视图引擎的灵活

    默认情况下创建mvc视图文件.cshtml会自动把这些同一个Controller的Action的视图放在一个文件夹。

    对应视图文件结构

    mvc视图自带的视图是razor引擎,可以强类型绑定视图,安全,性能方面都有保证。

    要指定视图对应的model类型很简单

    在Contoller里面用return View(xx)

    xx为对应的一个model对象。

    视图使用:

    @model xxx.Models.xx

    这样视图就可以用@Model.字段绑定了。

    视图可以像可以定义一个共用的部分Layout(就像Webform的master母版页),头部、页脚、菜单导航等这些共用的html都可以放在Layout里面,对于局部多个地方相同的html,可以用@Html.Action("actionName","controllerName")方法来绑定一个局部视图(就像Webform的用户控件) 

    1. public class NavController : Controller
    2. {
    3. [OutputCache(Duration=7200)]
    4. [ChildActionOnly]
    5. public PartialViewResult SpecialListMenu()
    6. {
    7. return PartialView();
    8. }
    9. [OutputCache(Duration = 7200)]
    10. [ChildActionOnly]
    11. public PartialViewResult NewsListMenu()
    12. {
    13. return PartialView();
    14. }
    15. }

    Action对应的局部视图也可以定义输出缓存OutputCache单位是分钟,这样下次请求直接在缓存中取出来,提高了程序的效率。 一般对变化不频繁的Action我都这样会加上缓存。加上[ChildActionOnly]表示只能通过视图来引用,不能直接在浏览器访问。

    3.1、自定义视图引擎

    分享一下AtomicCms里面的自定义视图引擎的代码。

    1. using System.Collections.Generic;
    2. using System.Web.Mvc;
    3. namespace AtomicCms.Web.Core.Mvc
    4. {
    5. public class CustomRazorViewEngine : RazorViewEngine
    6. {
    7. public CustomRazorViewEngine()
    8. {
    9. string[] mastersLocation = new[]
    10. {
    11. string.Format("~/skins/{0}/views/{0}.cshtml",
    12. Utils.SkinName)
    13. };
    14. MasterLocationFormats = CustomViewEngineHelper.AddNewLocationFormats(
    15. new List<string>(MasterLocationFormats),
    16. mastersLocation);
    17. string[] viewsLocation = new[]
    18. {
    19. string.Format("~/skins/{0}/Views/{{1}}/{{0}}.cshtml",
    20. Utils.SkinName)
    21. };
    22. ViewLocationFormats =
    23. PartialViewLocationFormats =
    24. CustomViewEngineHelper.AddNewLocationFormats(new List<string>(ViewLocationFormats),
    25. viewsLocation);
    26. }
    27. public override ViewEngineResult FindView(ControllerContext controllerContext,
    28. string viewName,
    29. string masterName,
    30. bool useCache)
    31. {
    32. masterName = CustomViewEngineHelper.OverrideMasterPage(masterName,
    33. controllerContext);
    34. return base.FindView(controllerContext,
    35. viewName,
    36. masterName,
    37. useCache);
    38. }
    39. }
    40. }

    这样可以实现mvc视图主题,网站可以制作不同风格的主题,每个主题分别绑定视图就可以了。

    要使自定义的视图引擎生效还需要在Global.asax加入下面的代码把默认视图引擎禁用。

    1. ViewEngines.Engines.Clear();
    2. ViewEngines.Engines.Add(new CustomRazorViewEngine());

    4、Model绑定

    Action的参数可以是一个个单独的参数,也可以是一个model对象,mvc可以从请求中获取到参数绑定相应的字段到model中去。这样实现了表单提交的时候,自动装配的功能,而不需要类似这样:Request.Form["xx"]获取值赋值给model。

    mvc默认的参数绑定是按照以下顺序的。

    Request.Form=》RouteData.Values=》Request.QueryString=》Request.Files

    假设Action的一个参数id,会从下面按顺序获致id的值,一旦找到就不会再往下面寻找。

    1. Request.Form["id"]

    2. RouteData.Values["id"]

    3. Request.QueryString["id"]

    4. Request.Files["id"]

    实践开发过程中的一个添加功能,绑定一个model对象,视图代码:

    1. @model MvcModels.Models.Person
    2. @{
    3. ViewBag.Title = "CreatePerson";
    4. }
    5. <h2>Create Person</h2>
    6. @using(Html.BeginForm()) {
    7. <div>@Html.LabelFor(m => m.PersonId)@Html.EditorFor(m=>m.PersonId)</div>
    8. <div>@Html.LabelFor(m => m.FirstName)@Html.EditorFor(m=>m.FirstName)</div>
    9. <div>@Html.LabelFor(m => m.LastName)@Html.EditorFor(m=>m.LastName)</div>
    10. <div>@Html.LabelFor(m => m.Role)@Html.EditorFor(m=>m.Role)</div>
    11. <button type="submit">Submit</button>
    12. }

    后台代码

    1. [HttpPost]
    2. public ActionResult CreatePerson(Person model) {
    3. return View("Index", model);
    4. }

    这样前台的表单的值会对应到model的相应的字段里面。当然也可以指定哪些字段要绑定

    1. public ActionResult AddSummary(
    2. [Bind(Include = "HomeAddress", Exclude = "Country")]AddressSummary summary)
    3. {
    4. //do something
    5. return View(summary);
    6. }

    MVC的校验非常的好,自带非空检验,类型检验,也可以写复杂的正则表达式
    [Requred]
    Public string Name{get;set;}
    以上表示Name字段必填。

    4.1自定义Binder绑定

    使用IModelBinder接口自定义一个购物车的Binder类

    1. public class CartModelBinder : IModelBinder
    2. {
    3. private const string sessionKey = "Cart";
    4. public object BindModel(ControllerContext controllerContext,
    5. ModelBindingContext bindingContext)
    6. {
    7. //从Session读取购物车对象
    8. Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
    9. if (cart == null)
    10. {
    11. cart = new Cart();
    12. controllerContext.HttpContext.Session[sessionKey] = cart;
    13. }
    14. return cart;
    15. }
    16. }

    在Global.asax里面的Application_Start方法加入代码为Model绑定集合加入上面自定义的CartModelBinder类。

    ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());

    这样以后的Action的Cart对象如:

    1. public ViewResult Summary(Cart cart)
    2. {
    3. return View(cart);
    4. }

    就会自动绑定,也就是从Session里面取key为Cart的对象。

    5、控制器灵活

    mvc的Controller拓展也很灵活

    上面就是MVC框架程序的执行流程,上面图中的ControllerFactory,Controller,Action Invoker都可以完全自定义拓展。

    我们创建的Controller是其实默认继承System.Web.Mvc.Controller的,这是一个抽象类,其实它为我们提供了很多基础实现

    它的很多方法都定义为虚方法,所以如果我们要实现自己个性化的东西也可以重写里面的方法。

    5.1、自定义一个ControllerFactory

    1. using System;
    2. using System.Web.Mvc;
    3. using System.Web.Routing;
    4. using System.Web.SessionState;
    5. using ControllerExtensibility.Controllers;
    6. namespace ControllerExtensibility.Infrastructure {
    7. public class CustomControllerFactory: IControllerFactory {
    8. public IController CreateController(RequestContext requestContext,
    9. string controllerName) {
    10. Type targetType = null;
    11. switch (controllerName) {
    12. case "Product":
    13. targetType = typeof(ProductController);
    14. break;
    15. case "Customer":
    16. targetType = typeof(CustomerController);
    17. break;
    18. default:
    19. requestContext.RouteData.Values["controller"] = "Product";
    20. targetType = typeof(ProductController);
    21. break;
    22. }
    23. return targetType == null ? null :
    24. (IController)DependencyResolver.Current.GetService(targetType);
    25. }
    26. public SessionStateBehavior GetControllerSessionBehavior(RequestContext
    27. requestContext, string controllerName) {
    28. return SessionStateBehavior.Default;
    29. }
    30. public void ReleaseController(IController controller) {
    31. IDisposable disposable = controller as IDisposable;
    32. if (disposable != null) {
    33. disposable.Dispose();
    34. }
    35. }
    36. }
    37. }

    CustomControllerFactory职责是根据请于的获取到路由信息来创建相应的Controller对象

    要使自定义的CustomControllerFactory生效还需要在在Application_Start()方法中加入注册代码

    1. ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());

    6、AOP面向方面编程

    Java的Spring框架的AOP(面向方面编程)很强大,AOP的优点是大大的降低了软件模块的耦合性,提高了代码的复用和维护性。

    ASP.NET MVC有各种Filter过滤器,就相当于AOP的技术。可以把应用于身份验证,日志记录,异常处理,这样核心业务只关心自己的逻辑代码就是了,最后的代码不会参杂有业务代码身份验证、日志相关的代码。

    我这之前写了一篇介绍mvc的aop文章,AOP实践--利用MVC5 Filter实现登录状态判断

    7、IOC控制反转

    .Net方面的IOC框架是也是不少的主流的有Autofac、Castle Windsor、Unity、Spring.NET、StructureMap、Ninject等。MVC使用这些框架也很好集成。有的都不用自己写IOC框架与MVC集成代码了。像Autofac有MVC5和MVC2、3、4都有现有集成代码,如下图。

    直接安装就可以在自己的MVC项目中用了,如果你用的IOC框架没有在nuget中找到MVC集成包,自己写有也很容易。

    具体请看我这前的文章IOC实践--用Autofac实现MVC5.0的IOC控制反转方法

    8、单元测试容易

    你可以不通过Web服务器IIS之类的来测试Action和Controller,利用moq框架很容易的就mock模拟出真实的Web请求。

    mvc的Controller和Action方法都可以很方便的进行单元测试。

    你如果要测试一个Action方法的返回值,你都可以不用解析任何的HTML的。 只需要监视Action的返回值ActionResult类型的对象。

    不用模拟用户请求,MVC框架的model绑定对象,做为Action方法的参数,然后返回相应的结果 。最简单的测试就是你传入具体的参数直接调

    Action方法,就可以了。比如要测试一个Action是真能返回一个指定的View

    1. public ViewResult Index() {
    2. return View("Homepage");
    3. }

    测试代码:

    1. using System;
    2. using Microsoft.VisualStudio.TestTools.UnitTesting;
    3. using ControllersAndActions.Controllers;
    4. using System.Web.Mvc;
    5. namespace ControllersAndActions.Tests {
    6. [TestClass]
    7. public class ActionTests {
    8. [TestMethod]
    9. public void ViewSelectionTest() {
    10. // 创建要测试的 Controller
    11. ExampleController target = new ExampleController();
    12. // 调用Action
    13. ViewResult result = target.Index();
    14. // 判断测试结果
    15. Assert.AreEqual("Homepage", result.ViewName);
    16. }
    17. }
    18. }

    9、开源

    MVC是开源的框架,而NuGet是一个VS很有用的一个包管理工具,上面有很多有用的类库,搜mvc出现下面的结果。

    可以看到很多有用的类库,分页(PagedList.Mvc),Grid.Mvc。

    9、entityframework完美配合

     MVC5项目添加Controller可以选择”包含视图的MVC5控制器(使用Entity Framework)“,这样一个Model的增、删、改、查这些相关的View和Action自动给你生成好了,只需要根据自己需要改一下基本上就能用了。这样大大的提高的开发速度,对于开发管理后台这个太好用了。

    10、总结

    总结:我之前一直都觉得.net是入门比较容易,因为很多东西微软都给你封装好了,要成为高手比较难,不像java的好多开源的框架,从中可以学到好多的软件架构和设计模式这类的东西,例如,面向接口编程,AOP,IOC这类的。但是伴随着.Net的相关东西开源,比如MVC、EF、甚至现在.NET Framework也开源了,研究的越来越多,这些.net现在也可以,我上面写就可以看到MVC的每个部分都很灵活,完全可以根据自己的需要重写,订制。建议想成为高手或架构师,完全有必要仔细研究MVC的源码和原来,因为从里面可以学到很多设计模式、软件架构、软件设计相关的技巧,对于提升我们的技术能力很有帮助。

     
    .net网站&系统开发技术学习交流群:533829726
    本站文章除注明转载外,均为本站原创或翻译,欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,共创和谐网络环境。
    转载请注明:文章转载自:蓝狐软件工作室 » 我喜欢ASP.NET的MVC因为它牛逼的9大理由
    本文标题:我喜欢ASP.NET的MVC因为它牛逼的9大理由
    本文地址:http://www.lanhusoft.com/Article/77.html
  • 相关阅读:
    iOS AutoLayout的用法
    UIPickerView的使用(一)
    UIPickerView的使用(二)
    logging模块
    configparser模块
    hashlib模块
    json & pickle 模块
    对表的操作
    表记录曾删改查
    库、表曾删改查和存储引擎
  • 原文地址:https://www.cnblogs.com/tangjiansheng/p/5703149.html
Copyright © 2011-2022 走看看