ASP.NET MVC4 入门简介

  1. 云栖社区>
  2. 博客>
  3. 正文

ASP.NET MVC4 入门简介

暖枫无敌 2017-09-14 18:42:18 浏览869
展开阅读全文

1、什么是设计模式?

模式的理解

模式是一种解决问题的思路,而不是具体的做法。

 

设计模式的理解

在软件开发领域,设计模式是为解决开发中某一类问题而提出的一种解决方案。因此,设计模式本质上是思想,而不是代码。设计模式追求的思想上的复用,而不是代码上的复用。

 

2、ASP.NET MVC概述

ASP.NET MVC是一种构建Web应用程序的框架,它将一般的MVC(Model-View-Controller)模式应用于ASP.NET框架。

MVC将Web应用程序划分为三个主要的部分,以下是MSDN给出的定义:

模型(Model:模型对象是实现应用程序数据域逻辑的应用程序部件。 通常,模型对象会检索模型状态并将其存储在数据库中。 例如,Product 对象可能会从数据库中检索信息,操作该信息,然后将更新的信息写回到 SQL Server 数据库内的 Products 表中。

视图(View:视图是显示应用程序用户界面 (UI) 的组件。 通常,此 UI 是用模型数据创建的。 Products 表的编辑视图便是一个视图示例,该视图基于 Product 对象的当前状态显示文本框、下拉列表和复选框。

控制器(Controller:控制器是处理用户交互、使用模型并最终选择要呈现的视图来显示 UI 的组件。 在 MVC 应用程序中,视图仅显示信息;控制器则用于处理和响应用户输入和交互。 例如,控制器处理查询字符串值,并将这些值传递给模型,而模型可能会使用这些值来查询数据库。

 


3、ASP.NET MVC的发展历程

我们以一张时间轴线图开始,了解一下ASP.NET MVC的发展历程。


2007年2月,Microsoft公司的Scott Guthrie在旅途中草拟了ASP.NET MVC的内核程序。经过9个预览版本,于2009313,正式发布ASP.NETMVC1官方版本。

时隔一年,ASP.NETMVC220103发布,部分主要特征如下:

•     带有自定义模板的UI辅助程序

•     在客户端和服务端基于特性的模型验证

•     强类型的HTML辅助程序

•     改善的Visual Studio开发工具

•     支持将大型应用程序划分为域

•     支持异步控制器

•     使用Html.RenderAction支持渲染网页或网站的某一部分

•     新的辅助函数、使用工具和API增强

20111ASP.NET MVC3正式推出,部分主要特征如下:

•     支持Razor视图引擎

•     支持.NET4数据注解

•     改进了模型验证

•     提供更强的控制和更大的灵活性,支持依赖项解析(Dependency Resolution)和全局操作过滤器(Global Action Filter)

•     丰富的JavaScript支持,其中包括非侵入式JavaScript、jQuery验证和JSON绑定

•     支持NuGet,可以用来发布软件,管理整个平台的依赖

20129ASP.NET MVC4正式发布,新增功能主要包括:

•     ASP.NET Web API

•     增强了默认的项目模板

•     添加使用jQuery Mobile的手机项目模板

•     支持显示模式(Display Mode)

•     支持异步控制器的任务

•     捆绑和微小(minification)

201310ASP.NET MVC5与Visual Studio 2013一起发布,下面列出了一些主要特征:

•     One ASP.NET

•     新的Web项目体验

•     ASP.NETIdentity

•     Bootstrap模板

•     特性路由

•     ASP.NET基架

•     身份验证过滤器

•     过滤器重写

4、创建ASP.NET MVC4应用程序

1、选择“文件”->“新建”->“项目”选项,如下图所示:


2、在“新建项目”对话框左侧的“已安装”->“模板”->“Visual C#”列表下,选中Web选项,选择ASP.NET MVC4 Web应用程序,将应用程序命名为MyFirstMvcProject,点击“确定”按钮,如下图所示:


3、在弹出的“新ASP.NET 项目”对话框中,选中“基本”模板,视图引擎选择“Razor”,同时将“创建单元测试项目”勾选上,点击“确定”按钮,如下图所示:


4、至此,一个新的MVC项目已经创建完成,如下图所示:


5、ASP.NET MVC应用程序结构

新的MVC项目创建完成后,会自动向这个项目中创建一些目录,下表介绍了这些目录的主要用途。

目录

用途

App_Data

用于存储想要读取/写入的数据文件

App_Start

用于保存一些功能的配置代码

Content

用于保存CSS、图像和其他站点内容

Controllers

用于保存处理URL请求的控制器类

Models

用于保存表示和操纵数据以及业务对象的类

Scripts

用于保存JavaScript库文件和脚本

Views

用于保存负责呈现输出结果的UI模板文件

 

6、ASP.NETMVC的约定

在默认情况下,ASP.NET MVC应用程序对约定的依赖性很强,这样就避免了开发人员配置和指定一些项,因为这些项可以根据约定来推断。这个概念通常被称为“习惯优于配置(convention over configration”。
    ASP.NET MVC对于程序结构的约定如下:
1、每个Controller类的名字以Controller结尾,保存在Controller目录中。
2、应用程序的所有视图放在单独的Views目录下。
3、控制器使用的视图是在Views主目录下的,与控制器名称相同的子目录中。

 

7、WebForm和ASP.NET MVC,为什么MVC更好一些?

    ASP.NET Webform 后台代码(behind code)—— 福音与诅咒

  我们已经在项目开发中使用过ASP.NETWebform技术,大家会发现它更接近可视化设计,换句话说,开发者只需要从设计面板中拖拽控件即可完成UI,接着在behindcode中实现逻辑代码即可完成最后的Web页面功能。


  所以换句话说,当你从设计面板中拖拽一个按钮时,在后台代码中就会生成一个button对象,你只需要在按钮的点击事件中实现事件响应代码即可。

public partial class WebForm1 :System.Web.UI.Page

{

       protected void Page_Load(object sender, EventArgs e)

        {

           // Developers write code here

        }

       protected void Button1_Click(object sender, EventArgs e)

        {

           // Developers write code here

        }

  }

  当我们在页面中拖拽一些UI元素时,双击它们即可在后台代码中生成一系列事件响应代码,这些逻辑代码都在ASPX.CS文件中。


  这个后台代码文件是ASP.NETWebForm的关键,你可以在这个文件中应用.NET的所有特性,包括事件、委托、HTTP协议以及Session等等。

  但是这种behindcode模式有5个问题,下面我们将一一讲述这5个问题,并用MVC的设计思想来分别解决这些问题。

 问题1:基于视图的方案来解决基于行为的需求

 我们的网站最终是由用户使用的,用户访问网站肯定会有特定的目的,网站要做的就是通过让用户的交互行为来完成其想要的目的。比如当用户访问一个购物网站时,也许他的交互行为会是这样的:

·        购买产品

·        打印发票

  这些交互行为是通过按钮点击、右键点击和浏览器URL实现的。由于这些交互都是基于HTTP协议的,所以如果我们能将这些交互行为映射到具体的一些方法上,那么整个架构将会变得简单很多。

  但是微软做不到这样,因为它要实现可视化网页编程,所以他们最终选择了基于视图的解决方案。


  从上图可以看出,整个请求过程看上去很奇怪:

·        用户发起一个HTTP请求,比如HTTPPOST / GET

·        IIS服务器将请求映射到视图

·        视图调用页面的生命周期,通过事件驱动,调用合适的交互方法

·        最后将交互的结果展现给终端用户

  因为微软一开始就选择了基于视图的设计方案,所以架构本身很难向基于用户交互的设计思想靠拢。换句话说,当用户发出“购买”请求时,先是访问了视图页面“Shopping.aspx”,后台逻辑代码在“Shopping.aspx.cs”中,页面生命周期中会将页面的计算结果返回给用户。


  如果利用MVC的思想,都是基于用户交互行为的话,那么请求流程将会是如下所示:


 问题2:坏架构的副作用——紧耦合

  当选择了一个错误的架构以后,未来将会出现很多难以解决的副作用,在ASP.NETWebForm中就出现了这个问题。尽管behindcode后台代码被分离到不同的文件中,但是ASPX.CS文件和ASPX文件却紧密的联系在一起,这将导致系统的耦合度很高,并且很难解耦合,这是一个很头疼的问题。


  简单地说,我们很难将Customer.aspx.cs和CustomerDetailed.aspx简单地剥离开,后台代码已经紧紧地将其捆在一起,而且也很难复用。如果我们可以将请求先通过action,而不通过视图view,action得到的数据再由控制器决定由哪个view展示,那么请求的流程将会是这样的:


  所以我们可以很方便地控制最终结果是由移动页面展示还是正常页面展示,如下代码:

publicActionResult Index(string DeviceType)

{

           if (viewType == "Mobile")

            {

                returnView("MobileView");

            }

            else

            {

                returnView("NormalView");

            }

}

 问题3HTML不是唯一的返回类型

  由于视图view和后台代码behindcode紧密耦合在一起,所以默认的返回类型就固定了,都是HTML类型。如果你想改变类型就必须设置Content-type和调用Response.End方法。

  如果我们创建一个Action,返回的类型由Action中指定,系统就可以在同一个action中根据不同条件输出不同的返回类型。代码如下:

publicActionResult Index(string  viewType)

{

            if (viewType == "JSON")

            {

                return Json(new Customer(),JsonRequestBehavior.AllowGet);

            }

            else

            {

                returnView("DisplayCustomer", new Customer());

            }

}

 问题4:视图和数据的灵活组合

  Webform是视图优先的架构,所以视图决定了展现的数据,因此视图的扩展性就很差,如果遇到复杂的数据结构,这种方式就显得力不从心了。

  但是如果是行为优先的架构的话,当我们触发action时,action可以根据不同的请求选择不同的数据模型和视图结构,如下图:


  在MVC中,你可以在不同的view中选择相同的数据模型,比如下面的代码,customerdata数据既可以绑定在DetailCustomer视图中,也可以绑定在Customer视图中。

publicActionResult Index(string ViewName,Customer customerdata)

{

            if (ViewName =="Detailed")

            {

returnView("DetailCustomer",customerdata);

            }

            else

            {

                returnView("Customer",customerdata);

            }

}

  但这在WebForm中实现起来是非常麻烦的。

 问题5、将behind code当做普通的类来进行单元测试

  behindcode后台代码在WebForm中是一个非常庞大的类,并且不能简单地实例化。要知道WebForm是继承于Page类的,Page类不能直接实例化,因为它有太多的依赖项。

publicpartial class WebForm1 : System.Web.UI.Page

    {

        protected void Page_Load(object sender,EventArgs e)

        {

        }

        public void Button1_Click(objectsender, EventArgs e)

        {

            Session["SomeSession"] ="Is this set";

        }

    }

  为什么我们想要实例化Page类呢?其中一个原因就是可以方便单元测试。比如我要测试一个按钮点击事件,用来检查Session是否设置成功。在WebForm中的代码看起来不是那么舒服:

[TestMethod]

publicvoid TestMethod1()

{

            WebApplication22.WebForm1 obj = newWebApplication22.WebForm1();

            obj.Button1_Click(this, newEventArgs());

}

  并且运行时还会抛出一个异常:


  在MVC中,这个类变成了一个普通类,我们可以在测试工程中将它实例化,并对类里面的属性方法、Session、ViewBag 、 TempData等进行单元测试。

publicclass HomeController : Controller // this class is simple

{

        public ActionResult Index()

        {

            Session["SomeSession"] ="Is this set";

            return View("SomeView");

        }

}

 所以是否选择MVC解决方案?


  从WebForm架构切换到MVC架构,我们需要做以下几件事情:

·        将behindcode中的代码转移到controller类中,并将原来的方法转换成action方法。

·        中间层用数据模型和逻辑接口代替。

·        视图view只用来展现数据和页面布局。

·        DAL层和其他层没有什么变化,因为它和behindcode关系不大。


  所以MVC架构中,用户的请求分为下面3个步骤:

·        终端用户发送请求,路由器将请求路由到合适的Controller,Controller是逻辑实体和行为Action的集合。

·        Controller将请求映射到特定的Action。

·        Action有两个任务,第一是获取合适的数据,第二是将这些数据和视图View绑定起来。Action创建数据模型,并将数据模型连接到指定View,输出最终的相应结果。

网友评论

登录后评论
0/500
评论
暖枫无敌
+ 关注