2018-03-27 开胃学习.Net 系列 - MVC 总结

当前,MVC作为一种主流框架,被广泛运用,如JAVA Web开发,.NET ASP,NET MVC

(1)MVC由三大核心模块构成:
控制器(Controller,简称C),
模型(Model,简称M)
视图(View,简称V);

(2)View负责视图呈现,Model负责数据处理,Controller负责处理视图与模型之间逻辑;

(3)WebForm中,一般是UI+BLL+DAL+Utility+WebService模式,而在MVC中,一般采用SOA+WebAPI+DAL+Model+MQ+AOP+Docker模式;




















EF and MVC Versioning

As of Visual Studio 2017, two varieties of web projects:
我们这课学习主要是

ASP.NET Web Application

  • Entity Framework 6 (or less)
  • MVC 5 (or less), Web API 2

ASP.NET Core Web Application

  • Cross-platform (Windows, Linux, Mac)
  • Entity Framework 7
  • MVC 6 & Web API combined (no distinction)

More on Core 1.0

Main features:

  • “No compile” development
  • Cloud-optimized 云优化
  • Modular (NuGet) 模块化
  • Host agnostic (Open Web Interface for .NET ̶OWIN)
  • No distinction between web application and web services Web应用程序和Web服务之间没有区别
  • Open source
  • Lightweight HTTP request pipeline
  • Side-by-side versioning

MVC 与 Web Forms 比较

  • Web Forms page life cycle does not apply
  • MVC Page life cycle different and simpler
  • Webform 每个页面由三部分组成:前端代码(Default.aspx),后台代码(Default.aspx.cs)和设计器(Default.aspx.designer.cs);
  • Multiple forms on a page supported支持多页表单
  • No server controls
  • No view state 视图状态 (since there are no server controls)
  • UI decoupled from the business logic 用户界面与业务逻辑分离
  • Many views for the same data 针对相同数据的许多视图
  • One view and many ways to process the data 一种视图和许多方法来处理数据
  • Higher degree of control over output 对产出的更高程度的控制
  • 更容易测试和执行测试驱动的开发
  • WebForm不利于前后端分离,MVC前后端分离
  • WebForm中,一般是UI+BLL+DAL+Utility+Webservice模式,而在MVC中,一般采用SOA+WebAPI+DAL+Model+MQ+AOP+Docker模式



















MVC Example

MVC

MVC 全过程
  • Controller alive only when request is alive
  • Controller 会失效,下一次request进来时,我们将会有一个新的controller
  • Routing 机制会不断地发送参数 params,上面的case就是config出Account Controller,然后得出involved的action,上图案例是login action
  • Login 是个Method。去查看Controller File,最后会有Login这个选项。这里要使用Database query,data come back,data 会进入一个business logic,生成新的 View
  • 这个新生成的View会进入一个 Razor View Engine, 这个Razor View Engine和 ASPS Markup 类似
    • ASP.NET页面由标记(Markup)和代码(Codebehind)文件组成
    • Aspx Markup 是一些普通的 Html 和一些特殊的Xml tag Server Control
    • Server Control 会渲染自己的Html
  • 这里最主要的区别就是没有Server Control, Webform 到达 浏览器就是纯html




















除了上面的,以下这个是另外一种更高级的案例:

MVC Example

主要是在Action ForgotPassword 里面还包含了另外一个Action EmailVerifier。这里做了一个Redirection,redirect到同一个Controller的另外一个Action。实际上,我们还可以Redirect到另外一个Controller的Action里,而且可以Redirect到 more than one Controller。



















Web Forms vs. MVC Lifecycle


Webform 需要很熟悉Page Lifecycle发生了什么
MVC 使用过程则不需要太清楚 Lifecycle中的内容


MVC Lifecycle

When a request is received, it is routed to the UrlRoutingModule object and then to the MvcHandler HTTP handler. The MvcHandler HTTP handler determines which controller to invoke by adding the suffix "Controller" to the controller value in the URL to determine the type name of the controller that will handle the request. The action value in the URL determines which action method to call.
当接收到一个请求时,它被路由到UrlRoutingModule对象,然后发送到MvcHandler HTTP处理程序。MvcHandler HTTP处理程序通过向URL中的控制器值添加后缀“控制器”来确定要调用哪个控制器,以确定控制器的类型名称,该控制器将处理请求。URL中的操作值决定调用哪个操作方法。

当Controller被MvcHandler选中之后,下一步就是通过ActionInvoker选定适当的Action来运行。

  1. UrlRoutingModule
  2. RouteTable apply 之后,RouteHandler 自动生成
  3. Controller object created by controller factory, factory里有MvcHandler,ProcessRequest()
  4. Controller.Execute()
  5. ActionInvoker
    这里有个pre action filter method
  1. ActionMethod()
  2. ActionResult
  3. ActionResult.ExecuteResult()




































Routing

WebForm中,对URL的传入请求通常映射到磁盘上的物理文件,如.aspx文件。例如对http://server/application/Product.aspx?id=4的请求映射到名为Products.aspx文件,该文件包含代码和标记用于呈现对浏览器的响应

Routing tell us which controller and action should execute in response to an HTTP request

The process of mapping URLs to controllers is called routing.
MVC中多数情况下是将URL映射到Controller和Controller下的Action
下面是Controller的例子:


URL patterns for routes in MVC applications typically include {controller} and {action} placeholders.
在MVC运用程序中,路由URL模式通常包含控制器和动作占位符。

When a request is received, it is routed to the UrlRoutingModule object and then to the MvcHandler HTTP handler. The MvcHandler HTTP handler determines which controller to invoke by adding the suffix "Controller" to the controller value in the URL to determine the type name of the controller that will handle the request. The action value in the URL determines which action method to call.
当接收到一个请求时,它被路由到UrlRoutingModule对象,然后发送到MvcHandler HTTP处理程序。MvcHandler HTTP处理程序通过向URL中的控制器值添加后缀“控制器”来确定要调用哪个控制器,以确定控制器的类型名称,该控制器将处理请求。URL中的操作值决定调用哪个操作方法。

For example, a URL that includes the URL path /Products is mapped to a controller named ProductsController. The value in the action parameter is the name of the action method that is called. A URL that includes the URL path /Products/show would result in a call to the Showmethod of the ProductsController class.
例如,一个包含URL路径 /产品 的URL映射到一个名为ProductsController的控制器。action参数中的值是调用的操作方法的名称。一个包含URL路径 /产品/show 的URL会导致对ProductsController类的Showmethod的调用。
【ASP.NET MVC系列】浅谈ASP.NET MVC 路由




































Route Registration

MVC应用程序首次运行时,会调用Application_Start()方法。这个方法随后调用了RegisterRoutes()方法创建路由表。

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                // routing pattern
                defaults: new { controller = "Department", action = "Index", id = UrlParameter.Optional }
                // If nothing specified in the URL, these are the assumed values (will invoke HomeController)
            );
        }
    }

默认路由就是:如果不填写Controller,会默认定位HomeController,如果不填写Action,会默认调用Index方法,如果不填写id,那么默认为空字符串。

即以下这些URL都会定位到HomeController.Index()方法,返回Index View视图。

  • index 是一个特殊的URL, 表明了大多数的服务器
  • id 在这里是optional的,也可以设置成Required
  • 可以只输入一个controller 名,但是不写action 名,就默认了是index action

If you adopt the MVC convention of implementing controllers by creating classes that derive from the ControllerBase class and giving them names that end with "Controller", you do not need to manually add routes in an MVC application. The preconfigured routes will invoke the action methods that you implement in the controller classes.
如果您通过创建从控制器基类派生的类来实现控制器的MVC约定,并给它们以“控制器”结尾的名称,那么您就不需要在MVC应用程序中手动添加路由了。预配置的路由将调用您在控制器类中实现的操作方法。

If you want to add custom routes in an MVC application, you use the MapRoute(RouteCollection, String, String) method instead of the MapPageRoute(String, String, String) method.
如果您想在MVC应用程序中添加自定义路由,您可以使用MapRoute(RouteCollection、String、String)方法,而不是MapPageRoute(字符串、字符串、字符串)方法。

The following example shows the code that creates default MVC routes in the Global.asax file, as defined in the Visual Studio project template for MVC applications.
下面的例子展示了在全局中创建默认MVC路由的代码。asax文件,正如在Visual Studio项目模板中定义的MVC应用程序。




































Controller

所有的controller 都源于 Controller 类

  • 这里返回了一个View function。在MVC project里,会有一个叫View的folder 默认存在。
  • 在View folder里还有一个Home folder,在这个folder里会查找一个Index file,返回。
  • 可以specify 任何View。
  • Controller name is significant: used for routing
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers
{
    public class ControllerDemoController : Controller
    {
        //
        // GET: /ControllerDemo/

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }
    }




































Controller Actions

通常,在定义一个方法时,我们常规性地根据方法是否有返回值归结为有返回值和无返回值两大类,控制器的本质是类,控制器的action本质是方法,如果按照数学集合来定义,那么控制器是类的一个子集,同理,控制器action是方法的一个子集,因此,在研究控制器以及控制器action时,我们是可以才用研究类和方法的一般思维的。

控制器动作(具体的action)返回的结果叫做控制器动作结果,动作结果是控制器返回给浏览器请求的内容。ASP.NET MVC框架支持六种标准类型的动作结果。

  • Action都是Method,但是并非所有Method都是Action

  • Action 以Controller类的方法来实现

  • 但是如果我们想写一个Method,例如 HelperMethod,不可以看作是一个Action,使用[NonAction]属性 作为annotation

  • Action 应该是需要 public,而不可以是private的

  • Action 不能像普通方法那样“重载” 参考

    1. 不允许使用不同参数的同名方法,也就是不能overload
    2. 除了区分GET和POST(需要annotation注释)。可以写同名的Action去处理GET和POST
    3. 在C#里,重载是可以的
  • Controller 通常返回ActionResult或Task <ActionResult>类型

  • 使用model binder将action参数绑定data

  • 参数值可能来自各种来源:
    1.Form values
    2.Querystring parameters
    3.Cookie值

  • 注意返回的是一个 async Task<ActionResult>
  • await block the IO bound computation, free up the thread of CPU of other thing while waiting the result return.
  • 在method的最开始,有一些annotation
  • [HttpPost] 属性是handle POST 而不是GET,不一定需要些GET
  • [AllowAnoymous]
  • [ValidateAntiForgeryToken] 确保不是为了欺骗服务器
  • return View(model) 把model传给View
  • RedirectToAction 这里我们redirect到其他的action,controller




































Action Results

通常在 ASP.NET MVC项目中创建一个 Controller的时候, Index()方法默认的返回类型都是 ActionResult,ActionResult实际上是一个抽象类,因此实际返回的类型是该抽象类的子类

  1. ViewResult - 呈现网页,表示 HTML的页面内容(视图)
  2. PartialViewResult - 呈现分部视图(PartialView)
  3. RedirectResult - 重定向到另一个操作方法(重定向)
  4. ContentResult - 返回用户定义的内容(内容)
  5. JavaScriptResult - 返回在客户端上运行的JavaScript(JavaScript)
  6. FileResult - 返回二进制输出(File)
  7. HttpNotFoundResult - 表示资源未找到(HttpNotFound)
  8. EmptyResult - 返回没有结果

上述的Controller,可以invoke database,可以invoke business logic。但是,不应该把业务逻辑放在controller里。

ActionResult是Action运行后的回传型别,但是当Action回传ActionResult的时候,其实并不包含这个ActionResult(例如ViewResult)的运行结果,而是包含运行这个ActionResult时所需的数据,当MvcHandler从Controller取得ActionResult之后才会去运行出ActionResult的结果。在ActionResult抽象类中仅仅定义了一个ExecuteResult()方法。




































Model

Typically an instance of an Entity Framework class, but could be an instance of any class
Can be adorned with data annotations (e.g. for validation)

  • MVC会对这些作出处理




































Views

  • Responsible for rendering the user interface (e.g. HTML)
  • Rendering performed by the Razor View Engine
  • Razor view files end in .cshtml (C#) or .vbhtml (Visual Basic)
    1.Reflects the embedded programming language
  • Similar to Web Forms view engine
    1.Web Forms: HTML with embedded ASPX markup
    2.Razor: HTML with embedded C#
    3.Elegant, minimal syntax
  • @ is a key transition character in Razor
  • More on Razor later!


  • 每次进入这个循环,都会生成这个html。方法是DisplayFor,后面传入参数
  • 这个是html helper
  • EditorforDisplayFor
  • ActionLink(),第一个是内容,然后是action,最后是参数







1.ASP.NET MVC页面基本被放在Views文件夹下;
2.利用APS.NET MVC模板生成框架,Views文件夹下的默认页面为.cshtml页面;
3.ASP.NET MVC默认页面为Razor格式的页面,因此默认页面为.cshtml页面;
4.ASP.NET MVC中,支持WebForm页面,即.aspx页面;
5.ASP.NET MVC中,支持静态html页面;


1.这里没添加Account控制器;
2.默认约定:在Controllers新增一个控制器,就会默认地在Views文件夹下新增一个视图问价,用来存放该控制器添加的视图,如上图中增加Home控制器, 在Views下就自动新增加Home文件,用来存放是Home控制器视图;




































Razor View

  • 这里有个Html.BeginForm。而不是用常用的form










View Models

  • 限制:只能将一个Model传递给View
  • 但有时我们想传不止一个模型,或者特定于View的信息
  • 办法:
    1.创建一个View Model Class,其唯一目的是存储的view-specific data
    2.在controller中,创建view model并 populate the fields填充字段
    3.Pass the view model to the view the same way as before.
    4.Never use the View Model for a Entity Framework
    5.View models should never be used for business logic.


  • Display










Passing Data

ViewData和TempData属性均返回一个具有字典结构的数据容器,即字典类型的key/Value对,ViewBag为Dynamic类型。

From controller to view during 传递数据 during the same HTTP request方法:

  • Pass the model directly to the view:
  • ViewBag:动态输入Dynamically typed
  • ViewData:强类型 Strongly typed
  • ViewBag和ViewData属性是同一份数据的不同表现形式,二者的不同之处在于前者是一个动态对象,可以为其指定任意属性(动态属性名将作为数据字典的Key)
  • Useful when there are multiple models
  • 存储在键/值对中Stored in key/value pairs
  • 存储在ViewBag中的对象在取出时必须转换为原始类型

From controller to controller传递数据 typically through a redirect:

  • TempData
    TempData存储临时数据,并且设置的变量在被第一次读取后会被移除,即TempData设置的变量只能被读取一次
  • Key/value pairs
  • Objects stored in TempData must be cast
  • Store data in TempData before a call to RedirectToAction.










Partial Views

A partial view is a regular view (with .cshtml extension) that renders part of a web page.

  • Good for “packaging up” a logical grouping of HTML, typically for reuse
  • Can be used to render headers, footers, and body separately (for example)
    To display a partial view, call the helper method Html.Partial or Html.RenderPartial
  • Partial returns a string
  • RenderPartial writes directly to the Response object
  • By default, partial views are expected to be in the folder: \Views\Shared\











参考链接:

Routing - 深入理解Asp.net MVC路由
Routing - ASP.NET MVC-轻松理解Routing(路由)
ASP.NET自定义控件复杂属性声明持久性浅析
理解 ASP.NET MVC系列之二:URL Routing机制:RouteTable
理解 ASP.NET MVC系列之一:ASP.NET MVC基于MVC设计模式
理解 Asp.Net MVC的Controller(控制器)
理解 ASP.NET MVC 中的 Controllers and Actions
理解 ASP.NET MVC 中的 ActionResult

ASP.NET MVC Model Binding 模型绑定
entity-framework - 在MVVM和 Entity Framework 中,POCO类的含义
ASP.NET MVC系列 浅谈ASP.NET MVC运行过程
ASP.NET MVC系列 浅谈ASP.NET MVC 控制器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容