了解.net mvc实现原理ActionResult/View
类名 | 抽象类 | 父类 | 功能 |
ActionResult | abstract | Object | 顶层父类 |
ContentResult | 根据内容的类型和编码,数据内容.通过Controller的Content方法返回 | ||
EmptyResult | 返回空结果 | ||
FileResult | abstract | 写入文件内容,具体的写入方式在派生类中. | |
FileContentResult | FileResult | 通过 文件byte[] 写入Response 返回客户端,Controller的File方法 | |
FilePathResult | FileResult | 通过 文件路径 写入Response 返回客户端,Controller的File方法 | |
FileStreamResult | FileResult | 通过 Stream 写入Response 返回客户端,Controller的File方法 | |
HttpUnauthorizedResult | 抛出401错误 | ||
JavaScriptResult | 返回javascript文件 | ||
JsonResult | 返回Json格式的数据 | ||
RedirectResult | 使用Response.Redirect重定向页面 | ||
RedirectToRouteResult | 根据Route规则重定向页面 | ||
ViewResultBase | abstract | 调用IView.Render() 返回视图,两个常用属性ViewData,TempData | |
PartialViewResult | ViewResultBase | 调用父类ViewResultBase
的ExecuteResult方法. 重写了父类的FindView方法. 寻找用户控件.ascx文件 | |
ViewResult | ViewResultBase |
调用父类ViewResultBase
的ExecuteResult方法. Controller的View()方法默认封装ViewResult返回结果 |
public ActionResult ShowContent() { return Content("测试ContentResult方法"); //默认封装ContentResult文本返回 } public ActionResult Index(UserVO userVo) { return View(); //默认封装ViewResult返回 } public ActionResult DownLoadFile(string fileName) { return File(Server.MapPath(@"/Images/view.jpg"), @"image/gif"); } public ActionResult ToOther(string fileName) { return Redirect(@"http://localhost:1847/Menu/ShowContent"); }
//1--------------------------------- protected virtual ResultExecutedContext InvokeActionResultWithFilters(ControllerContext controllerContext, IList<IResultFilter> filters, ActionResult actionResult) { ResultExecutingContext preContext = new ResultExecutingContext(controllerContext, actionResult); //InvokeActionResult 做为委托被前置与后置包围了 Func<ResultExecutedContext> continuation = delegate { InvokeActionResult(controllerContext, actionResult); return new ResultExecutedContext(controllerContext, actionResult, false /* canceled */, null /* exception */); }; // need to reverse the filter list because the continuations are built up backward Func<ResultExecutedContext> thunk = filters.Reverse().Aggregate(continuation, (next, filter) => () => InvokeActionResultFilter(filter, preContext, next)); return thunk(); } //2-------------------------------------------- internal static ResultExecutedContext InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func<ResultExecutedContext> continuation) { filter.OnResultExecuting(preContext); //前置拦截---------------------------------------- if (preContext.Cancel) { return new ResultExecutedContext(preContext, preContext.Result, true /* canceled */, null /* exception */); } bool wasError = false; ResultExecutedContext postContext = null; try { postContext = continuation(); //ActionResult的ExecuteResult的调用环节------------------------------------------ } catch (ThreadAbortException) { // This type of exception occurs as a result of Response.Redirect(), but we special-case so that // the filters don‘t see this as an error. postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, null /* exception */); filter.OnResultExecuted(postContext); //出错了,后置拦截---------------------------------- throw; } catch (Exception ex) { wasError = true; postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, ex); filter.OnResultExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnResultExecuted(postContext); //后置拦截---------------------------------------------- } return postContext; } //3------------------------------------------------------------------ protected virtual void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) { actionResult.ExecuteResult(controllerContext); }
ublic override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } HttpResponseBase response = context.HttpContext.Response; response.ContentType = ContentType; if (!String.IsNullOrEmpty(FileDownloadName)) { // From RFC 2183, Sec. 2.3: // The sender may want to suggest a filename to be used if the entity is // detached and stored in a separate file. If the receiving MUA writes // the entity to a file, the suggested filename should be used as a // basis for the actual filename, where possible. string headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName); context.HttpContext.Response.AddHeader("Content-Disposition", headerValue); } WriteFile(response); }
protected override void WriteFile(HttpResponseBase response) { // grab chunks of data and write to the output stream Stream outputStream = response.OutputStream; using (FileStream) { byte[] buffer = new byte[_bufferSize]; while (true) { int bytesRead = FileStream.Read(buffer, 0, _bufferSize); if (bytesRead == 0) { // no more data break; } outputStream.Write(buffer, 0, bytesRead); } } }
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 = result.View; } TextWriter writer = context.HttpContext.Response.Output; ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer); View.Render(viewContext, writer); if (result != null) { result.ViewEngine.ReleaseView(context, View); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。