動作方法的重新轉向

ASP.NET Core Web 應用開發–使用 MVC 框架 / PART II MVC 的細節 / 動作方法與 ActionResult / 動作方法的重新轉向

動作方法執行完畢之後,並不一定會有回應內容,重新轉向亦相當常見,下表列舉支援轉向作業的 ActionResult 子類別。

類別說明
RedirectResult轉向至指定的(參考 / 絕對)URL
RedirectToPageResult轉向至指定的Razor Page頁面
RedirectToActionResult轉向至指定的動作方法
RedirectToRouteResult轉向至一個根據路由組態產生的URL

從第一個RedirectResult 開始,這是最簡單的,回傳這個物件表示要求轉向一個指定的URL,可以是相對或絕對路徑,在動作方法中透過 Redirect() 的引用來達到這個目的,考慮以下的配置:

return Redirect(url) ;

其中的 url 是要轉向的目標網址列字串。

於控制器檔案 HomeController.cs 定義動作方法命名為 RRDemo,並且配置以下的內容:

public IActionResult RRDemo()
{
    var url = "https://www.kangting.tw//03/aspnet-core-web-mvc.html";
    return Redirect(url);
}

動作方法 RRDemo() 最後引用 Redirect() 轉向至url變數表示的路徑網址,這是本書的線上內容網址,現在執行專案開啟預設網頁,於網址輸入「https://localhost:xxxxx/home/rrdemo」,如以下左截圖:

按一下ENTER鍵,或發現瀏覽器跳轉至本書線上專頁。

Redirect() 回傳的是 RedirectResult 物件,負責執行轉向作業,以上示範的是一個絕對路徑,如果想要轉向至相同網站的特定位置,也可以直接指定相對路徑如下:

public IActionResult RRDemo()
{
    var url = "/App/HelloMessage";
    return Redirect(url);
}

當一個要求傳送進來,根據這裏設定的url,會轉向至App控制器中,找到HelloMessage動作方法執行。

類似的方法還有另外一個RedirectToAction() ,例如以下的配置:

return RedirectToAction(acname,ctname);

第一個 acname參數是轉向的動作方法名稱,接下來的ctname則是控制器名稱。

其回傳的是 RedirectToActionResult 物件,執行轉向至 ctname 控制器中,名稱為acname的動作方法,如上述示範的相對路徑「/App/HelloMessage」為例,以下的設定可以達到相同的效果:

public IActionResult RTADemo()
{
    var acname = "HelloMessage";
    var ctname = "App";
    return RedirectToAction(acname, ctname);
}

動作方法 RTADemo() 會得到與上述 RRDemo() 完全相同的轉向結果。

持續以此為例,如果想要轉向的是目前控制器內的動作方法,則只需指定第一個參數acname 即可。

如果想要進一步以路由樣式指定轉向的目標位址,可以引用另外一個回傳 RedirectToRouteResult 物件的 RedirectToRoute() 方法,考慮以下的配置:

public RedirectToRouteResult RedirectToRouteDemo()
{
return RedirectToRoute(new { 
        controller = "Home",
        action="Index" ,
        Id= 123 
});
}

其中接受一個Route物件,根據指定的控制器與動作方法進行轉向,指定參數則一併成為URL的一部份,這一組配置將轉向至如下的URL。

http://localhost:51379/Home/Index/123

結合路由組態

更彈性的轉向可以先在路由組態完成設角,再進行指定,開啟App_Start/RouteConfig.cs,於其中配置一個新的route樣式,命名為「rtr」:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "rtr",
        pattern: "App/{*HelloMessage}",
        defaults: new { controller = "App", action = "HelloMessage" }
        );
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

現在於控制器中,配置動作方法如下:

public IActionResult RTRDemo()
{
    return RedirectToRoute("rtr");
}

現在於網址列輸入「https://localhost:44393/Home/RTRDemo」,傳送之後,會找到Home控制器中的RTRDemo 動作方法,RedirectToRoute("rtr") 則根據 rtr 路由組態設定,轉向至以下網址:

https://localhost:xxxxx/App

這會對應至以下的網址:

https://localhost:xxxxx/App/HelloMessage

以上討論了三組不同的轉向方法,分別是Redirect、RedirectToAction與RedirectToRoute,如果查詢規格手冊,會發現這三個方法各還有Permanent的版本-RedirectPermanent、RedirectToActionPermanent與RedirectToRoutePermanent ,兩種版本的差異在於前者回傳 302 狀態碼,後者則是 301 ,除非原始資源確定永久移除,強迫瀏覽作業每一次均會直接轉向,否則的話引用非 Permanent 的版本即可。

沒有留言: