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

このフォームはリクエストを実行し、200OKのレスポンスを受け取ります。デバグ応答htmlは表示されますが、リダイレクトされません。

HTMLを使用せずに手動で行うと、必要な場所に正常にリダイレクトされます。

これはコントローラーです:

//
    // 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);
    }

なぜこの奇妙な行動?

4

1 に答える 1

6

これがajax投稿であるため、リダイレクトできません。オプションは、成功関数が実行に必要なリダイレクトを認識してから発行されるような値を返すことです。

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

または、リダイレクトビューを作成することもできます

RedirectionView.cshtml

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

そして、このビューをajax投稿から返すと、リダイレクトされます。


編集

これは予想以上に注目を集めたので、さらに2つの完全な例を使用して、この回答を少し改善すると思いました。


1:jQueryのajax

見る:

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

コントローラ:

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>

コントローラ

[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 );
}
于 2012-12-01T09:25:55.463 に答える