代码之家  ›  专栏  ›  技术社区  ›  Pablo Fernandez

在ASP.NET MVC中,在同一视图中分离两个窗体

  •  5
  • Pablo Fernandez  · 技术社区  · 15 年前

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

    Html.ValidationSummary()
    

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

    如何将这两个表单分开,以便在同一视图/页面上独立工作?

    5 回复  |  直到 15 年前
        1
  •  3
  •   solidbeats    15 年前

    我不得不处理同样的问题。我发现无法使用内置validationSummary()分隔验证消息。以下是两个建议:

    1. 将验证摘要放置在可以同时应用于两个表单的区域中。例如,如果登录和注册表单并排,请将验证摘要放在两个表单上方居中的一个分区中。我在 Mahalo login page .
    2. 在适当的控制器操作方法中,向ViewData添加一些内容,指示调用了哪个操作。在视图中,每个表单都有一个验证摘要,但每个表单都将根据添加到视图数据的内容有条件地呈现。

    无论采用哪种方式,表单字段都应具有唯一的名称。

    我选择了解决方案1,因为我对我能找到它的方式很满意。但是,如果您需要验证摘要显示在两个不同的位置,具体取决于提交的表单,请使用2。

        2
  •  5
  •   Charlino    15 年前

    啊,是的,我以前就必须这么做。我发现的方法是在viewdata中设置一个标志,详细说明发布了哪个表单,然后我创建了自己的扩展方法来验证摘要。

    代码现在不在我身边,所以我会尽力为它做一些空中代码,这显然只是一个如何做的概念,所以以面值来考虑。

    首先,我将使用与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") %>
    <% } %>
    

    控制器-注 视图数据[“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 "";
            }
        }
    }
    

    HTHs 查尔斯

        3
  •  2
  •   tvanfosson    15 年前

    即使输入元素的形式不同,它们也需要不同的名称/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; }
    }
    
        4
  •  0
  •   Ben Scheirman    15 年前

    如果表单发布到完全不同的操作,那么ModelStateDictionary应该只包含由调用的操作提供的错误。

    你能发布相关的代码吗?

        5
  •  0
  •   GalacticCowboy    15 年前

    我不确定是否有方法拆分validationSummary()。

    对于表单,您可以使用各种字段创建要绑定的模型类。不过,这不会比你已经拥有的多。