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,
public class FileResult : ActionResult { public FileResult(string fileDownloadName, string filePath, string contentType) { FileDownloadName = fileDownloadName; FilePath = filePath; ContentType = contentType; } public string ContentType { get; private set; } public string FileDownloadName { get; private set; } public string FilePath { get; private set; } public async override Task ExecuteResultAsync(ActionContext context) { var response = context.HttpContext.Response; response.ContentType = ContentType; context.HttpContext.Response.Headers.Add("Content-Disposition", new[] { "attachment; filename=" + FileDownloadName }); using (var fileStream = new FileStream(FilePath, FileMode.Open)) { await fileStream.CopyToAsync(context.HttpContext.Response.Body); } } }
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,
public class HomeController : Controller { private readonly IApplicationEnvironment _appEnvironment; public HomeController(IApplicationEnvironment appEnvironment) { _appEnvironment = appEnvironment; } public virtual FileResult File(string fileDownloadName, string filePath, string contentType = "application/octet-stream") { return new FileResult(fileDownloadName, filePath, contentType); } public ActionResult ReadMe() { return File("readme.txt", _appEnvironment.ApplicationBasePath + "\\a.txt"); } public IActionResult About() { return File("about.xml", _appEnvironment.ApplicationBasePath + "\\a.xml", "application/xml"); } }
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.