Custom ActionResult in ASP.NET Core and MVC 6
Introduction:
ActionResult in ASP.NET Core has been improved because it can be now asynchronous. Means action result now have ActionResult.ExecuteResultAsync in addition to ActionResult.ExecuteResult. Infect IActionResult only have ExecuteResultAsync. So, we have now option to create custom action result with async support. In this article, I will show how to create a custom ActionResult with async support in ASP.NET Core.
Description:
Currently, ASP.NET Core is missing file action result(it will be there for sure, AFAIK). Here is, how we can create a simple custom async action result,
01 |
public
class
FileResult : ActionResult
|
02 |
{
|
03 |
public
FileResult(string
fileDownloadName, string
filePath, string
contentType)
|
04 |
{
|
05 |
FileDownloadName = fileDownloadName;
|
06 |
FilePath = filePath;
|
07 |
ContentType = contentType;
|
08 |
}
|
09 |
10 |
public
string
ContentType { get; private
set; }
|
11 |
public
string
FileDownloadName { get; private
set; }
|
12 |
public
string
FilePath { get; private
set; }
|
13 |
14 |
public
async override
Task ExecuteResultAsync(ActionContext
context)
|
15 |
{
|
16 |
var response =
context.HttpContext.Response;
|
17 |
response.ContentType = ContentType;
|
18 |
context.HttpContext.Response.Headers.Add("Content-Disposition", new[] { "attachment; filename="
+ FileDownloadName });
|
19 |
using
(var fileStream = new
FileStream(FilePath, FileMode.Open))
|
20 |
{
|
21 |
await
fileStream.CopyToAsync(context.HttpContext.Response.Body);
|
22 |
}
|
23 |
}
|
24 |
}
|
Here I am overriding ExecuteResultAsync and using famous CopyToAsync method to copy the file contents to response body. Here is how we can use this custom action result in our controller,
01 |
public
class
HomeController : Controller
|
02 |
{
|
03 |
private
readonly
IApplicationEnvironment
_appEnvironment;
|
04 |
05 |
public
HomeController(IApplicationEnvironment
appEnvironment)
|
06 |
{
|
07 |
_appEnvironment = appEnvironment;
|
08 |
}
|
09 |
10 |
public
virtual
FileResult File(string
fileDownloadName, string
filePath, string
contentType = "application/octet-stream")
|
11 |
{
|
12 |
return
new
FileResult(fileDownloadName, filePath,
contentType);
|
13 |
}
|
14 |
15 |
public
ActionResult ReadMe()
|
16 |
{
|
17 |
return
File("readme.txt", _appEnvironment.ApplicationBasePath + "\\a.txt");
|
18 |
}
|
19 |
20 |
public
IActionResult About()
|
21 |
{
|
22 |
return
File("about.xml", _appEnvironment.ApplicationBasePath + "\\a.xml", "application/xml");
|
23 |
}
|
24 |
}
|
Note that I am using IApplicationEnvironment to get the application base path because there is no Server.MapPath method in Core.
Update: File action result is now available with this commit.
Summary:
We have now async action result support in ASP.NET Core. In this article, I showed you how to create a custom async result in ASP.NET Core.