demoshop

demo, trying to be the best_

之前 demo 有寫過一篇「驗證 AJAX 動態載入的頁面是否已被導向(簡單版)」引來不少朋友提供一些實作的建議,所以今天要再來寫一篇利用 ASP.NET MVC 的 ActionFilter 機制,來實作的的文章。

demo廢言因為寫 ASP.NET MVC 後對於 前端 Javascript 的使用越來越高,難免不會碰到需要動態載入的頁面,但是有些頁面是需要登入的,在什麼都不處理的情況之下會發生很笨的錯誤(相關說明請參考「驗證 AJAX 動態載入的頁面是否已被導向(簡單版)」),但是這種寫法需要在每次的 ajax load 都多一些判斷(當然你也可以自己包起來),但是既然 ASP.NET MVC 有提供 ActionFilter 這種機制那真的不用可惜阿。

 

●首先參考了 星寂 寫的「ASP.NET MVC – Ajax 登入驗證」實作了一份,但是發現當頁面是使用 Html.RenderAction 叫用的就會發生以下錯誤「Child actions are not allowed to perform redirect actions.

demo廢言經過追查 Source Code 後看到這是一個特別明確加上去的 if 判斷式,因此猜想可能是怕使用者不小心造成循環導向的無窮迴圈。


●後來參考了 MVC 的 Source Code 改寫成以下的寫法

public class AuthorizePlus : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //原始驗證機制
            base.OnAuthorization(filterContext);

            //驗證是否是授權的連線,以及不能是 AJAX 呼叫。
            if (filterContext.Result is HttpUnauthorizedResult && !filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new HttpUnauthorizedResult();
                return;
            }
            else if (filterContext.Result is HttpUnauthorizedResult)
            {
                ContentResult cr = new ContentResult();
                cr.Content = "<p style=\"color:Red;font-weight:bold;\">您尚未登入無法觀看!! 請先登入後再嘗試。</p>";
                filterContext.Result = cr;
            }
        }
    }

這樣子就會使用 HttpUnauthorizedResult 將 HTTP 狀態碼改為 401 讓 .NET 內建的機制自己接到後轉向去 Web.config 設定的未登入頁面,簡單解決這個需求。


●如果你需要針對 RenderAction特別做處理的話可以使用以下的 Code

if (filterContext.IsChildAction)
{
    //是使用RenderAction 叫用的
}

分隔線

ASP.NET MVC – Ajax 登入驗證

回應討論