微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用多种表单时验证失败

如何解决使用多种表单时验证失败

我正在使用this construct在同一视图中托管多个表单:

enter image description here

当我提交第一个表单而不输入凭据时,验证失败。表单以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

viewmodel

Imports System.ComponentModel.DataAnnotations

Namespace viewmodels.Home
  Public Class SignIn
    <required(ErrorMessage:="User Name is required.")>
    <display(Name:="User Name")>
    Public Property Username As String

    <required>
    Public Property Password As String

    <display(Name:="Remember Me")>
    Public Property RememberMe As Boolean
  End Class
End Namespace

查看

@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",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

但是我仍然想使用内置的验证机制,如果可以在同一视图中使用多种形式的话。

解决方法

您可以尝试两种方法:

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

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

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

这不是一个优雅的解决方案!

2。在控制器中,使用SignInOrSignUp作为输入,但从用户界面提供SignInSignUp模型:

使用这种方法,您无需更改vbhtml / cshtml文件,因为在控制器方法上的参数类型只是您要更改的地方,它将保留下来:

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

除非涉及一些复杂的验证,否则此方法将像魅力一样起作用!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。