Controller 提供了众多的方法让我们返回各种类型的 ActionResult。

1. View

最常用的一种,用于返回一个 "标准" 页面。

protected internal virtual ViewResult View(string viewName, string masterName, object model){    if (model != null)    {        base.ViewData.Model = model;    }    return new ViewResult     {         ViewName = viewName,         MasterName = masterName,         ViewData = base.ViewData,         TempData = base.TempData     };}public class ViewResult : ViewResultBase{    protected override ViewEngineResult FindView(ControllerContext context)    {        ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);        if (result.View != null)        {            return result;        }        ...    }}

这个页面默认是 ViewPage,也可以是我们自己定义的其它模板引擎页面。

MVC 还提供了强类型的 ViewPage<TModel>。

public class User{    public string Name { get; set; }    public int Age { get; set; }}public class TestController : Controller{    public ActionResult Index()    {        ViewData["message"] = "Hello, World!";        var model = new User { Name = "Tom", Age = 13 };        return View(model);    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Learn.MVC.Controllers.User>" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title></head><body>    Name: <%= Model.Name %>; Age: <%= Model.Age %></body></html>

在 WebForm 时代,我们就已经习惯了将一个页面分解成多个 UserControl,现在我们依然可以这么做。htmlHelper 专门提供了 RenderPartial 扩展方法,从当前视图目录(Views\xxx)下载入 .ascx 页面。

public static class RenderPartialExtensions{    public static void RenderPartial(this HtmlHelper htmlHelper, partialViewName, model, viewData)    {        htmlHelper.RenderPartialInternal(partialViewName, viewData, model, ViewEngines.Engines);    }}public class HtmlHelper{    internal virtual void RenderPartialInternal(string partialViewName, ViewDataDictionary viewData,         object model, ViewEngineCollection viewEngineCollection)    {        ...        ViewDataDictionary newViewData = null;        if (model == null)        {            if (viewData == null)                newViewData = new ViewDataDictionary(ViewData);            else                newViewData = new ViewDataDictionary(viewData);        }        else        {            if (viewData == null)                newViewData = new ViewDataDictionary(model);            else                newViewData = new ViewDataDictionary(viewData) { Model = model };        }        ViewContext newViewContext = new ViewContext(ViewContext, ViewContext.View,             newViewData, ViewContext.TempData);        IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);        view.Render(newViewContext, ViewContext.HttpContext.Response.Output);    }    internal static IView FindPartialView(viewContext, partialViewName, viewEngineCollection)    {        ViewEngineResult result = viewEngineCollection.FindPartialView(viewContext, partialViewName);        if (result.View != null)        {            return result.View;        }        ...    }}

RenderPartialInternal 调用 FindParitialView 从视图引擎中载入 .ascx,同时将当前的环境参数传递给它。也就是说 RenderPartial 只是一种视图级别的行为,并不会再次触发 Controller Action 操作,这点要和 Controller.PartialView() 区别开来。

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Learn.MVC.Controllers.User>" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title></head><body>    Name: <%= Model.Name %>; Age: <%= Model.Age %>    <br />    <% Html.RenderPartial("Part"); %></body></html>

Part.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Learn.MVC.Controllers.User>" %><%= ViewData["message"] %> <br /><%= Model.Name %>

2. Content

Content 用于输出(Response.Write) "静态" 片段。

protected internal virtual ContentResult Content(content, contentType, contentEncoding){    return new ContentResult    {        Content = content,        ContentType = contentType,        ContentEncoding = contentEncoding    };}public class ContentResult : ActionResult{    public string Content { get; set; }            public override void ExecuteResult(ControllerContext context)    {        ...        HttpResponseBase response = context.HttpContext.Response;        if (!String.IsNullOrEmpty(ContentType))        {            response.ContentType = ContentType;        }        if (ContentEncoding != null)        {            response.ContentEncoding = ContentEncoding;        }        if (Content != null)        {            response.Write(Content);        }    }}

看看和 jQuery 的配合使用。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult Part()    {        return Content("<a href=\"http://www.rainsts.net\">Q.yuhen</a>");    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title>    <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.min.js" type="text/javascript"></script>    <script type="text/javascript">        $(function()        {            $("#div1").load("/test/part");        });    </script></head><body>    <div id="div1">    </div></body></html>

3. PartialView

Controller.PartialView() 和 HtmlHelper.RenderPartial() 的不同之处在于前者是再次执行 ActionInvoke 并返回一个 ActionResult 结果,后者只是使用现有的 ViewContext 显示一个视图片段。而与 Controller.Content() 的区别是 PartialView() 使用视图引擎输出一个 "动态" 的 ascx 结果。

protected internal virtual PartialViewResult PartialView(string viewName, object model){    if (model != null)    {        ViewData.Model = model;    }    return new PartialViewResult    {        ViewName = viewName,        ViewData = ViewData,        TempData = TempData    };}public class PartialViewResult : ViewResultBase{    protected override ViewEngineResult FindView(ControllerContext context)    {        ViewEngineResult result = ViewEngineCollection.FindPartialView(context, ViewName);        if (result.View != null)        {            return result;        }                ...    }}

和 Content() 一样,我们通常将其和 jQuery 等 Ajax 框架配合使用。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult Part()    {        ViewData["time"] = DateTime.Now;        var model = new User { Name = "Tom", Age = 13 };        return PartialView(model);    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title>    <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.min.js" type="text/javascript"></script>    <script type="text/javascript">        $(function()        {            $("#div1").load("/test/part");        });    </script></head><body>    <div id="div1">    </div></body></html>

Part.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Learn.MVC.Controllers.User>" %><%= ViewData["time"] %> <br /><%= Model.Name %>; <%= Model.Age %>

4. Redirect / RedirectToAction / RedirectToRoute

Controller 提供了几种方式,让我们在不同的 Action 之间进行跳转。

public class MvcApplication : System.Web.HttpApplication{    public static void RegisterRoutes(RouteCollection routes)    {        ...        routes.MapRoute        (            "Test2",            "Test/T2/{name}/{age}",            new { controller = "Test", action = "T2", name = "", age = 0 }        );        ...    }}

方法1:

Redirect() 直接用 Response.Redirect() 完成 url 跳转。

public class TestController : Controller{    public ActionResult Index()    {        return Redirect("/Test/T2/Tom/23");    }    public ActionResult T2(User user)    {        return Content(user.Name);    }}

相关细节:

protected internal virtual RedirectResult Redirect(string url){    ...    return new RedirectResult(url);}public class RedirectResult : ActionResult{    public override void ExecuteResult(ControllerContext context)    {        ...        string destinationUrl = UrlHelper.Content(Url, context.HttpContext);        context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);    }}

方法2:

RedirectToAction() 直接使用 Action Name 进行跳转。

public class TestController : Controller{    public ActionResult Index()    {        return RedirectToAction("T2", new { name = "Tom", age = 23 });    }    public ActionResult T2(User user)    {        return Content(user.Name);    }}

如果目标 Action 不在当前 Controller 类,则可以指定目标 Controller Name。

return RedirectToAction("T2", new { controller="Test2", name = "Tom", age = 23 });

相关细节:

protected internal virtual RedirectToRouteResult RedirectToAction(string actionName,     string controllerName, RouteValueDictionary routeValues){    RouteValueDictionary mergedRouteValues;    if (RouteData == null)    {        mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName,             controllerName, null, routeValues, true /* includeImplicitMvcValues */);    }    else    {        mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName,             controllerName, RouteData.Values, routeValues, true /* includeImplicitMvcValues */);    }    return new RedirectToRouteResult(mergedRouteValues);}public class RedirectToRouteResult : ActionResult{    public override void ExecuteResult(ControllerContext context)    {        ...        string destinationUrl = UrlHelper.GenerateUrl(RouteName, null /* actionName */,             null /* controllerName */, RouteValues, Routes, context.RequestContext,             false /* includeImplicitMvcValues */);        ...        context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);    }}

可以看到 RedirectToRouteResult.ExecuteResult 中使用 Route 相关信息拼接成目标 Url 后进行跳转。

方法3:

RedirectToRoute() 则是直接用 MapRoute 时定义的 Route Name 进行跳转。

public class TestController : Controller{    public ActionResult Index()    {        return RedirectToRoute("Test2", new { name = "Tom", age = 23 });    }}

相关细节:

protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues){    return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues));}

执行过程和 RedirectToAction() 相同。

5. Json

Json() 在编写 Ajax 时非常有用,可以将 Entity 等对象序列化成 JSON 格式供 Javascript 使用。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult GetUser(string name)    {        var user = new User { Name = name, Age = 23 };        return Json(user);    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title>    <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.min.js" type="text/javascript"></script>    <script type="text/javascript">        $(function()        {            $("#btnTest").click(function()            {                $.getJSON                (                    "/Test/GetUser",                     { name: "Tom" },                     function(json)                    {                        alert(json.Name + ";" + json.Age);                    }                );            });        });    </script></head><body>    <input type="button" id="btnTest" value="Test" /></body></html>

很好用,不是吗?看看相关细节。

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding){    return new JsonResult    {        Data = data,        ContentType = contentType,        ContentEncoding = contentEncoding    };}public class JsonResult : ActionResult{    public override void ExecuteResult(ControllerContext context)    {        ...        if (Data != null)        {            JavaScriptSerializer serializer = new JavaScriptSerializer();            response.Write(serializer.Serialize(Data));        }    }}

使用 System.Web.Script.Serialization.JavaScriptSerializer 完成 JSON 序列化操作,也就是说我们还可以用 ScriptIgnoreAttribute 排除某些属性。

6. Javascript

某些时候,我们需要根据一些逻辑判断来载入执行不同的 Javascript 代码。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult GetJs(int id)    {        switch (id)        {            case 1:                return JavaScript("alert('Hello, C#!');");                        case 2:                return JavaScript("alert('Hello, MVC!');");                        default:                return null;        }    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title>    <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.min.js" type="text/javascript"></script>    <script type="text/javascript">        $(function()        {            $("#btnTest").click(function()            {                var id = $("#txtId").val();                $.getScript("/Test/GetJs/" + id);            });        });    </script></head><body>    <input type="text" id="txtId" value="1" />    <input type="button" id="btnTest" value="Test" /></body></html>

只是这种做法,似乎将 View 和 Controller 的耦合加大了…… 还不如直接用 Javascript 来处理这些。

protected internal virtual JavaScriptResult JavaScript(string script){    return new JavaScriptResult { Script = script };}public class JavaScriptResult : ActionResult{    public override void ExecuteResult(ControllerContext context)    {        ...        HttpResponseBase response = context.HttpContext.Response;        response.ContentType = "application/x-javascript";        if (Script != null)        {            response.Write(Script);        }    }}

7. File (Download / Upload)

File() 提供了 Download 功能。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult Download(int id)    {        var filename = String.Format("~/Content/Download/{0}.rar", id);        var fileDownloadName = String.Format("{0}.rar", id);        return File(filename, "application/octet-stream", fileDownloadName);    }}

当我们在浏览器请求 "/Test/Download/1" 是就会打开下载窗口,同时给出了保存文件名。

protected internal virtual FileContentResult File(byte[] fileContents, contentType, fileDownloadName){    return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName };}public abstract class FileResult : ActionResult{    public override void ExecuteResult(ControllerContext context)    {        ...        HttpResponseBase response = context.HttpContext.Response;        response.ContentType = ContentType;        ...        WriteFile(response);    }    protected abstract void WriteFile(HttpResponseBase response);}public class FileContentResult : FileResult{    protected override void WriteFile(HttpResponseBase response)    {        response.OutputStream.Write(FileContents, 0, FileContents.Length);    }}

文件上传是另一个常用的 Web 应用。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult Upload(HttpPostedFileBase file)    {        var filename = Server.MapPath("~/Content/Upload/" + Path.GetFileName(file.FileName));        file.SaveAs(filename);        return null;    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title></head><body>    <form action="/Test/Upload" enctype="multipart/form-data" method="post">        <input type="file" name="file" />        <input type="submit" name="upload" />    </form></body></html>

MVC 提供了一个 HttpPostedFileBaseModelBinder 将 Request.Files 的信息直接映射给 Action 同名参数。

public class HttpPostedFileBaseModelBinder : IModelBinder{    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)    {        ...        HttpPostedFileBase theFile = controllerContext.HttpContext.Request.Files[bindingContext.ModelName];        // case 1: there was no <input type="file" ... /> element in the post        if (theFile == null)        {            return null;        }        // case 2: there was an <input type="file" ... /> element in the post, but it was left blank        if (theFile.ContentLength == 0 && String.IsNullOrEmpty(theFile.FileName))        {            return null;        }        // case 3: the file was posted        return theFile;    }}

看看一次上传多个文件的演示。

public class TestController : Controller{    public ActionResult Index()    {        return View();    }    public ActionResult Upload(HttpPostedFileBase file1, HttpPostedFileBase file2)    {        var html = String.Format("{0}:{1}<br />{2}:{3}",             file1.FileName, file1.InputStream.Length,            file2.FileName, file2.InputStream.Length);        return Content(html);    }}

Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title>Index</title></head><body>    <form action="/Test/Upload" enctype="multipart/form-data" method="post">        <input type="file" name="file1" />        <input type="file" name="file2" />        <input type="submit" name="upload" />    </form></body></html>
[最后修改

转载于:https://www.cnblogs.com/dudu837/archive/2010/11/03/1868176.html

ASP.NET MVC . Controller相关推荐

  1. ASP.NET MVC Controller激活系统详解:默认实现

    Controller激活系统最终通过注册的ControllerFactory创建相应的Conroller对象,如果没有对ControllerFactory类型或者类型进行显式注册(通过调用当前Cont ...

  2. .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  3. ASP.NET MVC Controller Overview摘录

    原文URL:http://www.asp.net/learn/mvc/tutorial-03-cs.aspx Understanding Controllers 1. Controller定义   M ...

  4. How ASP.NET MVC Works?

    一.ASP.NET + MVC IIS与ASP.NET管道 MVC.MVP以及Model2[上篇] MVC.MVP以及Model2[下篇] ASP.NET MVC是如何运行的[1]: 建立在" ...

  5. .net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象

    原文地址:http://www.cnblogs.com/fannyatg/archive/2012/04/16/2451611.html ------------------------------- ...

  6. ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[上篇]

    Action方法的执行具有两种基本的形式,即同步执行和异步执行,而在ASP.NETMVC的整个体系中涉及到很多同步/异步的执行方式,虽然在前面相应的文章中已经对此作了相应的介绍,为了让读者对此有一个整 ...

  7. mvc移动创建oracle表,使用 ASP.NET MVC (C#)在15分钟内创建电影数据库应用程序 | Microsoft Docs...

    使用 ASP.NET MVC 在 15 分钟内创建电影数据库应用程序 (C#)Create a Movie Database Application in 15 Minutes with ASP.NE ...

  8. Professional C# 6 and .NET Core 1.0 - Chapter 41 ASP.NET MVC

    What's In This Chapter? Features of ASP.NET MVC 6 Routing Creating Controllers Creating Views Valida ...

  9. [ASP.NET MVC 小牛之路]10 - Controller 和 Action (2)

    继上一篇文章之后,本文将介绍 Controller 和 Action 的一些较高级特性,包括 Controller Factory.Action Invoker 和异步 Controller 等内容. ...

  10. 通过源代码研究ASP.NET MVC中的Controller和View(二)

    通过源代码研究ASP.NET MVC中的Controller和View(一) 在开始之前,先来温习下上一篇文章中的结论(推论): IView是所有HTML视图的抽象 ActionResult是Cont ...

最新文章

  1. 排序算法c语言和oc实现的,几种常用的排序算法,OC实现
  2. Qos和区分服务(DiffServ)
  3. 网站社区类产品管理经验
  4. 阅读Java_如何阅读 Java 开源代码?
  5. linux 创建内核线程
  6. JVM——Java对象是如何创建、存储和访问的?
  7. Spring Restful Web服务示例 - 使用JSON/Jackson和客户端程序
  8. flutter html 加载_Flutter 加载本地 HTML 文件
  9. JupterNoteBook
  10. 查询同一张表符合条件的某些数据的id拼接成一个字段返回
  11. 图片双面打印顺序混乱_为什么双面打印一面是正的一面是反的?
  12. PPT文件太大?如何压缩PPT?这几招帮你搞定
  13. 6.11编写计算正方体、圆柱体、球体的表面积和体积的类。
  14. 读《洞穴奇案》——从虐猫到禁食狗肉,自然法真的存在吗?
  15. 软件工程网络15个人阅读作业2(201521123042 姚佳希)
  16. linux内存双通道,两根内存就是双通道?太年轻
  17. java与javax有什么区别?
  18. MySQL通过命令导入导出数据
  19. uploadifive struts2实现图片上传
  20. pandas中inplace_对python pandas中 inplace 参数的理解

热门文章

  1. WebGL 绘制Line的bug(三)
  2. Java:单例模式的七种写法 (转)
  3. ife task0003学习笔记(三):JavaScript闭包
  4. Codeforces Round #288 (Div. 2)E. Arthur and Brackets
  5. 整理下常用到的css属性
  6. .net zero power toole 破解日志
  7. 序列化之Java默认序列化技术(ObjectOutputStream与ObjectInputStream)
  8. Symantec Backup Exec 2014 备份Exchange 2013之四设备初始化
  9. 应用层TCP三次握手及各种协议简介telnet【笔记】
  10. 如何查看并杀死僵尸进程?