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 ) からカスタム Validator の例を実装しようとしましたが、これらの例を使用してもうまくいかないことがわかりました。私にはあまり役に立たないクライアント側の検証で検証の概要を表示します。

私が探しているソリューションでは、クライアント側とサーバー側の両方の検証が正しいフォームに表示されるようにする必要があります。MVCを使用したこのような例はありますか? 可能であればjqueryを使用してクライアント側の検証を手動で行うことを避け、フレームワークを使用して作業を処理したいだけです。

あなたの提案をありがとう、リッチ

4

1 に答える 1

2

私が認めるよりも長くこの問題をいじった後、方法を知っていれば、答えはいつものように簡単でした!

この問題に遭遇した他の人にとっての解決策は、アクションの名前を変更して、POST アクションが GET アクションとは異なる名前になるようにすることです。このように、レイアウト ページがポスト バックされ、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 に答える