5

我已经查看了此站点上提供的许多解决方案以及其他针对我的问题的解决方案,但它们似乎都不适用于我的解决方案。

在我的布局页面上,我在屏幕顶部有一个登录区域。除非用户登录,否则它始终存在。此登录表单上有一个 ValidationSummary ,每次我使用站点上的另一个表单回帖时,都会触发此登录表单的验证。

我几乎可以肯定这取决于我如何从我的布局页面调用这个登录页面。它不是共享文件夹中的部分视图,它位于我项目的区域中。在我的布局页面上,我这样调用登录表单:

@Html.Action("LogOn", "Account", new { area = "Store" })

登录页面包含以下内容:

@model Project.ViewModels.LogOn_ViewModel

@{
    Layout = null;
}

@using (Ajax.BeginForm("LogOn", "Account", new { @area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" }))
{
    @Html.AntiForgeryToken()

    <div class="loginArea">
        <div class="notRegistered">
            <h4>Not registered yet?</h4>
            Register now<br/>
            @Html.ActionLink("Register", "Index", "SignUp", new { area = "Store" }, new { @class = "greenButton" })
        </div> <!-- /notRegistered -->

        <div class="loginForm">
            <div class="formFields">
                <label class="inline">@Html.LabelFor(m => m.UserName)</label>
                @Html.TextBoxFor(m => m.UserName)
                <label class="inline">@Html.LabelFor(m => m.Password)</label>
                @Html.PasswordFor(m => m.Password)
                <input type="submit" name="LogIn" value="Log in" class="blueButton" />
                <img id="actionLoaderImage" src="@Url.Content("~/Content/web/images/loader.gif")" alt="icon" style="margin-right:15px; display:none;" /> 
                @Html.ValidationSummary()
            </div>
        </div> <!-- /loginForm -->
    </div> <!-- /loginArea -->
}

登录控制器是标准的东西:

        // GET: /Account/Logon

        public ActionResult LogOn()
        {
            // if logged in show logged in view
            if (User.Identity.IsAuthenticated)
                return View("LoggedIn");

            return View();
        }


        // POST: /Account/Logon

        [HttpPost]
        public ActionResult LogOn(LogOn_ViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (SecurityService.Login(model.UserName, model.Password, model.RememberMe))
                {
                    return View("LoggedIn");
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }
            return PartialView(model);
        }

我怀疑这里发生的事情是 Html.Action 正在“发布”登录表单,如果帖子发生在页面的其他地方。这是有道理的,因为布局页面本身将作为表单发布操作的一部分发布。

我尝试从其他一些 SO 问题和博客(http://blogs.imeta.co.uk/MBest/archive/2010/01/19/833.aspx)中实现自定义验证器示例,但我发现使用这些示例不会使用客户端验证显示验证摘要,这对我来说用处不大。

我正在寻找的解决方案需要允许客户端和服务器端验证显示为正确的形式。有没有人有使用 MVC 的类似示例?如果可能的话,我想避免使用 jquery 手动维护客户端验证,而只是使用框架为我处理工作。

谢谢你的建议,丰富

4

1 回答 1

2

在解决这个问题的时间比我愿意承认的要长之后,一旦你知道怎么做,答案总是很简单!

对于遇到此问题的任何其他人,解决此问题的方法是重命名您的操作,以便您的 POST 操作与您的 GET 操作不同。这样,当 Layout 页面被回发并触发 PartialView 也被回发时,您的 PartialView 只有一个 GET 操作,因此不会触发 ValidationSummary。

根据我上面的示例,我已将表单更改为回发到我的登录部分视图的另一个操作,这为我解决了这个问题。

在我的布局页面中,指向商店区域中部分的链接保持不变:

@Html.Action("LogOn", "Account", new { area = "Store" })

然后登录表单操作被更改为指向一个新操作 - 与 GET 操作不同的名称:

    @using (Ajax.BeginForm("ConfirmLogon", "Account", new { @area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" }))
    { 
      .... 
    }

然后我只是重命名了我的控制器操作,以便它为 POST 操作具有不同的操作名称,这样当使用发布调用布局页面并且部分加载了一个不会调用我的登录 POST 操作的 POST 操作时:

        // POST: /Account/ConfirmLogon

        [HttpPost]
        public ActionResult ConfirmLogon(LogOn_ViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (SecurityService.Login(model.UserName, model.Password, model.RememberMe))
                {
                    return PartialView("LoggedIn");
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }
            return PartialView("Logon",model);
        }

希望这将帮助其他一些人解决这个问题。现在看起来很明显,但让我发疯:D

于 2012-06-20T08:37:33.760 回答