MVC 一页多个提交表单(Multi_Form in one page)

摘要:
优点:可以使用ModelState验证缺点:如果需要重新写类,如果属性多就很麻烦,重用性低②页面的对象定为多个form中的一个,其余的使用js验证优点:可以部分使用ModelState验证缺点:js使用麻烦需要前台后台写方法,验证麻烦③建立多个相同的页面,不过页面的对象不同,每个form的对象一个页面,如果有错则转到对象对应的页面。

前几天遇到同一页有多个提交表单的情况,经过艰苦奋斗终于解决。与大家分享一下。

我的要求有两个:①可以验证显示错误信息②显示错误信息的时候原保留填写的内容

未查找资料之前想了3个解决方案:

①将页面中所有的提交对象封装为一个对象,提交的时候只提交所需要的内容,当有错误信息的时候将已填的内容付给此此对象然后返回它。

优点:可以使用ModelState验证

缺点:如果需要重新写类,如果属性多就很麻烦,重用性低

②页面的对象定为多个form中的一个,其余的使用js验证

优点:可以部分使用ModelState验证

缺点:js使用麻烦需要前台后台写方法,验证麻烦

③建立多个相同的页面,不过页面的对象不同,每个form的对象一个页面,如果有错则转到对象对应的页面。

优点:可以使用ModelState验证

缺点:需要建立多个页面,其实质是转到其他地址。

经过深思熟虑如果第一种改良一下是不错的。

在网上找了半天终于找到与第一种相似的解决方案,不过国家完美。

方法如下:

①扩展HtmlHelper的beginForm 方法,添加一个参数表单名“formName”指定选用哪个Action方法,如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc.Html;
using System.Web.Mvc;

namespace MultiFormTest
{
    public static class HtmlHelperExtession
    {
        /// <summary>
        /// formName
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="formName">formName</param>
        /// <returns></returns>
        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string formName)
        {
            return BeginForm(htmlHelper, null, formName);
        }
        /// <summary>
        /// MvcForm form, string formName
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="form">form</param>
        /// <param name="formName">formName</param>
        /// <returns></returns>
        public static MvcForm BeginForm(this HtmlHelper htmlHelper, MvcForm form, string formName)
        {
            if (String.IsNullOrEmpty(formName))
                throw new ArgumentNullException("formName");

            if (form == null)
                form = htmlHelper.BeginForm();

            htmlHelper.ViewContext.Writer.WriteLine("<input name=\"n.__formName\" type=\"hidden\" value=\"" + formName + "\" />");

            return form;
        }
    }
}

Model对象如下,AccountModel 为页面对象,TestModel 和LogOnModel为form对象,将Form对象作为属性传给页面

 public class AccountModel
    {
        public TestModel Test { get; set; }
        public LogOnModel LogOn { get; set; }
    }
    public class TestModel
    {
        public string MyUserName { get; set; }
        public string MyEmail { get; set; }
        public string MyPassword { get; set; }
        public string MyConfirmPassword { get; set; }
    }
    public class LogOnModel
    {
        [Required]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        public bool RememberMe { get; set; }
    }

actionResult 方法,其中"LogOn"和Registertest"表单名

        [HttpPost]
        [FormActionSelector("LogOn")]
        public ActionResult Index(LogOnModel logOn)
        {
            var account = new AccountModel { LogOn = logOn };
            return View(account);
        }

        [HttpPost]
        [FormActionSelector("Registertest")]
        public ActionResult Index(TestModel test)
        {
            var account = new AccountModel { Test = test };
            return View(account);
        }

页面代码

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MultiFormTest.AccountModel>" %>

<%@ Import Namespace="MultiFormTest" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        <%: ViewData["Message"] %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
            http://asp.net/mvc</a>.
    </p>
      <% using (Html.BeginForm("Registertest"))
       { %>
    <%: Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") %>
    <div>
        <fieldset>
            <legend>Account Information</legend>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.Test.MyUserName)%>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(m => m.Test.MyUserName)%>
                <%: Html.ValidationMessageFor(m => m.Test.MyUserName)%>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.Test.MyEmail)%>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(m => m.Test.MyEmail)%>
                <%: Html.ValidationMessageFor(m => m.Test.MyEmail)%>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.Test.MyPassword)%>
            </div>
            <div class="editor-field">
                <%: Html.PasswordFor(m => m.Test.MyPassword)%>
                <%: Html.ValidationMessageFor(m => m.Test.MyPassword)%>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.Test.MyConfirmPassword)%>
            </div>
            <div class="editor-field">
                <%: Html.PasswordFor(m => m.Test.MyConfirmPassword)%>
                <%: Html.ValidationMessageFor(m => m.Test.MyConfirmPassword)%>
            </div>
            <p>
                <input type="submit" value="Register" />
            </p>
        </fieldset>
    </div>
    <% } %>
    <% using (Html.BeginForm("LogOn"))
       { %>
    <%: Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") %>
    <div>
        <fieldset>
            <legend>Account Information</legend>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.LogOn.UserName) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(m => m.LogOn.UserName)%>
                <%: Html.ValidationMessageFor(m => m.LogOn.UserName)%>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(m => m.LogOn.Password)%>
            </div>
            <div class="editor-field">
                <%: Html.PasswordFor(m => m.LogOn.Password)%>
                <%: Html.ValidationMessageFor(m => m.LogOn.Password)%>
            </div>
            <div class="editor-label">
                <%: Html.CheckBoxFor(m => m.LogOn.RememberMe)%>
                <%: Html.LabelFor(m => m.LogOn.RememberMe)%>
            </div>
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
    </div>
    <% } %>
  
</asp:Content>
HTML代码
<fieldset>
 <legend>Account Information</legend>
            <div class="editor-label">
                <label for="LogOn_UserName">UserName</label>
            </div>
            <div class="editor-field">
                <input id="LogOn_UserName" name="LogOn.UserName" type="text" value="admin" />
      </div>
            <div class="editor-label">
                <label for="LogOn_Password">Password</label>
            </div>
            <div class="editor-field">
                <input id="LogOn_Password" name="LogOn.Password" type="password" />
           </div>
            <div class="editor-label">
                <input id="LogOn_RememberMe" name="LogOn.RememberMe" type="checkbox" value="true" /><input name="LogOn.RememberMe" type="hidden" value="false" />
                <label for="LogOn_RememberMe">RememberMe</label>
            </div>
            <p>
                <input type="submit" value="Log On" />
            </p>
        </fieldset>
可以看到控件的Name 的值是对象.属性(如LogOn.UserName ),MVC识别这种样式,这是我所没想到的
效果:
image

image

image

经测试,有时这种方法得到的对象属性为Null ,不知为什么,很是郁闷,希望大家使用的的话命名等小心一下。不过可以将每个表单做成一个用户控件,控件对象为表单对象就可以避免这个情况。

测试model项目http://u.115.com/file/f1f7377159

免责声明:文章转载自《MVC 一页多个提交表单(Multi_Form in one page)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WAF绕过方法PhpStorm添加PHP代码规范检查CodeSniffer(phpcs)和PHP代码静态分析工具Mess Detector(phpmd)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

HTML中的按钮

html中的五种按钮 (1)<button></button> 表单外调用一个js文件时使用 (2)<input type="button" value=""/> 表单内调用一个js函数时使用 (3)<input type="submit" value=""/> 在表单内提交表单,更多使用(2) (4)<...

SharePoint 2013 图文开发系列之InfoPath入门

本文主要介绍SharePoint 2013中,简单发布InfoPath表单,并添加后台代码,示例比较简单,主要描述的是一个创建InfoPath的过程,而非多么深奥的后台代码,希望能够给初学者带来帮助。 主要过程有 Ø新建一个InfoPath表单 Ø修改表单的信任级别并添加证书 Ø发布到InfoPath得到管理员认证 Ø设计InfoPath布局及添加...

shiro中拦截器机制

8.1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展;所以如果对Filter不熟悉可以参考《Servlet3.1规范》http://www.iteye.com/blogs/subjects/Servlet-3-1了解Filter的工作原理。首先下图是Shiro拦截器的基础类图: 1、NameableFilter Nameab...

Django web编程2 -- 编辑页面内容

你将创建一些表单,让用户能够添加主题和条目,以及编辑既有的条目。你还将学习Django如何防范对基于表单的网页发起的常见攻击,这让你无需花太多时间考虑确保应用程序安全的问题。 然后,我们将实现一个用户身份验证系统。你将创建一个注册页面,供用户创建账户,并让有些页面只能供已登录的用户访问。接下来,我们将修改一些视图函数, 使得用户只能看到自己的数据。你将学习...

防止表单重复提交

1.方法一 在servlet中模拟网络延迟造成表单重复提交 //解决表单重复提交方法 //接收数据 String username = req.getParameter("username"); System.out.println("接收的数据为:"+username);...

前端重点题目汇总

1 . Blob 对象中的type属性表示的文件是 MIME 类型。   Blob构造函数返回一个新的Blob对象,基本语法是 var aBlob = new Blob( array, options );   其中 array 是 ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者...