1

我有一个包含两个部分的视图,它们使用 ajax 将它们的表单发布到操作中。onsuccess 回调将用户重定向到另一个 url。但是,当模型状态无效时,我不希望调用此 onsuccess 函数。我尝试从控制器返回 400 级错误以触发 onfailure 功能,但它会导致一些奇怪的行为并且不会显示验证错误。这是我的代码

行动:

[AllowAnonymous]
    [DisableCache]
    public ActionResult Login(string returnUrl ="/") //This is the view that contains the two other partial views.
    {
        var path = VirtualPathUtility.ToAbsolute(returnUrl);
        var url = new Uri(Request.Url, path).AbsoluteUri;
        ViewBag.ReturnUrl = url;
        return View();
    }


    [AllowAnonymous]
    public ActionResult _LoginPartial()
    {
        return PartialView(new LoginModel());
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult _LoginPartial(LoginModel model)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password,    persistCookie: model.RememberMe))
        {
            return PartialView();
        }

        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
        Response.StatusCode = 400;
        return PartialView(model);
    }

登录视图:

<hgroup class="title">
<h1>@ViewBag.Title.</h1>
</hgroup>

 @section CustomScripts {
     @if (ViewData.ModelState.IsValid){
         <script type ="text/javascript">
             function OnSuccess() {
                 var returnUrl = @Html.Raw(Json.Encode(ViewBag.ReturnUrl))
                 window.location = returnUrl;
             }
             function OnFailure() {
                alert("Fail");
            }
        </script>
    }
}

<section id="loginForm">

@{
     if(!WebSecurity.IsAuthenticated){
        <h2>Use a Creative Works account to log in.</h2>
        @Html.Action("_LoginPartial")
        @Html.ActionLink("Forgot your password?", "ResetPassword")
     }
}
</section>
<section id ="RegisterForm">
@{
    if(!WebSecurity.IsAuthenticated){
        <span>Don't have an account? Make one!</span>
        @Html.Action("RegisterPartial", new { returnUrl = ViewBag.ReturnUrl })
    }
}
</section>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

_Login部分视图

@model Cwo.Domain.Entities.LoginModel


@{
ViewBag.Title = "LoginPartial";
}
@using (Ajax.BeginForm("_LoginPartial", 
new AjaxOptions(){UpdateTargetId = "loginForm", 
InsertionMode = InsertionMode.Replace, OnSuccess = "OnSuccess", OnFailure = "OnFailure"
})) {    

 @Html.AntiForgeryToken()
 @Html.ValidationSummary(true)

    <fieldset>
        <legend>Log in Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
                @Html.ValidationMessageFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)
            </li>
            <li>
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
            </li>
        </ol>
        <input type="submit" value="Log in" />
    </fieldset>
    }

格式有点乱贴在这里,抱歉。我希望显示验证错误,而不是警报(“失败”)响应。如果有比从操作中返回 400 级错误更好的方法,请教我!

4

1 回答 1

0

我认为另一种表达问题的方式是您不希望执行 onsuccess 函数的内容?如果是这种情况,请将您的 @if (ViewData.ModelState.IsValid){ ... } 移到 OnSuccess 函数内部。如果状态无效,则该函数将没有胆量,因此什么也做不了。

我个人喜欢将 javascript 与 razor 分开……更重要的是,javascript 应该驻留在自己的 js 文件中。在这种情况下,您可以使用 razor 将 bool javascript 变量设置为函数或对象构造函数,然后只有当变量为真时才能成功。

于 2013-09-06T20:48:27.217 回答