【问题标题】:asp.net MVC 4 multiple post via different formsasp.net MVC 4 通过不同形式发布多个帖子
【发布时间】:2013-04-03 13:33:15
【问题描述】:

现在我明白了

if (IsPost){   //do stuff }

检查该页面上的所有发布方法。但是,我有 2 个不同的表格发布 2 个不同的信息。这些是登录表单和注册表单。

有没有办法可以根据哪种形式检查 IsPost?例如,

if(Login.IsPost){ //do stuff }

但是我将如何定义登录变量?我的表格如下:

<form id="Login" method = "POST">

我试过了:

var Login = Form.["Login"]

没有用。

我将不胜感激。

谢谢。

【问题讨论】:

标签: c# asp.net-mvc forms http-post


【解决方案1】:

在 MVC 视图中,您可以拥有尽可能多的表单和所需的字段。为简单起见,请使用单个视图模型,其中包含页面上每个表单所需的所有属性。请记住,您只能访问您提交的表单中的表单字段数据。因此,如果您在同一页面上有登录表单和注册表单,您可以这样做:

LoginRegisterViewModel.cs

public class LoginRegisterViewModel {
    public string LoginUsername { get; set; }
    public string LoginPassword { get; set; }

    public string RegisterUsername { get; set; }
    public string RegisterPassword { get; set; }
    public string RegisterFirstName { get; set; }
    public string RegisterLastName { get; set; }
}

YourViewName.cshtml

@model LoginRegisterViewModel

@using (Html.BeginForm("Login", "Member", FormMethod.Post, new {})) {

    @Html.LabelFor(m => m.LoginUsername)
    @Html.TextBoxFor(m => m.LoginUsername)

    @Html.LabelFor(m => m.LoginPassword)
    @Html.TextBoxFor(m => m.LoginPassword)

    <input type='Submit' value='Login' />

}

@using (Html.BeginForm("Register", "Member", FormMethod.Post, new {})) {

    @Html.LabelFor(m => m.RegisterFirstName)
    @Html.TextBoxFor(m => m.RegisterFirstName)

    @Html.LabelFor(m => m.RegisterLastName)
    @Html.TextBoxFor(m => m.RegisterLastName)

    @Html.LabelFor(m => m.RegisterUsername)
    @Html.TextBoxFor(m => m.RegisterUsername)

    @Html.LabelFor(m => m.RegisterPassword)
    @Html.TextBoxFor(m => m.RegisterPassword)

    <input type='Submit' value='Register' />

}

MemberController.cs

[HttpGet]
public ActionResult LoginRegister() {
     LoginRegisterViewModel model = new LoginRegisterViewModel();
     return view("LoginRegister", model);
}

[HttpPost]
public ActionResult Login(LoginRegisterViewModel model) {
 //do your login code here
}

[HttpPost]
public ActionResult Register(LoginRegisterViewModel model) {
 //do your registration code here
}

不要忘记,在调用 BeginForm 时,您传递的控制器名称没有附加“控制器”:

@using (Html.BeginForm("Login", "Member", FormMethod.Post, new {}))

代替:

@using (Html.BeginForm("Login", "MemberController", FormMethod.Post, new {}))

【讨论】:

  • 那你怎么做验证?假设您的模型装饰有必需属性并添加了 2 个验证摘要,但是您如何确保第一个摘要中仅包含登录字段,而第二个摘要中仅包含注册字段?而且,通过按登录,您将只验证登录字段?
  • 这不是一个好方法。每个表单都需要 1 个模型绑定,都在同一个视图模型上,并在控制器前面加上每个模型的属性名称
  • 这是正确的一半,错误的一半。你将如何验证你的模型?这怎么可能是一个公认的答案?难以置信。
  • 您将如何使用数据注释进行验证?
  • 问题:不能让viewmodel成为父类,每个表单有两个子类吗?
【解决方案2】:

我只是为每个需要的表单加载一个局部视图(包含一个表单),给每个局部一个不同的视图模型:

  • 页面上的多个表单要求:满足。
  • 每个表单上的 Javascript 非侵入式验证:已完成。

【讨论】:

  • 这种方法有一个问题。任何服务器端验证都会被吞没。
  • 对于那些对此解决方案有疑问的人,请确保您没有在部分视图上使用自动生成的@using (Html.BeginForm()),因为表单提交不起作用,您需要使用更明确的@987654322 @ 反而。谢谢+1
【解决方案3】:

我们可以在点击相应的提交按钮时进行 ajax 发布,而不是提交表单。

@using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { @Id = "Form1" }))
{

}

@using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { @Id = "Form2" }))
{

}

为页面中的每个表单分配不同的 id 属性后,使用如下代码:

$(document).ready( function() {
  var form = $('#Form1');

 $('#1stButton').click(function (event) {

    $.ajax( {
      type: "POST",
      url: form.attr( 'action' ),
      data: form.serialize(),
      success: function( response ) {
        console.log( response );
      }
    } );
  } );
}

在第二个按钮单击事件上重复相同的操作以调用第二个表单的 ajax 发布。

此代码使用 .serialize() 从表单中提取相关数据。

供将来参考,jQuery docs 非常非常好。

注意:您用来触发通过 ajax post 提交表单的事件的按钮不应该是 submit 类型!否则这将永远失败。

【讨论】:

    【解决方案4】:

    您应该让每个&lt;form&gt; 指向具有自己模型参数的单独操作。

    【讨论】:

    • 我可以在同一个视图中有 2 个表单有 2 个模型参数吗?
    • 我不确定你的意思。
    • 我有两个表单 ins default.cshtml 和 IsPost 检查该页面,但是两个表单发布不同,我将如何在同一页面上制作不同的模型?
    • 是的,与 WebForms 世界中一个页面上只允许“一个表单”不同,MVC 允许您在页面上提交多个表单以提交各自的操作
    • @user2238691:ViewModel 什么都不做。每个表单都应该发布到不同的操作方法。
    【解决方案5】:
    使用此示例可防止在使用具有不同控制器操作的多个表单发布时进行不必要/意外的验证检查。


    寻找什么

    • 本质上,此代码利用模型内部的布尔值来标记在表单发布中调用了哪个控制器操作。
    • 注意我使用方法助手 IsActionLogin() 和 IsActionRegister() 设置的嵌套模型以及 [Is Action Login] 和 [Is Action Register] 布尔属性的使用。在相应的控制器动作中只会调用一个。
    • 注意模型中的 sReturnURL 属性。此属性存储以前的导航 url,并与登录和注册控制器操作共享。这将允许我们返回到用户在必须登录之前离开的页面。


      /* Begin Model logic */
      public class LoginRegisterModel
      {
          public LoginModel LoginModel { get; set; }
          public RegisterModel RegisterModel { get; set; }
          public string sReturnURL { get; set; }
          public bool bIsActionLogin { get; set; }
          public bool bIsActionRegister { get; set; }
          public void IsActionLogin()
          {
              bIsActionLogin = true;
              bIsActionRegister = false;
          }
          public void IsActionRegister()
          {
              bIsActionLogin = false;
              bIsActionRegister = true;
          }
      }
      
      public class LoginRegisterModel
      {
          public LoginModel LoginModel { get; set; }
          public RegisterModel RegisterModel { get; set; }
          public string sReturnURL { get; set; }
          public bool bIsActionLogin { get; set; }
          public bool bIsActionRegister { get; set; }
          public void IsActionLogin()
          {
              bIsActionLogin = true;
              bIsActionRegister = false;
          }
          public void IsActionRegister()
          {
              bIsActionLogin = false;
              bIsActionRegister = true;
          }
      }
      
      public class RegisterModel
      {
          [Required]
          [Display(Name = "Email")]
          [RegularExpression("^[a-zA-Z0-9_\\.-]+@([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$", ErrorMessage = "Email is not valid.")]
          public string UserName { get; set; }
      
          [Required]
          [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
          [DataType(DataType.Password)]
          [Display(Name = "Password")]
          public string Password { get; set; }
      
          [Required]
          [DataType(DataType.Password)]
          [Display(Name = "Confirm Password")]
          [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
          public string ConfirmPassword { get; set; }
      }
          /*End Model logic*/
      
          /*Begin Controller Logic*/
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult Login(LoginRegisterModel model, string sReturnURL)
          {
              model.IsActionLogin(); //flags that you are using Login Action
              //process your login logic here
          }
      
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult Register(LoginRegisterModel model, string sReturnURL)
          {
              model.IsActionRegister(); //flag Action Register action
              //process your register logic here
          }
          /*End Controller Logic*/
      
      /*Begin View Logic*/
      @model eCommerce.Models.LoginRegisterModel
      @{  
          /*Place this view logic in both the Login.cshtml and Register.cshtml. Now use the last Action called as a Boolean check against your validation messages, so unnecessary validation messages don't show up.*/
          bool bLoginCallBack = Model.bIsActionLogin; 
          bool bRegisterCallBack = Model.bIsActionRegister;
          MvcHtmlString htmlIcoWarn = new MvcHtmlString(" font awesome icon here ");
          MvcHtmlString htmlIcoHand = new MvcHtmlString(" font awesome icon here ");
      }
      
          @using (Html.BeginForm("Login", "Account", new { sReturnURL = Model.sReturnURL }))
          {
              @Html.AntiForgeryToken()
              if (bLoginCallBack)
              {
                  MvcHtmlString htmlLoginSummary = Html.ValidationSummary(true);
                  if (!htmlLoginSummary.ToHtmlString().Contains("display:none"))
                  {
                  @:@(htmlIcoWarn)@(htmlLoginSummary)
                  }
              }
              @Html.LabelFor(m => m.LoginModel.UserName)
              @Html.TextBoxFor(m => m.LoginModel.UserName, new { @placeholder = "Email" })
          @if (bLoginCallBack)
          {
              MvcHtmlString htmlLoginUsername = Html.ValidationMessageFor(m => m.LoginModel.UserName);
              if (!htmlLoginUsername.ToHtmlString().Contains("field-validation-valid"))
              {
              @:@(htmlIcoHand) @(htmlLoginUsername)
              }
          }
              @Html.LabelFor(m => m.LoginModel.Password)
              @Html.PasswordFor(m => m.LoginModel.Password, new { @placeholder = "Password" })
          @if (bLoginCallBack)
          {
              MvcHtmlString htmlLoginPassword = Html.ValidationMessageFor(m => m.LoginModel.Password);
              if (!htmlLoginPassword.ToHtmlString().Contains("field-validation-valid"))
              {
              @:@(htmlIcoHand) @(htmlLoginPassword)
              }
          }
                  @Html.CheckBoxFor(m => m.LoginModel.RememberMe)
                  @Html.LabelFor(m => m.LoginModel.RememberMe)
              <button type="submit" class="btn btn-default">Login</button>
          }
      @using (Html.BeginForm("Register", "Account", new { sReturnURL = Model.sReturnURL }))
      {
          @Html.AntiForgeryToken()
      
          if (bRegisterCallBack)
          {
              MvcHtmlString htmlRegisterSummary = Html.ValidationSummary(true);
              if (!htmlRegisterSummary.ToHtmlString().Contains("display:none"))
              {
                  @:@(htmlIcoWarn)@(htmlRegisterSummary)
              }
          }
              @Html.LabelFor(m => m.RegisterModel.UserName)
              @Html.TextBoxFor(m => m.RegisterModel.UserName, new { @placeholder = "Email" })
          @if (bRegisterCallBack)
          {
              MvcHtmlString htmlRegisterUsername = Html.ValidationMessageFor(m => m.RegisterModel.UserName);
              if (!htmlRegisterUsername.ToHtmlString().Contains("field-validation-valid"))
              {
              @:@(htmlIcoHand) @(htmlRegisterUsername)
              }
          }
              @Html.LabelFor(m => m.RegisterModel.Password)
              @Html.PasswordFor(m => m.RegisterModel.Password, new { @placeholder = "Password" })
          @if (bRegisterCallBack)
          {
              MvcHtmlString htmlRegisterPassword = Html.ValidationMessageFor(m => m.RegisterModel.Password);
              if (!htmlRegisterPassword.ToHtmlString().Contains("field-validation-valid"))
              {
              @:@(htmlIcoHand) @(htmlRegisterPassword)
              }
          }
              @Html.LabelFor(m => m.RegisterModel.ConfirmPassword)        @Html.PasswordFor(m => m.RegisterModel.ConfirmPassword, new { @placeholder = "Confirm Password" })                
          @if (bRegisterCallBack)
          {
              MvcHtmlString htmlRegisterConfirmPassword = Html.ValidationMessageFor(m => m.RegisterModel.ConfirmPassword);
              if (!htmlRegisterConfirmPassword.ToHtmlString().Contains("field-validation-valid"))
              {
              @:@(htmlIcoHand) @(htmlRegisterConfirmPassword)
              }
              <button type="submit" class="btn btn-default">Signup</button>
          }
      }
      /*End View Logic*/
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 2013-01-21
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 1970-01-01
      相关资源
      最近更新 更多