如何解决使用多种表单时验证失败
我正在使用this construct在同一视图中托管多个表单:
当我提交第一个表单而不输入凭据时,验证失败。表单以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
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
作为输入,但从用户界面提供SignIn
或SignUp
模型:
使用这种方法,您无需更改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 举报,一经查实,本站将立刻删除。