我有一个ASP.NET MVC 3.0应用程序。
在应用程序内部,我有一个登录视图,它通过LoginViewModel
类强类型化。此外,登录视图可以由两种不同类型的人Employees and Management
访问。
视图显示在< table >
中。用户必须首先(从2个单选按钮)选择他是什么类型的用户(Employee or Management
),并从选择中更改UI并显示(显示/隐藏)某些div
。
如果选择Employee
,我会要求Employee Number
和Password
。
如果选择Management
,我会要求UserCode
和Password
。
LoginViewModel有4个属性:
UserType
(代表所选的单选按钮)EmployeeNumber
(代表员工的文本框)UserCode
(代表管理的文本框)Password
(代表密码的文本框,无论选择谁)由于UI根据所选的单选按钮而更改,因此我无法在EmployeeNumber和UserCode属性上使用[Required]
属性,因为如果我这样做,< form >
将不会提交(因为其中一个)字段将被隐藏)。
为了克服这个限制/问题,我必须删除两个属性上的[Required]
属性,并且可能是这个客户端。
为了记录,我没有使用MicrosoftMVCValidation.js
,而是使用jquery.validate.min.js and jquery.validate.unobtrusive.js
问题1)
在线搜索示例时,我见过很多这样的文件:
的jquery。的不显眼 -ajax.min.js
此文件的目的是什么以及它与客户端验证(如果有)的相关性是什么? 我真的需要它吗?不应该jquery.validate.min.js和jquery.validate.unobtrusive.js足够吗?
问题2)
我知道可以编写自定义验证属性并将其放在EmployeeNumber或UserCode属性上,但如果我这样做(并且知道我将在UI中隐藏其中一个),我该如何阻止自己获取与[Required]
属性相同的问题? (意思是无法提交表格,因为隐藏了一个表格)
我可以直接在View中执行此操作吗?有人会如此友善地向我展示一个简单的例子吗?
由于
哦,是的...... jquery-1.7.1.min.js包含在主布局中(如果有人问的话)。
答案 0 :(得分:1)
有几种方法可以解决这个问题。
首先,您可以创建一个自定义属性,以查找模型中布尔值的值。布尔值将由经理或员工的单选按钮控制。如果这个布尔值为true,那么它验证它是否为假,然后它忽略它(基本上总是将有效设置为true)。您可以将此属性称为ConditionalRequiredAttribute。
这将是这样的。
public class MyModel {
public bool IsManager { get; set; }
[ConditionalRequired("IsManager", false)] // validates if IsManager is false
public int? EmployeeNumber { get; set; }
[ConditionalRequired("IsManager", true)] // validates if IsManager is True
public string UserCode { get; set; }
{
至于如何创建此属性,您可以从此处描述的属性http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2
开始另一种方法是使用Fluent Validation并再次根据复选框的值进行验证。
另一种方法是取消验证,并在模型中进行检查。
答案 1 :(得分:0)
您无需删除RequiredAttribute
。而是在LoginViewModel
中将这两个属性设置为虚拟。然后使用Employee
模型和Management
模型覆盖相应的属性,并根据需要设置RequiredAttribute
。您仍然可以使用相同的Action,然后根据选择使用UpdateModel
填充适当类型的模型。这不会在客户端的那些字段上给你验证,但你可以用javascript处理它,服务器端将正常为你处理。
答案 2 :(得分:0)
要回答您的第一个问题,jquery.unobtrusive-ajax.min.js不适用于不显眼的验证。它是用于使用@Ajax html帮助器(@ Ajax.Form等)。
要回答你的第二个问题,我实际上会为此创建2个完全不同的视图模型和相应的表单。当用户选择单选按钮时,显示正确的表单。这意味着,不要将Employee和Management组合到同一个LoginViewModel中。然后,您可以在两者之间分别处理验证以及其他视图逻辑。
更新
要回答有关强类型的问题,您可以创建2个不同的(部分)视图。一个人有@model EmployeeLoginViewModel,另一个人有@model ManagementLoginViewModel。要在单个页面上呈现它们,有几种不同的方法。您可以拥有一个LoginViewModel,其中包含ManagementLoginViewModel和EmployeeLoginViewModel各自的实例,然后使用@ Html.EditorFor(m =&gt; m.Employee)和@ Html.EditorFor(m =&gt; m.Management)。但是,只有部分视图位于EditorTemplates文件夹中时,此方法才有效。
另一种方法是使用@ Html.Action(),并使用2种不同的控制器操作方法来返回部分视图。
答案 3 :(得分:0)
结论:
在阅读了Olivehour,Yuriy和Mystere Man对此的不同看法之后,我得出了以下结论:
我相信我最初的做法是错误的,所以我决定重新考虑整个事情并从头开始。
我决定遵循olivehour的方法并创建一个复合/父 ViewModel,它将包含两个ViewModel(一个用于Employee,一个用于Management)。其中每个都有表单定义和适当的[Attributes]。
父视图将强烈键入复合ViewModel。然后,View将调用两个部分(同时并排显示两个表单),允许相应的用户决定使用哪个表单。
请注意,接受的答案是olivehour,因为我决定改变我的方法,但我强烈建议人们(如果有人甚至读这篇文章)在完整的验证指南上关注Mystere Man的链接。
第1部分和第2部分是每个人必读的内容!
如果我没有决定改变我的方法,我会选择Mystere Man的解决方案。
由于