Asp.net mvc 使用多个表单时验证失败

Asp.net mvc 使用多个表单时验证失败,asp.net-mvc,validation,asp.net-mvc-5,Asp.net Mvc,Validation,Asp.net Mvc 5,我使用在同一视图中承载多个表单: 当我提交第一个表单而不输入凭据时,验证失败。表单作为GET重新加载,URL为/home/signin,预期的错误消息不会显示 控制器的ModelState如预期的那样无效,但我不明白为什么不将此状态传递回视图 我做错了什么?如何使验证与多个表单一起工作 这是我的密码: 控制器 Imports System.Threading.Tasks Imports System.Web.Mvc Imports Website.ViewModels.Home Import

我使用在同一视图中承载多个表单:

当我提交第一个表单而不输入凭据时,验证失败。表单作为GET重新加载,URL为
/home/signin
,预期的错误消息不会显示

控制器的
ModelState
如预期的那样无效,但我不明白为什么不将此状态传递回视图

我做错了什么?如何使验证与多个表单一起工作

这是我的密码:


控制器

Imports System.Threading.Tasks
Imports System.Web.Mvc
Imports Website.ViewModels.Home
Imports Microsoft.AspNet.Identity.Owin

Namespace Controllers.Home
  Partial Public Class HomeController
    <AllowAnonymous>
    Public Function Index() As ActionResult
      Dim oViewModel As SignInOrSignUp

      oViewModel = New SignInOrSignUp

      Return Me.View("Index", oViewModel)
    End Function

    <HttpPost>
    <ValidateAntiForgeryToken>
    Public Async Function SignIn(Model As SignIn) As Task(Of ActionResult)
      Dim oViewModel As SignInOrSignUp
      Dim eStatus As SignInStatus
      Dim oAction As ActionResult

      oViewModel = New SignInOrSignUp With {.SignIn = Model}

      If Me.ModelState.IsValid Then
        eStatus = Await Me.SignInManager.PasswordSignInAsync(Model.Username, Model.Password, isPersistent:=False, shouldLockout:=False)

        If eStatus = SignInStatus.Success Then
          oAction = Me.Redirect("www.domain.com")
        Else
          Me.ModelState.AddModelError("", "Invalid signin attempt.")
          oAction = Me.View("Index", oViewModel)
        End If
      Else
        oAction = Me.View("Index", oViewModel)
      End If

      Return oAction
    End Function
  End Class
End Namespace

但如果可以在同一视图中使用多个表单,我仍然希望使用内置验证机制。

有两件事可以尝试:

1。将验证摘要放在页面上:

使用此选项,您不会更改控制器中的任何内容,但会将错误摘要放在页面上。您将不会突出显示字段,但仍可以显示所有错误,如:

<body>
  <div class="row">
    <div class="wrapper">
      @Html.ValidationSummary(false)
      ...
    </div>
  </div>
</body>

除非涉及到一些复杂的验证,否则这种方法将非常有效

行得通,谢谢。一旦网站允许我这样做,我会尽快发送赏金。与此同时,我对一些事情感到好奇。您说“从UI提供登录或注册模型”,但我是如何做到这一点的?是否在这里:
Html.BeginForm(“signin”、“home”、FormMethod.Post,新增为{.id=“SignInfo”})
?如果是这样,那似乎很奇怪,因为这里没有提到模型,只有一个
操作
和一个
控制器
。实际上,当您使用表单中的任何字段并提交表单时,将提交表单账单,而不是页面上的任何其他表单。因此,您只向server.Aha发送登录/注册模型数据。这就解释了,谢谢。模型活页夹比我聪明:-)
@ModelType ViewModels.Home.SignInOrSignUp

@Code
  Layout = Nothing
End Code

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Website</title>
  @Scripts.Render("~/scripts/bootstrap")
  @Scripts.Render("~/scripts/jquery")
  @Styles.Render("~/styles/bootstrap")
  @Styles.Render("~/styles/home")
</head>
<body>
  <div class="row">
    <div class="wrapper">
      <div class="section">
        <h5>Sign in here</h5>
        <div class="box">
          <div class="titlebar">Sign In</div>
          @Using (Html.BeginForm("signin", "home", FormMethod.Post, New With {.id = "SignInForm"}))
            @Html.AntiForgeryToken
            @Html.EditorFor(Function(M) Model.SignIn)
            @<div class="button">
              <input type="submit" value="Sign In" Class="button" />
            </div>
            @<div class="anchor">
              <a href="/">Forgot your password?</a>
            </div>
          End Using
        </div>
      </div>
      <div class="section">
        <h5>Or enter your City Code here</h5>
        <div class="box">
          <div class="titlebar">Sign Up</div>
          @Using (Html.BeginForm("signup", "home", FormMethod.Post, New With {.id = "SignUpForm"}))
            @Html.AntiForgeryToken
            @Html.EditorFor(Function(M) Model.SignUp)
            @<div class="button">
              <input type="submit" value="Continue" Class="button" />
            </div>
          End Using
        </div>
      </div>
    </div>
  </div>
</body>
</html>
@Code
  If IsPost AndAlso Request.Path = "/home/signin" AndAlso Model.SignIn.Username.IsNothing Then
    @Html.ValidationMessageFor(Function(Model) Model.SignIn.Username, "Username is required", New With {.class = "text-danger"})
  End If
End Code
<body>
  <div class="row">
    <div class="wrapper">
      @Html.ValidationSummary(false)
      ...
    </div>
  </div>
</body>
Namespace Controllers.Home
  Partial Public Class HomeController
    ...
    <HttpPost>
    <ValidateAntiForgeryToken>
    Public Async Function SignIn(Model As SignInOrSignUp) As Task(Of ActionResult)
       ...
    End Function
        
    <HttpPost>
    Public Async Function SignUp(Model As SignInOrSignUp) As Task(Of ActionResult)
       ...
    End Function
  End Class
End Namespace