我喜欢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

时间: 2024-08-03 07:26:10

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

Pro ASP.NET Core MVC 6th 第三章

第三章 MVC 模式,项目和约定 在深入了解ASP.NET Core MVC的细节之前,我想确保您熟悉MVC设计模式背后的思路以及将其转换为ASP.NET Core MVC项目的方式. 您可能已经了解本章中讨论的一些想法和约定,特别是如果您已经完成了高级ASP.NET或C#开发. 如果没有,我鼓励你仔细阅读 - 深入地理解隐藏在MVC背后的东西可以帮助你在通读本书时更好地与MVC框架的功能联系起来. MVC的历史 模型视图控制器模式起源于20世纪70年代后期,来自施乐PARC的Smalltalk

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

背景 在需要进行表单认证的Asp.NET 5 MVC项目被创建后,往往需要根据项目的实际需求做一系列的工作对MVC 5内建的身份验证机制(Asp.NET Identity)进行扩展和定制: Asp.NET内建的身份验证机制会使用Local DB(本地数据库)读写用户相关的信息,而在数据库驱动的项目中,管理业务信息的数据库通常是特定的数据库环境,比如远程SQL Server数据库实例或Access数据库等等,业务数据库中保存着一系列针对业务需求的数据表,因此需要定制MVC 5内建身份验证,使其操作

Pro ASP.NET Core MVC 第6版 第二章(后半章)

增加动态输出 整个web应用平台的关注点在于构建并显示动态输出内容.在MVC里,控制器负责构建一些数据并将其传给视图.视图负责渲染成HTML. 从控制器向视图传递数据的一种方式是使用ViewBag 对象,它是一个控制器基类的成员.ViewBag是一个动态对象,你可以给他赋值任意属性给视图来渲染用.代码2-5 演示了如何在HomeController里传递简单对象. Listing 2-5. 设置视图数据 using System; using Microsoft.AspNetCore.Mvc;

Pro ASP.NET Core MVC 第6版 第二章(前半章)

目录 第二章 第一个MVC 应用程序 学习一个软件开发框架的最好方法是跳进他的内部并使用它.在本章,你将用ASP.NET Core MVC创建一个简单的数据登录应用.我将它一步一步地展示,以便你能看清楚怎样构建一个MVC 应用程序.为了让事情简单,我跳过了一些技术细节,但是不要担心,如果你是一个MVC的新手,你将会发现许多东西足够提起你的兴趣.因为我用的东西有些没做解释,所以我提供了一些参考以便你可以看到所有的细节的东西. 安装Visual Studio 要想根据本书实践的话,必须安装Visua

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 分钟阅读时长 本文内容 1.Install Visual Studio and .NET Core 安装 VS 与 .NET Core 2.Create a web app 创建一个 web 应用 By Rick Anderson This tutorial will teach you the basics of

剖析ASP.NET Core MVC(Part 1)- AddMvcCore(译)

原文:https://www.stevejgordon.co.uk/asp-net-core-mvc-anatomy-addmvccore发布于:2017年3月环境:ASP.NET Core 1.1 欢迎阅读新系列的第一部分,我将剖析MVC源代码,给大家展示隐藏在表面之下的工作机制.此系列将分析MVC的内部,如果觉得枯燥,可以停止阅读.但就我个人而言,也是经过反复阅读.调试甚至抓狂,直到最后理解ASP.NET MVC源代码(或者自认为理解),从中获益匪浅.通过了解框架的运作机制,我们可以更好的使

ASP.NET Core MVC 视图

ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处,学习难度较低.以下内容主要体现了编程中模块化的思想,模块化才应是我们关注的重点. Layout 布局用于提供各个页面所需的公共部分,如:菜单.页头.页尾等.在ASP.NET Core中默认的布局文件是位于/Views/Shared文件夹下的_Layout.cshtml文件: 我们通常在_Layout.cshtml中引入公共资源,如: <link href="~/css/reset.css" rel

asp.net core MVC 全局过滤器之ExceptionFilter过滤器(一)

本系类将会讲解asp.net core MVC中的内置全局过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter过滤器(一) asp.net core MVC 过滤器之ActionFilter过滤器(二) asp.net core MVC 过滤器之ResultFilter过滤器(三) asp.net core MVC 过滤器之ResourceFilter过滤器(四) asp.net core MVC 过滤器之AuthorizationFilter过

ASP.NET Core MVC 在linux上的创建及发布

前言 ASP.NET core转眼都发布半月多了,社区最近也是非常活跃,虽然最近从事python工作,但也一直对.NET念念不忘,看过了园区大神们搭建的Asp.net core项目之后,自己也是跃跃欲试,准备搞一下ASP.NET Core mvc的创建和部署,于是便有了这篇文章,希望能够帮助到你. 环境准备 这是我的开发环境,使用的nginx是nginx 1.6.3 直接yum install,然后需要安装dotnet环境,可以参照官网教程https://www.microsoft.com/ne