Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax.ActionLink returns Login page within div when user need to login again

I have a Ajax.ActionLink which results in a partial view being returned. However, if my FormsAuthentication expires and the user needs to login again, the whole Login page is returned as the partial view.

This results in the full login page appearing within the div I set aside for the partial view. So it looks like two web pages on the page.

I am using the [Authorize] attribute on my controller and actions.

How can I force the login page to be returned as a full view?

like image 967
Valamas Avatar asked Nov 29 '11 01:11

Valamas


1 Answers

You can extend the [Authorize] attribute so that you can override the HandleUnauthorizedRequest function to return a JsonResult to your AJAX call.

public class AuthorizeAjaxAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext 
                                                      filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // It was an AJAX request => no need to redirect
            // to the login url, just return a JSON object
            // pointing to this url so that the redirect is done 
            // on the client

            var referrer = filterContext.HttpContext.Request.UrlReferrer;

            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new { redirectTo = FormsAuthentication.LoginUrl + 
                            "?ReturnUrl=" + 
                             referrer.LocalPath.Replace("/", "%2f") }
            };
        }
        else
            base.HandleUnauthorizedRequest(filterContext);
    }
}

Create a Javascript function handle the redirect:

<script type="text/javascript">
    function replaceStatus(result) {
        // if redirectTo has a value, redirect to the link
        if (result.redirectTo) {
            window.location.href = result.redirectTo;
        }
        else {
            // when the AJAX succeeds refresh the mydiv section
            $('#mydiv').html(result);
        }
    };
</script>

And then call that function in the OnSuccess option of your Ajax.ActionLink

Ajax.ActionLink("Update Status", "GetStatus", 
                 new AjaxOptions { OnSuccess="replaceStatus" })
like image 50
dnatoli Avatar answered Oct 23 '22 16:10

dnatoli