表单提交后如何停止从部分页面重定向

G G*_* Gr 3 javascript c# asp.net-mvc jquery json

有一个问题,我有一个名为Manage的局部视图,我将局部加载到:

Controller AdminPanelAdminProfile像这样查看:

                        <div id="tab-2" class="tab-pane">
                               @{Html.RenderPartial("~/Views/Account/Manage.cshtml");
                               }
                        </div>
Run Code Online (Sandbox Code Playgroud)

当我点击保存更改时,我被重定向到/Account/Manage,它应该是/AdminPanel/AdminProfile?

在此处输入图片说明

如果我尝试使用 ajax 脚本,不确定控制器是否为 json 返回正确的重定向或信息:

    public ActionResult Manage(ManageMessageId? message)
    {
        ViewBag.StatusMessage =
            message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
            : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
            : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
            : "";
        ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
        ViewBag.ReturnUrl = Url.Action("Manage");
        return View();
    }
public ActionResult Manage(LocalPasswordModel model)
{
    bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
    ViewBag.HasLocalPassword = hasLocalAccount;

            ViewBag.ReturnUrl = Url.Action("AdminProfile", "AdminPanel");
        //ViewBag.ReturnUrl = Url.Action("Manage");


    if (hasLocalAccount)
    {
        if (ModelState.IsValid)
        {
            // ChangePassword will throw an exception rather than return false in certain failure scenarios.
            bool changePasswordSucceeded;
            try
            {
                changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
            }
            catch (Exception)
            {
                changePasswordSucceeded = false;
            }

            if (changePasswordSucceeded)
            {
                    return RedirectToAction("AdminProfile", "AdminPanel", new { Message = ManageMessageId.ChangePasswordSuccess });
                
            }
            else
            {
                ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
            }
        }
    }
    else
    {
        // User does not have a local password so remove any validation errors caused by a missing
        // OldPassword field
        ModelState state = ModelState["OldPassword"];
        if (state != null)
        {
            state.Errors.Clear();
        }

        if (ModelState.IsValid)
        {
            try
            {
                WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
                return RedirectToAction("AdminProfile", "AdminPanel", new { Message = ManageMessageId.ChangePasswordSuccess });
            }
            catch (Exception)
            {
                ModelState.AddModelError("", String.Format("Unable to create local account. An account with the name \"{0}\" may already exist.", User.Identity.Name));
            }
        }
    }

    // If we got this far, something failed, redisplay form
    //return PartialView("Manage", model);
    return Json(new { redirectTo = Url.Action("AdminProfile", "AdminPanel") });
}
Run Code Online (Sandbox Code Playgroud)

这是加载的部分页面:

 @model LocalPasswordModel
@{
    ViewBag.Title = "Change Password";
}
<section class="hgroup">
    <div class="panel-body">
        <h1>@ViewBag.Title</h1>
        <ul class="breadcrumb pull-right top-right">
            <li>You're logged in as <strong>@User.Identity.Name</strong></li>
        </ul>
        <ul class="message-success">@ViewBag.StatusMessage</ul>
        @using (Html.BeginForm("Manage", "Account", Form.Post, new { @class = "form-horizontal" }))
        {
            @Html.AntiForgeryToken()
            @Html.ValidationSummary()
            <div class="form-group">
                <label class="col-sm-2 control-label">Old Password</label>
                <div class="col-sm-10">
                    @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" })
                </div>
            </div>
                                        <div class="form-group">
                                            <label class="col-sm-2 control-label">New Password</label>
                                            <div class="col-sm-10">
                                                @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
                                            </div>
                                        </div>
                                        <div class="form-group">
                                            <label class="col-sm-2 control-label">Confirm Password</label>
                                            <div class="col-sm-10">
                                                @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
                                            </div>
                                        </div>
                                        <div class="form-group">
                                            <div class="col-sm-8 col-sm-offset-2">
                                                <input type="submit" class="btn btn-primary" value="Change password" />
                                            </div>
                                        </div>

        }
    </div>
</section>
Run Code Online (Sandbox Code Playgroud)

下面的脚本被放置在_LayoutPage但是正如评论中提到的那样它没有做任何事情。

   <script type="text/javascript">
        $.ajax({
            type: "POST",
            url: '@Url.Action("Manage", "Account")',
            data: $('form').serialize(),
            success: function (result) {
                if (result.redirectTo) {
                    // The operation was a success on the server as it returned
                    // a JSON objet with an url property pointing to the location
                    // you would like to redirect to => now use the window.location.href
                    // property to redirect the client to this location
                    window.location.href = result.redirectTo;
                } else {
                    // The server returned a partial view => let's refresh
                    // the corresponding section of our DOM with it
                    $(".tab-2").html(result);
                }
            },
            error: function () {
    
            }
        });
    </script>
Run Code Online (Sandbox Code Playgroud)

我想要做的就是在提交后停止重定向,我已将其打开并悬赏。如果您还可以包括在用户点击提交后如何接收状态消息,那就太好了。

例如,用户点击保存更改 > 保存到服务器 > 然后将消息发送回部分页面(全部不重定向)

小智 5

首先,您需要将您的POST操作结果装饰为一个帖子。

[HttpPost]
public ActionResult Manage(LocalPasswordModel model){
Run Code Online (Sandbox Code Playgroud)

其次,您可以通过在控制器中测试表单提交结果的有效性来完全摆脱 javascript,这将管理用户是否被重定向。

[HttpPost]
public ActionResult Manage(LocalPasswordModel model){

    if(condition to redirect){
        return RedirectToAction("AdminProfile", "AdminPanel");
    }
    return View(model);

}
Run Code Online (Sandbox Code Playgroud)

最后,我看不到您实际上将 jquery 放在哪里。它需要放在表单页面的末尾,在您的脚本部分。你提到它在你的布局页面中?

我认为这个链接也可能有帮助,jQuery.post()event.preventDefault()也有助于防止表单提交客户端。

要具体控制您要重定向到的位置,请在每个有结果的地方添加重定向,例如:请注意我只是返回到管理员配置文件,因为这是操作员想要的

if (changePasswordSucceeded)
{
    return RedirectToAction("AdminProfile", "AdminPanel", new { Message = ManageMessageId.ChangePasswordSuccess });

 }
 else
 {
     ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
     return RedirectToAction("AdminProfile", "AdminPanel");
 }
Run Code Online (Sandbox Code Playgroud)

作为旁注,您需要仔细考虑程序流程来决定如何管理无效尝试等。