我很早就关注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

我喜欢ASP.NET的MVC因为它牛逼的9大理由(转载)的更多相关文章

  1. ASP.NET Core MVC如何上传文件及处理大文件上传

    用文件模型绑定接口:IFormFile (小文件上传) 当你使用IFormFile接口来上传文件的时候,一定要注意,IFormFile会将一个Http请求中的所有文件都读取到服务器内存后,才会触发AS ...

  2. Pro ASP.NET Core MVC 6th 第三章

    第三章 MVC 模式,项目和约定 在深入了解ASP.NET Core MVC的细节之前,我想确保您熟悉MVC设计模式背后的思路以及将其转换为ASP.NET Core MVC项目的方式. 您可能已经了解 ...

  3. 定制Asp.NET 5 MVC内建身份验证机制 - 基于自建SQL Server用户/角色数据表的表单身份验证

    背景 在需要进行表单认证的Asp.NET 5 MVC项目被创建后,往往需要根据项目的实际需求做一系列的工作对MVC 5内建的身份验证机制(Asp.NET Identity)进行扩展和定制: Asp.N ...

  4. 【翻译】使用Visual Studio创建Asp.Net Core MVC (一)

    This tutorial will teach you the basics of building an ASP.NET Core MVC web app using Visual Studio ...

  5. 你想要的都在这里,ASP.NET Core MVC四种枚举绑定方式

    前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...

  6. 005.Getting started with ASP.NET Core MVC and Visual Studio -- 【VS开发asp.net core mvc 入门】

    Getting started with ASP.NET Core MVC and Visual Studio VS开发asp.net core mvc 入门 2017-3-7 2 分钟阅读时长 本文 ...

  7. ASP.NET Core MVC Tag Helpers 介绍

    简介 Tag Helpers 提供了在视图中更改和增强现有HTML元素的功能.将它们添加到视图中,会经过Razor模板引擎处理并创建一个HTML,之后再返回给浏览器.有一些Tag Helpers,其实 ...

  8. 跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)

    作者:陈希章 发表于 2017年6月25日 谈一谈.NET 的跨平台 终于要写到这一篇了.跨平台的支持可以说是 Office 365 平台在设计伊始就考虑的目标.我在前面的文章已经提到过了,Micro ...

  9. ASP.NET Core MVC 2.1 顶级参数验证

    本文讨论ASP.NET Core 2.1中与ASP.NET Core MVC / Web API控制器中的模型绑定相关的功能.虽说这是一个功能,但从我的角度来看,它更像是一个错误修复! 请注意,我使用 ...

随机推荐

  1. AngularJS 分页

    前端源码: <div> <h1>列表页33</h1> <table> <thead> <tr><td>CandiID ...

  2. ABAP 上传文件到内表

    http://www.cnblogs.com/jiangzhengjun/p/4265642.html http://www.xuebuyuan.com/1233478.html

  3. opendrive

    opendrive和其他许多网盘一样.注册拥有5G的免费空间.每天1G的免费外链流量.更重要的是,他能够给你提供一个直接外链!这是国内外许多网盘都没有的.当你上载了一个MP3,你想用直接外链的形式在博 ...

  4. js中选定元素slice()

    选定元素slice() slice() 方法可从已有的数组中返回选定的元素. 语法 arrayObject.slice(start,end) 参数说明: 1.返回一个新的数组,包含从 start 到 ...

  5. ASP.NET知识总结(7.状体保持)

    客户端的状态保持方案:ViewState.隐藏域.Cookies.控件状态.URL查询参数 服务端的状态保持方案:Session(会话).Application.Caching(缓存).DataBas ...

  6. 判断IP地址是否合法类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IPFl ...

  7. 在此为LCT开一个永久的坑

    其实我连splay都还不怎么会. 今天先抄了黄学长的bzoj2049,以后一定要把它理解了. 写LCT怎么能不%数据结构大神yeweining呢?%%%chrysanthemums  %%%切掉大森林 ...

  8. 冰球项目日志2-yjw

    我们小组在12.31号进行了讨论,确定了基本的任务及分工,后面是元旦放假,大家没有做很多的东西,我也是把自己分工的部分方案想了下. 后面在1.3号,我们会再进行一次小组讨论,确定下最终的方案,然后进行 ...

  9. Android入门(一):Android发展史

    Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.尚未有统一中文名称,中国大陆地区较多人使用“安卓” ...

  10. c#内部类的使用

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...