ASP.NET MVC 中的 Action Result





5.00/5 (13投票s)
在本文中,您将学习 ASP.NET MVC 5 中关于 Action Result 的基本核心概念。希望您会喜欢。欢迎提出您的反馈意见。
引言和背景
本文将告诉您关于 ASP.NET MVC 中 Action Result 的从基础到高级的核心概念。上周,我的一位朋友问了一个问题:“为什么在 action 方法中存在 ContentResult
数据类型,它的目的是什么?” 我将本文献给他。希望他会喜欢。
将要涵盖的主题是
- 什么是
ActionResult
?- 返回内容的结果
- 重定向的结果
- 状态结果
这个问题
根据问题的第一个部分,为什么在 action 方法中存在 ContentResult
数据类型?要理解这一点,您必须了解 ASP.NET MVC 5 中的数据类型,因为 ContentResult
是一种数据类型,其基类型是 ActionResult
,因此您必须了解 ActionResult
。
让我们开始 Action Result 的学习。
操作结果
Action Result 实际上是一种数据类型。当它与 action 方法一起使用时,就称为返回类型。如您所知,action 指的是控制器的方法。所以 Action Result 是 action 执行后的结果。事实上,Action Result 是一种返回类型。这种返回类型有许多其他派生类型。首先,让我们看看 ActionResult
的基类型和派生类型。
namespace System.Web.Mvc
{
public abstract class ActionResult
{
//
// Summary:
// Initializes a new instance of the System.Web.Mvc.ActionResult class.
protected ActionResult();
}
}
正如您在 Visual Studio 中看到的,ActionResult
类型来自 System.Web.Mvc assembly
。问题是,我们无法使用 Visual Studio 的“转到定义”功能查看此程序集内部的内容。
要查看程序集内部,您可以按照下面提供的步骤下载 ILSpy,或者点击 此处 查看我名为 ILSpy.gif 的 GIF 文件。
步骤如下
- 我将为您提供下载 ILSpy 的直接链接。点击 此处。
- 如果您没有
System.Web.Mvc
程序集,则可以点击 此处 下载。 - 下载后,解压 ILSpy 并运行它。
- 点击文件(左上角)。
- 选择“打开”选项,然后打开您下载的程序集。
- 选择后,程序集将在 ILSpy 软件中加载。
- 展开程序集,您将看到
ActionResult
,也将其展开,您将看到基类型和派生类型。 - 下面图片显示了
ActionResult
的类型
现在您可以看到,ActionResult
是一个基数据类型,其派生类型包括 HttpStatusCodeResult
、JavaScriptResult
、FileResult
、ContentResult
、JsonResult
、EmptyResult
、RedirectResult
、RedirectToRouteResult
、ViewResult
。并且每个数据类型(基类型或派生类型)都应该有一个辅助方法。
当我们进入 ActionResult
时,发现它是一个 abstract
类。
namespace System.Web.Mvc
{
public abstract class ActionResult
{
//
// Summary:
// Initializes a new instance of the System.Web.Mvc.ActionResult class.
protected ActionResult();
}
}
它是一个 abstract
类,因为控制器的方法可以同时返回不同类型的数据。因此,它必须是 abstract
的,以便每个 Http 请求都能得到妥善处理。请看下面的代码
public ActionResult Index()
{
bool answer = DateTime.Now.Day + 2 == 5;
if (answer)
{
return Content("Correct");
}
else
{
return View();
}
}
如您所见,同一个 action 方法“Index
”返回两种不同的类型,分别是 Content
和 View
。所以,如果您想返回多种类型,您必须使用基类型 ActionResult
。
上述概念也回答了“何时选择基类型 ActionResult
或派生类型?”这个问题。
答案是,为特定结果选择派生类型是一种好习惯,但当您希望 action 方法返回多种类型时,您必须使用基类型 ActionResult
。
现在,重要的概念来了,派生类型有三个类别。让我们看一下。
正如您所见,ActionResult
的数据类型有三个类别
- 返回内容的结果
- 重定向的结果
- 状态结果
让我们逐一理解。
返回内容的结果
顾名思义,这些结果用于将内容返回到浏览器。有 7 种内容返回结果
ViewResult
PartialViewResult
ContentResult
EmptyResult
FileResult
JsonResult
JavaScriptResult
ViewResult
ViewResult
是一个 datatype
,负责返回 View
。让我们看一个例子。
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
}
Index 视图的代码如下
<h2> This is Index View. </h2>
如您所见上面的代码,index action 方法使用 ViewResult
类型返回 View。之后,MVC 将在 Views 文件夹的 “Home” 文件夹中查找名为 “Index
” 的 View。
输出
ViewResult
类型有趣之处在于,即使 action 方法的名称与 View 的名称不同,您也可以返回一个不同的 View
。看一个例子。
public class HomeController : Controller
{
public ViewResult Index()
{
return View(“Second View” );
}
}
您可以在下图中看到我们在 views 文件夹中有“Second View”页面
“Second View”页面的代码如下
<h2>This is Second View but having action name "Index"</h2>
如上所示,现在 MVC 将查找名为“Second View”的视图,而不是查找与 action 名称同名的视图。
输出
因此,您可以使用 ViewResult
类型调用任何其他具有不同 action 名称的视图。
PartialViewResult
这是用于返回部分视图页面而非常规视图页面的类型。看它的例子。
public class HomeController : Controller
{
public PartialViewResult Index()
{
return PartialView("Second View");
}
}
“Second View”的代码如下所示
<h2>This is Second View but having action name "Index"</h2>
输出
您可以看到,输出与上一个示例相同。但不同之处在于,这里我们看不到“© 2018 - My ASP.NET Application”这一行,因为它是来自 Layout 页面的行,由于使用了 PartialViewResult
数据类型,所以这里没有。
您可以看到,PartialViewResult
的输出与 ViewResult
相同。但是 Layout 页面的内容丢失了。这只是一个示例。这并非真实场景的示例。
现在让我们看一个有 Layout 页面的示例。创建一个名为“Student
”的新控制器和一个名为“Name
”的 action 方法,如下所示
public class StudentController : Controller
{
public PartialViewResult Name()
{
return View("_SecondView");
}
}
无需为“Name
”创建 View
。因为这里,Name
action 方法正在调用一个不同的 View
页面。请看下面的文件夹结构
创建部分视图页面的正确方法是,它应该在常规视图中使用,其名称以 _
开头,并且应该位于 Shared 文件夹中。
现在当您执行它时,您将看到相同的输出,但具有 Layout 页面的内容。请看下面的图片
所以,您可以在这里使用 PartialViewResult
datatype
。
ContentResult
ContentRresult
是一种 datatype
,负责返回内容。但有趣的是,您可以很好地控制返回的内容。我的意思是,您必须在 ContentResult
类型的“Content
”辅助方法中添加内容。在这里,您可以传递 HTML 内容、JavaScript 内容或其他任何内容。让我们通过示例来理解。
Home 控制器的代码如下
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("<h3>Zain Ul Hassan </h3>");
}
}
输出
您也可以在 Content 辅助方法中提供 MIME
(多用途互联网邮件扩展)类型,以便 MVC 在识别内容后采取适当的操作。代码如下所示
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("<h3>Zain Ul Hassan</h3>", "text/html");
}
}
输出与上面相同
您也可以提供 JavaScript 内容,它将由 ContentResult
类型返回。让我们看一个例子。
public class HomeController : Controller
{
public ContentResult Index()
{
return Content(
"<script> alert('Hi! I am Zain Ul Hassan') </script>"
);
}
}
输出将如以下所示显示一个警报
所以,您可以以上述方式使用 ContentResult
datatype
。
EmptyResult
此类型实际上用于返回空内容。但问题是,这种 EmptyResult
类型没有辅助方法。所以我们可以通过创建它的对象来使用它,如下所示
public class HomeController : Controller
{
public EmptyResult Index()
{
return new EmptyResult();
}
}
但是如果您想使用 ActionResult
,那么 MVC 将自动识别它是 EmptyResult
类型。代码如下
public class HomeController : Controller
{
public ActionResult Index()
{
return null;
}
}
所以,这就是 EmptyResult
类型的使用。
FileResult
FileResult
是一种用于将文件返回到浏览器的类型。此类型的辅助方法是 File
,并且有许多重载。因此,如果我们使用以下重载并仅指定文件的 URL 和 MIME(多用途互联网邮件扩展)类型,那么我们应该在浏览器中看到文件的内容。让我们看一个例子。
我们使用的重载是
protected internal FilePathResult File(string fileName, string contentType);
使用 FileResult
类型的 action 方法的代码如下
public class HomeController : Controller
{
public FileResult Index()
{
return File("~/Files/text.txt", "text/plain");
}
}
该文件包含在项目中,并且 URL 如上所示。输出如下
现在,如果您想以字节数组的形式返回文件,那么您需要使用以下代码
public class HomeController : Controller
{
public FileResult Index()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(Server.MapPath("~/Files/text.txt"));
return File(fileBytes, "text/plain");
}
}
输出与上面相同
现在,如果您不想在浏览器中显示文件,而是希望提示下载您的文件,那么您需要使用文件辅助方法的以下重载
protected internal virtual FilePathResult File
(string fileName, string contentType, string fileDownloadName);
使用 FileResult
的 action 代码如下
public class HomeController : Controller
{
public FileResult Index()
{
return File(Url.Content("~/Files/text.txt"), "text/plain", "testFile.txt");
}
}
输出
因此,这就是 FileResult
在不同场景下的使用。
JsonResult
这是 ActionResult
的派生类型,用于表示 JSON
数据。要查看如何将任何数据 JSON 化,您可以查看下面的代码
public JsonResult Index()
{
return Json(new { Name = "Zain Ul Hassan", ID = 1 });
}
其输出如下
执行上述代码后,您将收到此错误。现在让我们理解一下问题所在。
如您所知,JSON
包含您编码的宝贵数据,因此 MVC 会严格阻止通过 GET
请求共享信息。事实上,MVC 正在试图阻止您进行 JSON 劫持。
因此,如果您想通过 GET
请求共享信息,那么您必须使用以下代码
public JsonResult Index()
{
return Json(new { Name = "Zain Ul Hassan", ID = 1 }, JsonRequestBehavior.AllowGet);
}
输出将变为
因此,JsonRequestBehavior.AllowGet
允许 MVC 通过 GET
请求共享信息。但是,当您确定您的 JSON 数据不包含敏感数据时,您应该使用上述功能。
JavaScriptResult
此派生类型用于从控制器返回 JavaScript 代码。当它执行时,我们会看到我们在控制器 action 方法中提到的 JavaScript 代码。有关详细信息,请看一个例子
public JavaScriptResult Index()
{
return JavaScript("alert('Zain Ul hassan')");
}
名为 Index
的 View
具有以下代码
<script type="text/javascript" src="@Url.Action("Index")"></script>
输出如下
重定向的结果
此类型的 ActionResult
用于重定向目的,您将在此处看到示例。有 2 种重定向结果
- RedirectResult
- 重定向到 Action 结果
重定向结果
如果您使用此类型,它将重定向到您指定的 URL。示例如下
public RedirectResult Index()
{
return Redirect("https://www.c-sharpcorner.com/members/zain-ul-hassan2");
}
在输出中,将打开指定的 URL,如下所示
RedirectionResult
更适合重定向到实时 URL,也就是说,将其用于重定向到当前应用程序的本地页面不是最佳实践。为此,请使用下面解释的 RedirectionToRouteResult
。
重定向到路由结果
它负责重定向到应用程序内的操作。它有很多辅助方法,实际上是重载的。我们使用 RedirectToRoute
,它会将我们重定向到指定控制器内的操作。让我们看一个例子。
public RedirectToRouteResult Index()
{
return RedirectToRoute(new { controller = "Student", action = "Name" });
}
我们在 Student
控制器中有 Name
action 方法,Name
视图的代码如下
<h2>Redirection Successfull</h2>
所以输出如下
现在,如果您在同一个控制器中,并且不想指定控制器名称,那么更好的选择是 RedirectToAction
辅助方法。请看下面的代码
public class HomeController : Controller
{
public RedirectToRouteResult Index()
{
return RedirectToAction("SecondIndex");
}
public ActionResult SecondIndex()
{
return View();
}
}
SecondIndex
的视图代码如下
<h3>This is the SecondIndex of the same controller named as "Home"</h3>
输出如下
正如您所见,辅助方法 RedirectToAction
用于调用当前控制器内的操作,如果 MVC 找不到它,将发生 404 错误。RedirectToAction
有许多重载,您可以指定控制器、操作、路由值等。因此,您必须根据您的场景使用。
状态结果
它的职责是向浏览器发送状态代码。此集合有三种类型,如下所述
HttpStatusCodeResult
HttpUnauthorizedResult
HttpNotFoundResult
HttpStatusCodeResult
此类型用于向浏览器发送 HTTP 状态代码。看它的例子。
public HttpStatusCodeResult Index()
{
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
}
输出如下
您可以使用 HttpStatusCodeResult
类型的重载版本显示您自己的消息。
public HttpStatusCodeResult Index()
{
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized, "Sorry! You don't have access.");
}
输出
这里,HttpStatusCode
来自 System.Net
命名空间。并包含所有 HTTP 状态代码。
如果您不想使用 System.Net
命名空间,那么 HttpStatusCodeResult
有一个重载,其输出与上面相同。请看下面的代码
public HttpStatusCodeResult Index()
{
return new HttpUnauthorizedResult("Sorry! You don't have access.");
}
输出与上面相同,但代码看起来更具可读性。
HttpNotFoundResult
这也是 HttpStatusCodeResult
的一个重载,但它有一个辅助方法,我们不必创建一个匿名对象。代码如下
public HttpNotFoundResult Index()
{
return HttpNotFound("Sorry! You don't have access.");
}
输出
摘要
这些是理解 Action Results 的基本核心内容。如果您有任何疑问,请随时在下面的评论中与我联系。另外,请提供反馈,无论是积极的还是消极的——这将帮助我改进我的文章并提高我分享知识的热情。