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

时间:2015-10-16 16:08:27

标签: javascript c# jquery json asp.net-mvc

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

控制器AdminPanel,如此查看AdminProfile

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

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

enter image description here

如果我尝试使用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") });
}

这是加载的部分页面:

 @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>

下面的脚本放在_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>

我要做的就是在提交后停止重定向,我已将此打开以获得赏金。如果您还可以在用户点击提交后包含我如何收到状态消息,那将是很好的。

例如,用户点击保存更改&gt;保存到服务器&gt;然后将消息发送回部分页面(所有这些都没有重定向)

5 个答案:

答案 0 :(得分:4)

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

[HttpPost]
public ActionResult Manage(LocalPasswordModel model){

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

[HttpPost]
public ActionResult Manage(LocalPasswordModel model){

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

}

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

我认为此链接也可能有所帮助,jQuery.post()event.preventDefault()对于阻止表单提交客户端也很有用。

要具体控制您要重定向到的位置,请在每个地方添加重定向,例如:请注意我只返回到adminprofile,因为这是操作所需的

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

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

答案 1 :(得分:2)

是不是因为当您按下保存时,会将常规http帖子发送到服务器的“帐户/管理”页面,以便重定向。所以你的javascript实际上从未运行过?

尝试使用Ajax.BeginForm或更改保存按钮以使用您的javascript。

答案 2 :(得分:1)

如果您使用AJAX发布表单数据,那么只需在提交功能

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/tab_background_selected" android:state_selected="true"/>
    <item android:drawable="@color/tab_background_unselected"/>
</selector>

并在提交功能

<form onsubmit="mysubmitfunc(event)" ....>

答案 3 :(得分:1)

以正确的方式使用ajax提交,如何?附加表单提交事件,捕获提交事件,停止发布,从javscript发布,并在成功时处理响应。

将_LayoutPage js替换为next,确保使用ID识别表单,否则此javascript可能会影响其他表单。

$(function() { //shorthand document.ready function

    //recommended to use Id on form identification not class... search on google how to
    //attach handler on form submit
    $('.form-horizontal').submit(catchSubmit);


    //custom handler for form submit
    function catchSubmit(event) {
      event.preventDefault(); //stop html form post
      // ajax post with serialized form
      $.post($(this).attr("action"),
         $(this).serialize(),
         postSuccessHandler
      );
    }

   //redirect decizion
   function postSuccessHandler(data) {
     if (data.redirectTo) {
               window.location.href = data.redirectTo;
            } else {                    
                $(".tab-2").html(data);
            }
   }
});

答案 4 :(得分:0)

您还可以将html按钮移动到表单外部。