ASP.NET MVC Login Modal problems - redirect goes t

2019-03-06 05:49发布

问题:

I have the login view showing up in a modal dialog (using jquery simplemodal), and when the user fails login - it works fine - the error goes back to the modal. The problem is when the user successfully logs in - the page is supposed to be redirected and the modal disappears, but the modal is now updated with the entire page :(

In order for the modal to look correct - i check to see in the AccountController if the source of the login was Ajax, if so - return a partial view (to display in the modal) if not, return the full view (in case a user tries to access a page from outside of the website)

public ActionResult LogOn()
    {
        if (Request.IsAjaxRequest())
        {
            return PartialView("_LogOn");
        }

        return View();
    }

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(model.UserName, model.Password))
            {
                FormsService.SignIn(model.UserName, model.RememberMe);
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }

        // If we got this far, something failed, redisplay form
        if (Request.IsAjaxRequest())
        {
            return PartialView("_LogOn");
        }

        return View();
    }

In my Logon UserControl (the one thats in Site.Master) i added a script to logon from javascript when the login link is clicked

<script type="text/javascript">
    function openModel() {   
        $.ajax({
            type: "get",
            url: '/Account/LogOn',
            dataType: "html",
            contentType: "application/x-www-form-urlencoded;charset=utf-8",
            //  async: true,  
            success: function (result) {
                $.modal(result, {
                    closeHTML: "",
                    containerId: "login-container",    
                    overlayClose: true
                });
            }
        });  

    }       
</script>

While the partial view (that gets returned on Ajax call) looks like this:

<% using (Ajax.BeginForm("LogOn", "Account", new AjaxOptions{UpdateTargetId = "logonForm"})) { %>
<div id="logonForm">
    <%: Html.ValidationSummary(true, "Login was unsuccessful. Please review and try again.") %>

    <p>Please enter your username and password.
            </p>

        <p>
            <input id="submit" type="submit" value="Log In" />
        </p>
</div>

<% } %>

So the problem is that the AjaxOptions UpdateTargetId is the logonForm - which is what i want when the user fails to login, but when the successfully login..i want it to update the page normally - but i cant differentiate between ajax login and normal login in AccountController.LogOn unless i do this :P

Any ideas? Hope this makes sense - thanks

Its like im screwed either way.

回答1:

So instead of always returning html back to the success javascript callback I'd recommended returning json wherever you have a return RedirectToAction or return Redirect.

if (Request.IsAjaxRequest())
    return Json(new {Url = returnUrl});
else 
    return Redirect(returnUrl);

Or

if (Request.IsAjaxRequest())
    return Json(new {Url = Url.Action("Index", "Home")});
else 
    return RedirectToAction("Index", "Home");

On the javascript side do something like

success: function (result) {
    if(typeof result === 'string'){
        $.modal(result, {
            closeHTML: "",
            containerId: "login-container",    
            overlayClose: true
         });
    }
    else if (result.Url){
        location.href = result.Url;
    }
}


回答2:

Some simple jQuery to place on pages that should "break out" if accidentally displayed in a dialog:

<script type="text/javascript">

$(function () {

    if ($('title').length > 1) {
        location = '<%: Request.RawUrl %>';
    }
});

</script>