5

アカウントの作成ビューとログインビューを同じビューにマージしました。つまり、2つのフォームのビューですが、送信するとそれらが混在します。ログインしようとすると、次のようなエラーが表示されます。

Html.ValidationSummary()

どちらの形式でもエラーが発生します。そして、フィールドの名前をloginPassword、createPasswordに変更し始めました。そうしないと、送信してパスワードが欠落している場合、両側で欠落しているとマークされるためです。

同じビュー/ページで独立して機能できるように、これら2つのフォームを分離する方法は何でしょうか。

4

5 に答える 5

5

ああ、そうだ、私は前にこれを正確にやらなければならなかった。私が見つけた方法は、どのフォームが投稿されたかを詳細に示すフラグをViewDataに設定してから、ValidationSummary用の独自の拡張メソッドを作成することでした。

コードは今私と一緒にいないので、私は今それのためにいくつかのエアコードを実行するために最善を尽くします、それは明らかにそれを行う方法の概念にすぎないので、額面通りにそれを取ります。

まず、tvanfossonが「EntryPageModel」で提案したのと同じセットアップを使用します。

表示-Html.MyValidationSummaryに注意してください

<% using(Html.BeginForm("NewAccount", "Account")) %>
<% { %>
    <%= Html.MyValidationSummary("NewAccountForm") %>

    <%= Html.TextBox("NewAccount.FirstName") %>
    <%= Html.TextBox("NewAccount.LastName") %>
    <%= Html.TextBox("NewAccount.Email") %>
    <%= Html.Password("NewAccount.Password") %>
    <%= Html.Password("NewAccount.ConfirmPassword") %>
<% } %>

<% using(Html.BeginForm("Login", "Account")) %>
<% { %>
    <%= Html.MyValidationSummary("LoginForm") %>

    <%= Html.TextBox("Login.Email") %>
    <%= Html.Password("Login.Password") %>
<% } %>

コントローラ-ViewData["PostedForm"]に注意してください

public class Account : Controller
{
    private EntryPageModel _viewModel;

    public ActionResult NewAccount(FormCollection formValues)
    {
        try
        {
            //binding and validation for _viewModel.NewAccount
        }
        catch
        {
            ViewData["PostedForm"] = "NewAccountForm";
            return View("RegisterAndLogin", _viewModel);
        }
    }

    public ActionResult Login(FormCollection formValues)
    {
        try
        {
            //binding and validation for _viewModel.Login
        }
        catch
        {
            ViewData["PostedForm"] = "LoginForm";
            return View("RegisterAndLogin", _viewModel); //You'll want to pass in a model
        }
    }
}

カスタムhtml拡張子

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string MyValidationSummary(this HtmlHelper html, string formName)
        {
            if (!string.IsNullOrEmpty(html.ViewData["PostedForm"])
                && (html.ViewData["PostedForm"] == formName))
            {
                return html.ValidationSummary();
            }

            return "";
        }
    }
}

HTH、チャールズ

于 2009-06-04T22:26:20.627 に答える
3

私は同じ問題に対処しなければなりませんでした。組み込みのValidationSummary()を使用して検証メッセージを分離する方法がないことがわかりました。ここに2つの提案があります:

  1. 検証の要約を、両方のフォームに適用できる領域に配置します。たとえば、ログインフォームとサインアップフォームが並んでいる場合は、検証の概要を両方のフォームの中央にあるdivに配置します。Mahaloのログインページでこのスタイルの例を見つけました。
  2. 適切なコントローラーアクションメソッドで、呼び出されたアクションを示す何かをViewDataに追加します。ビューには、フォームごとにValidationSummaryがありますが、ViewDataに追加した内容に基づいて、それぞれが条件付きでレンダリングされます。

いずれの場合も、フォームフィールドには一意の名前を付ける必要があります。

私はそれを見せることができた方法に満足したので、私は解決策#1を選びました。ただし、送信されたフォームに応じて2つの異なる場所に検証の概要を表示する必要がある場合は、#2を使用してください。

于 2009-06-04T21:23:02.953 に答える
2

入力要素は、形式が異なっていても、異なる名前/IDを必要とします。名前が異なる場合を除き、コントロールの名前に基づいて一致するため、各コントロールの検証ロジックがトリガーされます。名前を変えて区別することで、あなたは正しい方向に進んでいると思います。

おそらく、次のようなことができるように、複合モデルを設定します(これは不完全であることに注意してください)。

<%= Html.TextBox( "Login.Name" ) %>
<%= Html.TextBox( "Login.Password" ) %>


<%= Html.TextBox( "NewAccount.Name" ) %>
<%= Html.TextBox( "NewAccount.Password" ) %>
<%= Html.TextBox( "NewAccount.ConfirmPassword" ) %>

サーバー側では、バインダーのプレフィックスオプションを使用します

public ActionResult Login( [Bind(Prefix="Login")]AccountModel model )
{
    ...
}

そして、モデルは次のようになります。

public class AccountModel
{
      public string Name { get; set; }
      public string Password { get; set; }
      public string ConfirmPassword { get; set; }
}

public class EntryPageModel
{
     public AccountModel Login { get; set; }
     public AccountModel NewAccount { get; set; }
}
于 2009-06-04T20:26:02.367 に答える
0

フォームが完全に異なるアクションに投稿している場合、ModelStateDictionaryには、呼び出されたアクションによって提供されたエラーのみが含まれている必要があります。

関連するコードを投稿できますか?

于 2009-06-04T20:18:06.377 に答える
0

ValidationSummary()を分割する方法があるかどうかはわかりません。

フォームの場合、さまざまなフィールドを使用して、バインドするモデルクラスを作成できます。しかし、それはあなたがすでに持っているものをはるかに超えることはありません。

于 2009-06-04T20:19:21.197 に答える