ASP.NET MVC流程解说

it2025-07-26  10

   

      开始想这个标题时,,很忧郁什么标题将得到更好的叫什么,最后确定的解释,虽然稍0基金会,但是,这个概念是非常。我想出了一个相当的价格值的。

,開始。

 

1、MVC的基本开发流程

 

2、webform和MVC的选择

 

3、MVC的内部过程

 

 

1、MVC的开发流程

 

     MVC的出现时微软在2009年左右開始提出的站点开发的新的发展方向。这个方面的开发官方解释是能够比較好的实现三层分离,并且分离之后。能够实现复用等相关优点,通常人们列举的样例是ui方面能够同一时候支持HTML网络或者WAP网络。可是事实上个人的理解是,动态站点的开发经过不断地证实和发展,java的struts模型。能够提高开发速度。也能够减少差多。是比較好的框架。而微软也须要提供自己的开发框架。不能够仅仅是一个界面一个界面的设计方式,设计模式逐步进入到了web开发的领域。

 

      MVC使用vs2010进行开发时(这里介绍的是MVC2),首先须要选在一个模板,然后vs2010会帮忙创建好相应的文件夹结构。

每一个文件夹的基本功能:

Content:主要用于描写叙述css之类的资源

Controllers:主要就是controller的存放位置。创建controller时。都是须要在该文件夹创建的。

Models:主要就是entity的详细位置。以及跟entity相关的操作类

Scripts:javascript脚本存放的位置

Views:该部分主要是放置view显示部分的

Global.asax:眼下来看,该部分主要就是路由设置

Web.config:该配置文件而已

         从开发的流程方面来看,MVC的开发方式,或者说思考的方式出现了变化,在MVC其中。须要理解一个重要的点是:

Controller才是系统的中心,一切环绕Controller展开。

 

Model所谓模型,能够理解为数据,这个数据能够是数据库中相应的表中的数据,这样的数据是仅仅有属性,而没有动作的。这样的数据通常也被称之为Entity,即实体,除了这样的数据之外。MODLE起始还要包含Interface,这些接口的目标是提供能够控制Entity的接口标准,然后在提供实现的载体,通常我们称之为Mock类,为了方便,可能我们还会在Model其中创建各种factory。从而简化对象的创建。

 

Controller这个部分就是核心了,事实上所谓核心,是说所有的处理,所有环绕着Controller展开,它的主要工作是訪问model,获取数据后,将參数转发给view,然后让view表现出来。

在这里主要完毕的工作有两点:

1、在client訪问一个页面后。须要跳转到Controller相应的action中去。然后在action中处理相应的view显示出来。

2、 完毕客户的表单提交对应处理,也就是Form表单处理。(还记得之前讲过,对于HTML而言。仅仅有Form表单实现了client的信息发送给服务端。然后由服务端处理相关的对应,由于MVC的设计目标就是放弃了微软原有的server控件,因此一切回归原始,採用HTML的form表单方式实现提交和相关的控制处理。)

 

View顾名思义,该部分就是现实的部分,这个部分须要时刻记住的是,这个view尽管也是aspx的页面,可是已经发生了根本性的变化,不再有所谓的codebeind代码了。这个view的全部变成将採用混合式的变成。你会注意到这个部分的变成变为HTML与C#的混合。会出现非常多的<%%><%=%>类似的代码。

非常多人起始对这个部分有不同的开发。混合代码对于分层不利。可是在MVC中,由于不涉及逻辑,所以view的表现变得简单。混合编程会变为能够接受的处理方式。

另外,这样的方式带来的优点是,美工能够介入了。他们的改动对于程序猿来说。没有什么特别,也是非常easy直接引入的。

带来的坏处是Gridview这样的强大的server控件被丢弃了。

尽管是这样。可是我个人认为。这是回到了web开发的本质。

他的思想,与JSP,PHP等等变为一致。

 

Golabal.asax路由表。这个部分就是所谓的全局路由表。在MVC框架中。之所以实现了MVC功能,一个重要的概念是路由表,该部分实现了地址訪问的动态。不再提供详细页面的訪问模式。

 

注意:给我的感觉是,记住在view文件夹和model文件夹中。加入子文件夹,每一个controller相应的view,都是一个文件夹下的view。

这个是MVC框架查找时自己主动搜索的。

 

2、webform和MVC的选择

 

         这个部分的争论,我想从微软開始推出MVC框架后。大家就在不间断的讨论着,不同的人,给出的看法也是不同。就我个人而言。我认为MVC才是未来趋势。是世界最后大同的根本。虽然web form的模式。是微软开创性的创造。可是毕竟web开发不是微软首创,非常多时候,大势所趋而已。

我这里仅仅是想谈谈两者的思想出发点的区别:

webform模式。这个模式的思维基础,是微软在桌面开发中取得了前所未有的成功。这些成功,微软希望拷贝到网络开发中,何为form。就是窗体开发。这样的框架的逻辑是所见即所得+事件处理,微软希望可以将web实现为桌面开发的模式。可是网络开发的基础是HTML和HTTP协议,这两个部分带来的问题是HTML表现元素有限,而且仅仅可以通过form与后台server通信。另外,HTTP协议无状态,无法实现消息机制,为了解决这些问题,微软创造了新的开发模式,引入ASP.NETserver控件,实现了丰富的控件。通过postback回传机制,实现了事件模型,通过codebehind技术实现web页面与C#代码的分离。上述技术。的确非常成功,也确实非常大程度上简化了web的开发。可是随着发展,带来了问题,就是webform的开发基础是页面化的。这样的思维模式是说你开一个页面,然后在这个页面写响应事件。可是这样的模式对于频繁变化的web程序缺乏良好的复用性。而且,前端人员开发的界面。往往在合成时,须要重做,这是微软自己创造的困难。这是一种以Page为中心的开发思想。

MVC模式,这个模式的思维基础。是分工清晰,以Controller为核心。在开发时能够先做model再做Controller。最后做view,通过使用demo view实现。最后再替换美工的view。这样的模式变成了以数据为中心的开发思想。最大的优点是,这样的模式中每一个部分都能够灵活复用,最大限度的实现如今的各种网络须要。比方互联网和移动互联网。并且。其它的变成语言。在思想方面也基本採用这样的模式。这样的模式终于被时间证明。成为了标准思考方式和开发方式。微软提倡的桌面化开发,渐渐退却往日之光芒。

 

3、MVC的内部过程

 

         这个部分是个很核心的问题,本文除了自己理解,还大量引用了其它相关的文章。

尝试解说清楚MVC的基本运转流程。

 

MVC的主体过程:

 

        

 

问题:

1、 浏览器请求的地址,并非详细的某个页面,如1234.aspx页面。而是controller/action方法。这是怎样做到的?

2、 Controller被訪问到以后。怎样找到详细的view进行返回的?

 

我个人的理解就是回答了上述的问题,也就解释清楚了MVC的基本框架。

第一个问题,浏览器请求地址的问题。MVC之所以可以找到详细的Controller是由于有一个route组件。实现了路由处理的功能。将请求转化为Controller的详细方法。须要注意该组件竟然是个独立组件。

Routing的作用:

1、 解析URL,识别其中的參数

2、 解析之后。调用详细的controller和action

 比方首页地址是: localhost/home/index

我们发现訪问上面的地址, 最后会传递给 HomeController中名为indexaction(HomeController类中的index方法).

当然server端不会自己去实现这个功能关键点就是在Global.asax.cs文件里的下列代码:

        public static void RegisterRoutes(RouteCollection routes)         {             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");               routes.MapRoute(                 "Default",                                              // Route name                 "{controller}/{action}/{id}",                           // URL with parameters                 new { controller = "Home", action = "Index", id = ""// Parameter defaults             );           }           protected void Application_Start()         {             RegisterRoutes(RouteTable.Routes);         }

 

回来看我们的Url: localhost/home/index

localhost是域名, 所以首先要去掉域名部分: home/index

相应了上面代码中的这样的URL结构:{controller}/{action}/{id}

由于我们建立了这样的Url结构的识别规则, 所以可以识别出 Controllerhome,actionindex,id没有则为默认值"".

上述功能之所以可以实现,关键在MapRoute方法。尽管MapRoute方法是RouteCollection对象的方法,可是却被放置在System.Web.Mvc程序集中, 假设你的程序仅仅引用了System.Web.Routing, 那么RouteCollection对象是不会有MapRoute方法的. 可是假设你同又引用了System.Web.Mvc, 则在mvcdll中为RouteCollection对象加入了扩展方法:

       public static void IgnoreRoute(this RouteCollection routes, string url);         public static void IgnoreRoute(this RouteCollection routes, string url, object constraints);         public static Route MapRoute(this RouteCollection routes, string name, string url);         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);         public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces);         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);         public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);

RouteCollection是一个集合,他的每一项应该是一个Route对象. 可是我们使用MapRoute时并没有创建这个对象, 这是由于当我们将MapRoute方法须要的參数传入时, 在方法内部会依据參数创建一个Route对象:

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {             if (routes == null) {                 throw new ArgumentNullException("routes");             }             if (url == null) {                 throw new ArgumentNullException("url");             }               Route route = new Route(url, new MvcRouteHandler()) {                 Defaults = new RouteValueDictionary(defaults),                 Constraints = new RouteValueDictionary(constraints)             };               if ((namespaces != null) && (namespaces.Length > 0)) {                 route.DataTokens = new RouteValueDictionary();                 route.DataTokens["Namespaces"] = namespaces;             }               routes.Add(name, route);               return route;         }

上面就是MapRoute方法的实现, 至于在创建Route对象时第二个參数是一个MvcRouteHandler, 它是一个实现了IRouteHandler接口的类. IRouteHandler十分简单仅仅有一个方法:

IHttpHandler GetHttpHandler(RequestContext requestContext);

參数是一个RequestContext 类实例, 这个类的结构也非常easy:

    public class RequestContext     {         public RequestContext(HttpContextBase httpContext, RouteData routeData);           public HttpContextBase HttpContext { get; }         public RouteData RouteData { get; }     }

当中的一个属性RouteData就包括了Routing依据Url识别出来各种參数的值, 当中就有ControllerAction的值.

归根结底, ASP.NET MVC最后还是使用HttpHandler处理请求. ASP.NET MVC定义了自己的实现了IHttpHandler接口的Handler:MvcHandler,  由于MvcRouteHandlerGetHttpHandler方法最后返回的就是MvcHandler. 

MvcHandler的构造函数须要传入RequestContext 对象, 也就是传入了全部的全部须要的数据, 所以最后能够找到相应的ControllerAction, 已经各种參数.

(引用參考:http://www.cnblogs.com/zhangziqiu/archive/2009/02/28/ASPNET-MVC-2.html)

(引用參考:http://www.cnblogs.com/zhangziqiu/archive/2009/03/11/Aspnet-MVC-3.html)

 

第二个问题:Controller找到了,Action也找到了。此时怎样哪?

 

以下分层次的总结Controller处理流程:  

1. 页面处理流程

发送请求 –> UrlRoutingModule捕获请求 –>MvcRouteHandler.GetHttpHandler() –> MvcHandler.ProcessRequest()

2.MvcHandler.ProcessRequest() 处理流程:

使用工厂方法获取详细的Controller –> Controller.Execute() –> 释放Controller对象

3.Controller.Execute() 处理流程

获取Action –> 调用Action方法获取返回的ActionResult –> 调用ActionResult.ExecuteResult() 方法

4.ActionResult.ExecuteResult() 处理流程

获取IView对象-> 依据IView对象中的页面路径获取Page-> 调用IView.RenderView() 方法(内部调用Page.RenderView方法)

 

通过对MVC源码的分析,我们了解到Controller对象的职责是传递数据,获取View对象(实现了IView接口的类),通知View对象显示.View对象的作用是显示.尽管显示的方法RenderView()是由Controller调用的,可是Controller不过一个"指挥官"的作用, 详细的显示逻辑仍然在View对象中.须要注意IView接口与详细的ViewPage之间的联系.ControllerView之间还存在着IView对象.对于ASP.NET程序提供了WebFormView对象实现了IView接口.WebFormView负责依据虚拟文件夹获取详细的Page,然后调用Page.RenderView().

引用參考:(Http://www.cnblogs.com/zhangziqiu/archive/2009/03/11/Aspnet-MVC-3.html

说到这里。相信非常多人開始似乎明确了,又似乎不明确了,以下我做进一步的解说,先看一下。通常Controller的实现例如以下:

 

    public class HomeController:Controller     {         public ActionResult Index()       {             Return View(“Index”); }     }

 

先看看关键类ActionResult。这个返回值。体现了微软精心设计。为什么做这么个类,事实上本质而言,微软希望这个action能够返回很多其它内容,而不不过view。

类名

抽象类

父类

功能

ContentResult

 

 

依据内容的类型和编码,数据内容.

EmptyResult

 

 

空方法.

FileResult

abstract

 

写入文件内容,详细的写入方式在派生类中.

FileContentResult

 

FileResult

通过文件byte[] 写入文件.

FilePathResult

 

FileResult

通过文件路径写入文件.

FileStreamResult

 

FileResult

通过文件Stream 写入文件.

HttpUnauthorizedResult

 

 

抛出401错误

JavaScriptResult

 

 

返回javascript文件

JsonResult

 

 

返回Json格式的数据

RedirectResult

 

 

使用Response.Redirect重定向页面

RedirectToRouteResult

 

 

依据Route规则重定向页面

ViewResultBase

abstract

 

调用IView.Render()

PartialViewResult

 

ViewResultBase

调用父类ViewResultBase ExecuteResult方法重写了父类的FindView方法寻找用户控件.ascx文件

ViewResult

 

ViewResultBase

调用父类ViewResultBase ExecuteResult方法重写了父类的FindView方法寻找页面.aspx文件

 

这里我们主要解说viewResult的作用。

在ASP.NETMVC中,ViewResult用的最多。Controller有一个View方法,它来实例化一个ViewResult对象,并返回。

以下是View方法:

protected internal virtual ViewResult View(string viewName, string masterName, object model) {     if (model != null) {         ViewData.Model = model;     }     return new ViewResult {         ViewName = viewName,         MasterName = masterName,         ViewData = ViewData,         TempData = TempData     }; }

 

ViewResult类的ExecuteResult方法的详细參考例如以下:

public override void ExecuteResult(ControllerContext context) {     if (context == null) {         throw new ArgumentNullException("context");     }     if (String.IsNullOrEmpty(ViewName)) {         ViewName = context.RouteData.GetRequiredString("action");     }     ViewEngineResult result = null;     if (View == null) {         result = FindView(context);  // 非常关键。找到详细的view         View = result.View;     }     ViewContext viewContext = new ViewContext(context, View, ViewData, TempData); // 非常关键,渲染自己     View.Render(viewContext, context.HttpContext.Response.Output);     if (result != null) {         result.ViewEngine.ReleaseView(context, View);     } }

 

那么怎样FindView哪?详细例如以下:

 

rotectedoverrideViewEngineResult FindView(ControllerContext context) {     ViewEngineResult result =ViewEngineCollection.FindView(context, ViewName, MasterName);     if (result.View != null) {         return result;     }     //we need to generate an exception containing all the locations we searched   StringBuilder locationsText = new StringBuilder();     foreach (string location in result.SearchedLocations) {         locationsText.AppendLine();         locationsText.Append(location);     }     throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,     MvcResources.Common_ViewNotFound,ViewName, locationsText)); }

 

从ViewResult类的FindView方法中,得知ViewEngineResult是通过ViewEngineCollection的FindView得到的。而ViewEngineCollection正是ViewEngines的静态属性Engines,Engines返回一个仅仅有一个WebFormViewEngine类型实例的一个集合。所以。ViewEngineResult会是调用WebFormViewEngine类的FindView方法返回的结果。

假设ViewEngins的静态属性Engines有多个ViewEngine提供。那么就依次遍历它们直到找到第一个不为空的ViewEngineResult为止。这样我们就能够在同一个MVC站点中使用多种视图引擎了。

 

静态类ViewEngines的描写叙述例如以下:

public static class ViewEngines {   private static readonly ViewEngineCollection _engines = new ViewEngineCollection { new WebFormViewEngine(), new RazorViewEngine() };           public static ViewEngineCollection Engines     {         get { return _engines;}      }  }     public class ViewEngineCollection : Collection<IViewEngine>  {      //其它成员  public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName);  public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName);  }

从上述样例能够看出,起始微软为我们提供了两个ViewEngine, WebFormViewEngine和RazorViewEngine,WebFormViewEngine相应的是ASPX界面,RazorViewEngine相应的是.cshtml/.vbhtml引擎

此外,这里有一个隐藏非常深的概念,似乎非常多书都没讲清楚。每个引擎都会相应一个view。作为页面渲染使用。对于viewengine做进一步的解释,就是说,为什么一个view其中的<%%>之类的界面元素最后能够变成html。就是这些引擎在起作用。他们的内部实现,能够提供类似正則表達式或者是页面parsing的方法,完毕页面字符串解析。从而转换为相应的html,再response给client浏览器。

 

微软提供的两种viewengine和view例如以下:

RazorViewEngine和Razorview

(參考引用:http://www.cnblogs.com/artech/archive/2012/09/05/razor-view-engine-02.html)

WebformViewengine和Webformview

 

通过上边的讲述。主要的概念已经讲清楚了,假设希望实现自己的viewengine,能够查看一下微软參考实现是怎样做到的,然后我们就能够防治自己的viewengine了。这里便须要进一步说明的是。为什么MVC须要viewengine。而WEBFORM不须要,是由于,微软的webform是直接通过IHttphandler处理了,也就是说ASP.NETWEBFORM模式中的HTTPHANDLER完毕了事件处理和页面显示的双重功能。而ASP.NETMVC没有事件处理,因此页面显示被划到了viewengine其中实现了。事件处理。被controller替换处理了。

 

微软的Razorview和Webformview本质上是实现于IView接口,而WebformViewengine和Webformview本质上是实现于IViewEngine

 

以下介绍他们的实现逻辑:

public interface IView    2: {       3:     void Render(ViewContext viewContext, TextWriter writer);    4: }    5:     6: public class ViewContext : ControllerContext    7: {    8:     //其它成员    9:     public virtual bool ClientValidationEnabled { get; set; }   10:     public virtual bool UnobtrusiveJavaScriptEnabled { get; set; }   11:    12:     public virtual TempDataDictionary TempData { get; set; }      13:     [Dynamic]   14:     public object                     ViewBag { [return: Dynamic] get; }   15:     public virtual ViewDataDictionary ViewData { get; set; }   16:     public virtual IView              View { get; set; }   17:     public virtual TextWriter         Writer { get; set; }   18: }   19:    20: public abstract class HttpResponseBase   21: {   22:     //其它成员   23:     public virtual TextWriter Output { get; set; }   24: }     1: public interface IViewEngine    2: {       3:     ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);    4:     ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);    5:     void ReleaseView(ControllerContext controllerContext, IView view);    6: } 1: public class ViewEngineResult    2: {       3:     public ViewEngineResult(IEnumerable<string> searchedLocations);    4:     public ViewEngineResult(IView view, IViewEngine viewEngine);    5:       6:     public IEnumerable<string> SearchedLocations { get; }    7:     public IView               View { get; }    8:     public IViewEngine         ViewEngine { get; }    9: }

 

1: public class ViewResult : ViewResultBase    2: {       3:     protected override ViewEngineResult FindView(ControllerContext context);    4:     public string MasterName { get; set; }    5: }    6:     7: public abstract class ViewResultBase : ActionResult    8: {      9:     public override void ExecuteResult(ControllerContext context);   10:     protected abstract ViewEngineResult FindView(ControllerContext context);   11:     12:     public object                     Model { get; }   13:     public TempDataDictionary         TempData { get; set; }      14:     [Dynamic]   15:     public object                     ViewBag { [return: Dynamic] get; }   16:     public ViewDataDictionary         ViewData { get; set; }     17:     public string                     ViewName { get; set; }   18:     public ViewEngineCollection       ViewEngineCollection { get; set; }   19:     public IView                      View { get; set; }   20: }

 

(參考引用:http://www.cnblogs.com/artech/archive/2012/08/22/view-engine-01.html)

 

自己定义的View以及相关的Viewengine,參考例如以下:

public class StaticFileView:IView    2: {    3:     public string FileName { get; private set; }    4:     public StaticFileView(string fileName)    5:     {    6:         this.FileName = fileName;    7:     }    8:     public void Render(ViewContext viewContext, TextWriter writer)    9:     {   10:         byte[] buffer;   11:         using (FileStream fs = new FileStream(this.FileName, FileMode.Open))   12:         {   13:             buffer = new byte[fs.Length];   14:             fs.Read(buffer, 0, buffer.Length);   15:         }   16:         writer.Write(Encoding.UTF8.GetString(buffer));   17:     }   18: } internal class ViewEngineResultCacheKey    2: {    3:     public string ControllerName { get; private set; }    4:     public string ViewName { get; private set; }    5:     6:     public ViewEngineResultCacheKey(string controllerName, string viewName)    7:     {    8:         this.ControllerName = controllerName ??

string.Empty;

   9:         this.ViewName = viewName ?? string.Empty;   10:     }   11:     public override int GetHashCode()   12:     {   13:         return this.ControllerName.ToLower().GetHashCode() ^ this.ViewName.ToLower().GetHashCode();   14:     }   15:    16:     public override bool Equals(object obj)   17:     {   18:         ViewEngineResultCacheKey key = obj as ViewEngineResultCacheKey;   19:         if (null == key)   20:         {   21:             return false;   22:         }   23:         return key.GetHashCode() == this.GetHashCode();   24:     }   25: } 1: public class StaticFileViewEngine : IViewEngine    2: {    3:     private Dictionary<ViewEngineResultCacheKey, ViewEngineResult> viewEngineResults = new Dictionary<ViewEngineResultCacheKey, ViewEngineResult>();    4:     private object syncHelper = new object();    5:     public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)    6:     {    7:         return this.FindView(controllerContext, partialViewName, null, useCache);    8:     }    9:    10:     public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)   11:     {   12:         string controllerName = controllerContext.RouteData.GetRequiredString("controller");   13:         ViewEngineResultCacheKey key = new ViewEngineResultCacheKey(controllerName, viewName);   14:         ViewEngineResult result;   15:         if (!useCache)   16:         {   17:             result = InternalFindView(controllerContext, viewName, controllerName);   18:             viewEngineResults[key] = result;   19:             return result;   20:         }   21:         if(viewEngineResults.TryGetValue(key, out result))   22:         {   23:             return result;   24:         }   25:         lock (syncHelper)   26:         {   27:             if (viewEngineResults.TryGetValue(key, out result))   28:             {   29:                 return result;   30:             }   31:    32:             result = InternalFindView(controllerContext, viewName, controllerName);   33:             viewEngineResults[key] = result;   34:             return result;   35:         }               36:     }   37:    38:     private ViewEngineResult InternalFindView(ControllerContext controllerContext, string viewName, string controllerName)   39:     {   40:         string[] searchLocations = new string[]   41:         {   42:             string.Format( "~/views/{0}/{1}.shtml", controllerName, viewName),   43:             string.Format( "~/views/Shared/{0}.shtml", viewName)   44:         };   45:    46:         string fileName = controllerContext.HttpContext.Request.MapPath(searchLocations[0]);   47:         if (File.Exists(fileName))   48:         {   49:             return new ViewEngineResult(new StaticFileView(fileName), this);   50:         }   51:         fileName = string.Format(@"\views\Shared\{0}.shtml", viewName);   52:         if (File.Exists(fileName))   53:         {   54:             return new ViewEngineResult(new StaticFileView(fileName), this);   55:         }   56:         return new ViewEngineResult(searchLocations);   57:     }   58:    59:     public void ReleaseView(ControllerContext controllerContext, IView view)   60:     { }   61: } 1: public class MvcApplication : System.Web.HttpApplication    2: {    3:     protected void Application_Start()    4:     {    5:         //其它操作    6:         ViewEngines.Engines.Insert(0, new StaticFileViewEngine());    7:     }    8: } 1: public class HomeController : Controller    2: {    3:     public ActionResult ShowNonExistentView()    4:     {    5:         return View("NonExistentView");    6:     }    7:     8:     public ActionResult ShowStaticFileView()    9:     {   10:         return View();   11:     }   12: }

我们为Action方法ShowStaticFileView创建一个StaticFileView类型的View文件ShowStaticFileView.shtml(该View文件保存在“~/Views/Home”文件夹下,扩展名不是.cshtml,而是shtml),其内容就是例如以下一段完整的HTML。

   1: <!DOCTYPE html>    2: <html>    3:     <head>    4:         <title>Static File View</title>    5:     </head>    6:     <body>    7:         这是一个自己定义的StaticFileView。    8:     </body>    9: </html>

 

(參考引用:http://www.cnblogs.com/artech/archive/2012/08/23/view-engine-02.html)

版权声明:本文博主原创文章,博客,未经同意不得转载。

转载于:https://www.cnblogs.com/bhlsheji/p/4852224.html

最新回复(0)