5

我已将创建帐户视图和登录视图合并到同一个视图中。所以这是一个有两个表单的视图,但是当我提交时它们会混合在一起。如果我尝试登录并显示错误:

Html.ValidationSummary()

两种形式都会出错。我开始将字段重命名为loginPassword,createPassword,因为否则当我提交并且密码丢失时,它会在两边都标记为丢失。

将这两种形式分开以便它们可以在同一个视图/页面上独立工作的方法是什么?

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() 来分隔验证消息。这里有两个建议:

  1. 将验证摘要放置在可以适用于两种表单的区域。例如,如果登录和注册表单并排放置,则将验证摘要放置在两个表单上方居中的 div 中。我在Mahalo 登录页面上找到了这种风格的示例。
  2. 在适当的控制器操作方法中,向 ViewData 添加一些内容,指示调用了哪个操作。在视图中,每个表单都有一个 ValidationSummary,但每个表单都将根据您添加到 ViewData 的内容有条件地呈现。

无论哪种方式,表单字段都应该被唯一命名。

我选择了解决方案#1,因为我对能够让它看起来的方式感到满意。但是,如果您需要根据提交的表单将验证摘要显示在两个不同的位置,请使用 #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" ) %>

在服务器端,使用 binder 的 prefix 选项

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 回答