預設建立的專案可以看到每個action 回傳型別都為一個IActionResult的interface,每一個回傳型別都會去實作該介面,有泛型意味。

ContentResult

可以用於指定一班文字回傳或者不同MIME型態的內文

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Net5AppDiffAction.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction.Controllers
    public class HomeController : Controller
        private readonly ILogger<HomeController> _logger;
        public HomeController(ILogger<HomeController> logger)
            _logger = logger;
        public IActionResult Index()
            return View();
        public IActionResult Privacy()
            return View();
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        public ContentResult GreetUser_GeneralStr()
            return Content("Hello world from .net core mvc");
        public ContentResult GreetUser_HTML()
            return Content("<div><b>Hello world from .net core mvc</b></div>","text/html");
        public ContentResult GreetUser_XML()
            return Content("<div><b>Hello world from .net core mvc</b></div>", "text/xml");

ViewResult
回傳一個畫面

public ViewResult TodoList()
    ViewBag.Message = "Todo List test";
    return View();

RedirectResult

有分兩種一般跳轉(status code:302)
跟永久跳轉(status code:301)

public RedirectResult GotoURL()
    return Redirect("http://www.google.com"); //HTTP status code : 302
public RedirectResult GotoURLPermanently()
    return RedirectPermanent("http://www.google.com"); //HTTP status code : 301

永久跳轉(status code:301)
通常若是要轉向到既有的檔案或自己站內的頁面
會建議用永久跳轉,有助於SEO成效。
如果資源已被永久刪除,將不再是先前的位置訪問。大部分Browser
都會緩存此響應並自動執行重定向,而無需再次請求原始資源。

一般跳轉(status code:302)

若想驗證回傳的status code可以下載Fiddler來自行測試

當Press Enter後即可從左側觀察的到status code回傳對應結果

RedirectToActionResult

跳轉到指定的action可傳相應的參數

public ViewResult TodoList(string Message = "Default Message for TodoList Test")
    ViewBag.Message = Message;
    return View();
public RedirectToActionResult GotoContactsAction()
    return RedirectToAction("TodoList", new { Message = "I am coming from a different action..." });

RedirectToRouteResult

藉由route的跳轉

在startup.cs中做一些route的設置修改

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
            services.AddControllersWithViews();
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
                endpoints.MapControllerRoute(
                    name: "TodoListRoute",
                    pattern: "GotoAbout",
                    defaults: new { controller = "Home", action = "TodoList" });
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");

這裡在HomeController.cs新增的這個action就是去透過指定route來做相應跳轉

public RedirectToRouteResult GotoAbout()
    return (RedirectToRoute("TodoListRoute"));

這裡要注意各自對應參數要一致

FileResult

用於文檔下載

public FileResult DownloadFile()
    return File("/css/site.css","text/plain","download_newsite.css");
public FileResult ShowLogo()
    return File("./Images/logo.png","images/png");

FileContentResult

和FileResult不同點在於傳入參數要是binary型態
且結果不會下載而是直接呈現在網頁上

這裡準備預設./wwwroot/css/site.css和./Data/Products.xml兩種檔案

測試的action

public FileContentResult DownloadContent_css()
    var testFile = System.IO.File.ReadAllBytes("./wwwroot/css/site.css");
    return new FileContentResult(testFile,"text/plain");
public FileContentResult DownloadContent_xml()
    var testFile = System.IO.File.ReadAllBytes("./Data/Products.xml");
    return new FileContentResult(testFile, "text/xml");

FileStreamResult

把文本內容透過stream形式寫入來做檔案下載

public FileStreamResult CreateFile()
    var stream = new System.IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes("Hello FileStreamResult"));
    return new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("text/plain"))
        FileDownloadName = "test.txt"

VirtualFileResultPhysicalFileResult

虛擬檔案路徑(相對路徑一定要存放wwwroot下的目錄)
實際硬碟檔案路徑(要指定實際硬碟絕對路徑)
這裡我們注入IWebHostEnvironment 間接取得站台根目錄

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Net5AppDiffAction.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Net5AppDiffAction.Controllers
    public class HomeController : Controller
        private readonly ILogger<HomeController> _logger;
        private readonly IWebHostEnvironment _environment;
        public HomeController(ILogger<HomeController> logger, IWebHostEnvironment enviroment)
            _logger = logger;
            _environment = enviroment;
        public VirtualFileResult VirtualFileResultDemo()
            return new VirtualFileResult("/css/site.css", "text/plain");
        public PhysicalFileResult ShowProducts()
            return new PhysicalFileResult(_environment.ContentRootPath + "/Data/Products.xml", "text/xml");
        public PhysicalFileResult PhysicalFileResultDemo()
            return new PhysicalFileResult(_environment.ContentRootPath + "/wwwroot/css/site.css", "text/plain");

JsonResult

這裡準備創建好一個 model class Products

寫回傳Json result的 action

public JsonResult ShowNewProducts()
    Products prod = new Products() { ProductCode = 101, ProductName = "Printer", Cost = 1500 };
    return Json(prod);

藉由JsonResult序列化物件至JSON格式字串

EmptyResult 和 NoContentResult

測試action

public EmptyResult EmptyResultDemo()
    return new EmptyResult();
public NoContentResult NoContentResultDemo()
    return NoContent();

各自差異在於
NoContentResult status code返回204
EmptyResult status code則是預設的200返回
當你不想有任何response顯示在網頁上的時候
而同時也不想throw 出error直接給client端的時候
就會看你是傾向告知user你查詢結果為空(NoContentResult)
或者執行過程有錯(EmptyResult)

若想驗證回傳的status code可以下載Fiddler來自行測試

本文同步發表至個人部落格(分兩篇->因為鐵人賽規劃30天原先blog分兩篇章)
.NET Core第31天_Controller Action的各種不同回傳(ContentResult,ViewResult,RedirectResult,RedirectToActionResult,RedirectToRouteResult,FileResult)_part1
https://coolmandiary.blogspot.com/2021/08/net-core31controller.html

.NET Core第32天_Controller Action的各種不同回傳(FileContentResult,FileStreamResult,VirtualFileResult,PhysicalFileResult,JsonResult,EmptyResult,NoContentResult)_part2
https://coolmandiary.blogspot.com/2021/09/net-core32controller.html

雖然沒有成功連續不中斷每天發文
但仍然期許之後下次比賽可以挑戰成功
希望文章可以對於同樣新手學習有幫助

Response.Redirect() vs Response.RedirectPermanent()
https://stackoverflow.com/questions/16537955/response-redirect-vs-response-redirectpermanent

Redirect() vs RedirectPermanent() in ASP.NET MVC
https://stackoverflow.com/questions/17517318/redirect-vs-redirectpermanent-in-asp-net-mvc

RedirectPermanent
https://www.c-sharpcorner.com/forums/redirectpermanent

FileResult In ASP.NET Core MVC
https://www.c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2/

認識 ASP․NET Core 檔案提供者與透過 Web API 下載實體檔案
https://blog.miniasp.com/post/2019/12/08/Understanding-File-Providers-in-ASP-NET-Core-and-Download-Physical-File

File Providers in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-3.1&WT.mc_id=DT-MVP-4015686

ASP.NET Core MVC returning file using FileResult
https://geeksarray.com/blog/aspnet-core-mvc-returning-file-using-fileresult