Skip to main content
 首页 » 编程设计

c#之@Ajax.BeginForm 请求/响应正常,但 Controller 不重定向

2024年01月28日34emanlee

@using (Ajax.BeginForm("Login", "Account", "",  
            new AjaxOptions { HttpMethod = "POST" },  
            new { id = "loginForm", name = "loginForm" })) 
{ 
 ... 
} 

此表单执行请求并收到响应 200 OK。调试我可以看到响应 html 但我没有被重定向。

如果我在不使用 html 的情况下手动执行此操作,我会成功地重定向到我需要的位置。

这是 Controller :

// 
    // POST: /Account/Login 
    [HttpPost]         
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public ActionResult Login(LoginModel model) 
    { 
        MembershipProvider mp = Membership.Provider; 
        bool isDigital = bool.Parse(Request.Form.GetValues("hasDigital")[0]); 
        string certDBNumber; 
 
        if (isDigital) 
        { 
            /*** Retira só o que enteressa do Certificado.Subject (CPF/CNPJ)*/ 
            string code = Request.Form.GetValues("code")[0]; 
            string[] dataArray = code.Split(','); 
            string data = dataArray.Last(); 
            string[] numberArr = data.Split(':'); 
            string number = numberArr.Last(); 
 
            /*** Resgata chave do usuário no banco ***/ 
            using (tgpwebgedEntities context = new tgpwebgedEntities()) 
            { 
                var userObj = from u in context.aspnet_Users  
                              where u.UserName == model.UserName  
                              select u.UserId; 
                Guid userID = userObj.First(); 
                var obj = from u in context.sistema_UsersCertified  
                          where u.userID == userID select u.keyNumber; 
                certDBNumber = obj.First(); 
            } 
 
            //Verifica se usuário é credenciado 
            if (number == certDBNumber) { 
                FormsAuthentication.SetAuthCookie(model.UserName, false); 
                return RedirectToAction("Index", "Home");                     
            } 
        }//Login sem certificado digital 
        else 
        { 
            if (ModelState.IsValid &&  
                           mp.ValidateUser(model.UserName, model.Password)) 
            { 
                FormsAuthentication.SetAuthCookie(model.UserName, false); 
                return RedirectToAction("Index", "Home"); 
            } 
        } 
        /*** Se chegou até aqui algo deu errado. Mostra denovo o form ***/ 
        ModelState.AddModelError("", "Username ou Password incorreto!."); 
        return View(model); 
    } 

为什么会有这种奇怪的行为?

请您参考如下方法:

由于这是一个 ajax 帖子,您无法重定向。一个选项是返回一个值,使成功函数实现需要发生的重定向,然后发出

if( someReturnedFlag == true ){ 
 window.location = redirectionUrl;//http://www.stackoverflow.com 
} 

或者,你可以做一个重定向 View

RedirectionView.cshtml

@{ 
 Layout = null; 
} 
<script type="text/javascript"> 
 window.location = "hardcodedurl";//or pass it in using @model 
</script> 

然后从您的 ajax 帖子返回此 View ,它会重定向。


编辑

这得到了比我预期更多的关注,所以我想我会用两个更完整的例子来改进这个答案。


1:jQuery的ajax

查看:

$.ajax({ 
        url: "@(Url.Action("TargetAction","TargetController"))", 
        type: 'POST', 
        data: $("#loginForm").serialize(), 
        success: function (URL) { 
         window.location = URL; 
        } 
}); 

Controller :

public class TargetController: Controller 
[HttpPost] 
public string TargetAction(ViewModel model) 
{ 
 //use model (note that the serialized form was bound to the model) 
 return "http://www.stackoverflow.com"; 
} 

2:RedirectionView.cshtml

主视图:

@{ 
 AjaxOptions ajaxOpts = new AjaxOptions 
 { 
    UpdateTargetId = "redirectWhenDone" 
 }; 
} 
 
@using (Ajax.BeginForm("TargetAction", ajaxOpts)) 
{ 
 ... 
} 
<div id="redirectWhenDone"></div> 

RedirectionView.cshtml

@model string 
@{ 
 Layout = null; 
} 
<script type="text/javascript"> 
 window.location = "@(Model)"; 
</script> 

Controller

[HttpPost] 
public ActionResult TargetAction(ViewModel vm) 
{ 
 //use ViewModel 
 
 ... 
 
 
 //it is important to use an object here for the string 
 object url = "http://www.stackoverflow.com"; 
 //otherwise the View() method will consider the string a parent location and look 
 //for the RedirectionView in the wrong place (basically using the wrong overload) 
 return View("RedirectionView", url ); 
}