MVC3 验证 - 需要组中的一个
给定以下视图模型:
public class SomeViewModel
{
public bool IsA { get; set; }
public bool IsB { get; set; }
public bool IsC { get; set; }
//... other properties
}
我希望创建一个自定义属性来验证至少一个可用属性是否为真。我设想能够将属性附加到属性并分配组名称,如下所示:
public class SomeViewModel
{
[RequireAtLeastOneOfGroup("Group1")]
public bool IsA { get; set; }
[RequireAtLeastOneOfGroup("Group1")]
public bool IsB { get; set; }
[RequireAtLeastOneOfGroup("Group1")]
public bool IsC { get; set; }
//... other properties
[RequireAtLeastOneOfGroup("Group2")]
public bool IsY { get; set; }
[RequireAtLeastOneOfGroup("Group2")]
public bool IsZ { get; set; }
}
我想在表单提交之前在客户端进行验证,因为表单中的值会发生变化,这就是为什么我更喜欢避免类级别如果可能的话属性。
这将需要服务器端和客户端验证来查找具有作为自定义属性的参数传入的相同组名称值的所有属性。这可能吗?非常感谢任何指导。
Given the following viewmodel:
public class SomeViewModel
{
public bool IsA { get; set; }
public bool IsB { get; set; }
public bool IsC { get; set; }
//... other properties
}
I wish to create a custom attribute that validates at least one of the available properties are true. I envision being able to attach an attribute to a property and assign a group name like so:
public class SomeViewModel
{
[RequireAtLeastOneOfGroup("Group1")]
public bool IsA { get; set; }
[RequireAtLeastOneOfGroup("Group1")]
public bool IsB { get; set; }
[RequireAtLeastOneOfGroup("Group1")]
public bool IsC { get; set; }
//... other properties
[RequireAtLeastOneOfGroup("Group2")]
public bool IsY { get; set; }
[RequireAtLeastOneOfGroup("Group2")]
public bool IsZ { get; set; }
}
I would like to validate on the client-side prior to form submission as values in the form change which is why I prefer to avoid a class-level attribute if possible.
This would require both the server-side and client-side validation to locate all properties having identical group name values passed in as the parameter for the custom attribute. Is this possible? Any guidance is much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一种继续进行的方法(还有其他方法,我只是举例说明一种与您的视图模型相匹配的方法):
现在,让我们定义一个控制器:
和一个视图:
剩下的最后一部分是为客户端注册适配器侧面验证:
根据您的具体要求,可能会调整代码。
Here's one way to proceed (there are other ways, I am just illustrating one that would match your view model as is):
Now, let's define a controller:
and a view:
The last part that's left would be to register adapters for the client side validation:
Based on your specific requirements the code might be adapted.
使用 jquery-validation 团队的
require_from_group
:jQuery-validation 项目在 src 文件夹中有一个名为 additional 的子文件夹>。
您可以在此处查看。
在该文件夹中,我们有许多不常见的附加验证方法,这就是默认情况下不添加它们的原因。
正如您在该文件夹中看到的,它存在如此多的方法,您需要通过选择您实际需要的验证方法来选择。
根据您的问题,您需要的验证方法被命名为来自附加文件夹的
require_from_group
。只需下载位于此处的关联文件并将其放入您的
Scripts
应用程序文件夹中。该方法的文档对此进行了解释:
为什么需要选择此实现:
此验证方法是通用的,适用于每个输入(文本、复选框、单选框等)、文本区域和
选择
。 此方法还允许您指定需要填充的最小输入数量,例如我创建了两个类
RequireFromGroupAttribute
和RequireFromGroupFieldAttribute
这将帮助您在服务器端和客户端验证上RequireFromGroupAttribute
类定义RequireFromGroupAttribute
仅派生自Attribute
。该类仅用于配置,例如设置验证需要填写的字段数量。您需要向此类提供 CSS 选择器类,验证方法将使用该类来获取同一组中的所有元素。由于必填字段的默认数量为 1,因此,如果指定组中的最低要求大于默认数量,则此属性仅用于装饰您的模型。RequireFromGroupFieldAttribute
类定义RequireFromGroupFieldAttribute
派生自ValidationAttribute
并实现IClientValidatable
。您需要在模型中参与组验证的每个属性上使用此类。您必须传递 css 选择器类。如何在视图模型中使用它?
在您的模型中,以下是如何使用它:
默认情况下,您不需要使用
RequireFromGroupAttribute
装饰您的模型,因为默认的必填字段数量为 1。但是如果您想要多个必填字段与 1 不同,您可以执行以下操作:如何在视图代码中使用它?
请注意,您在使用
RequireFromGroupField
属性时指定的组选择器将在您的视图中使用,方法是将其指定为组中涉及的每个输入中的类。这就是服务器端验证的全部内容。
我们来谈谈客户端验证。
如果您检查
RequireFromGroupFieldAttribute
类中的GetClientValidationRules
实现,您将看到我使用的是字符串requirefromgroup
而不是require_from_group
作为ValidationType
属性的方法名称。这是因为 ASP.Net MVC 只允许验证类型的名称包含字母数字字符,并且不能以数字开头。因此,您需要添加以下 javascript:javascript 部分非常简单,因为在适配器函数的实现中,我们只需将验证委托给正确的
require_from_group
方法。因为它适用于每种类型的
input
、textarea
和select
元素,所以我可能认为这种方式更通用。希望有帮助!
Use of
require_from_group
from jquery-validation team:jQuery-validation project has a sub-folder in src folder called additional.
You can check it here.
In that folder we have a lot of additional validation methods that are not common that is why they're not added by default.
As you see in that folder it exists so many methods that you need to choose by picking which validation method you actually need.
Based on your question, the validation method you need is named
require_from_group
from additional folder.Just download this associated file which is located here and put it into your
Scripts
application folder.The documentation of this method explains this:
Why you need to choose this implementation :
This validation method is generic and works for every
input
(text, checkbox, radio etc),textarea
andselect
. This method also let you specify the minimum number of required inputs that need to be filled e.gI created two classes
RequireFromGroupAttribute
andRequireFromGroupFieldAttribute
that will help you on both server-side and client-side validationsRequireFromGroupAttribute
class definitionRequireFromGroupAttribute
only derives fromAttribute
. The class is use just for configuration e.g. setting the number of fields that need to be filled for the validation. You need to provide to this class the CSS selector class that will be used by the validation method to get all elements on the same group. Because the default number of required fields is 1 then this attribute is only used to decorate your model if the minimum requirement in the spcefied group is greater than the default number.RequireFromGroupFieldAttribute
class definitionRequireFromGroupFieldAttribute
which derives fromValidationAttribute
and implementsIClientValidatable
. You need to use this class on each property in your model that participates to your group validation. You must pass the css selector class.How to use it in your view model?
In your model here is how to use it :
By default you don't need to decorate your model with
RequireFromGroupAttribute
because the default number of required fields is 1. But if you want a number of required fields to be different to 1 you can do the following :How to use it in your view code?
Notice the group selector you specified when using
RequireFromGroupField
attribute is use in your view by specifing it as a class in each input involved in your groups.That is all for the server side validation.
Let's talk about the client side validation.
If you check the
GetClientValidationRules
implementation inRequireFromGroupFieldAttribute
class you will see I'm using the stringrequirefromgroup
and notrequire_from_group
as the name of method for theValidationType
property. That is because ASP.Net MVC only allows the name of the validation type to contain alphanumeric char and must not start with a number. So you need to add the following javascript :The javascript part is really simple because in the implementation of the adaptater function we just delegate the validation to the correct
require_from_group
method.Because it works with every type of
input
,textarea
andselect
elements, I may think this way is more generic.Hope that helps!
我在我的应用程序中实现了 Darin 的出色答案,只是我将其添加为字符串而不是布尔值。这适用于姓名/公司或电话/电子邮件等内容。我很喜欢它,除了一点点挑剔。
我尝试在没有工作电话、移动电话、家庭电话或电子邮件的情况下提交表格。我在客户端收到四个单独的验证错误。这对我来说很好,因为它可以让用户确切地知道可以填写哪些字段来消除错误。
我输入了一个电子邮件地址。现在,电子邮件下的单一验证消失了,但电话号码下的三个验证仍然存在。这些也不再是错误。
因此,我重新分配了检查验证的 jQuery 方法来解决这个问题。代码如下。希望它能帮助某人。
I implemented Darin's awesome answer into my application, except I added it for strings and not boolean values. This was for stuff like name/company, or phone/email. I loved it except for one minor nitpick.
I tried to submit my form without a work phone, mobile phone, home phone, or email. I got four separate validation errors client side. This is fine by me because it lets the users know exactly what field(s) can be filled in to make the error go away.
I typed in an email address. Now the single validation under email went away, but the three remained under the phone numbers. These are also no longer errors anymore.
So, I reassigned the jQuery method that checks validation to account for this. Code below. Hope it helps someone.
我知道这是一个旧线程,但我刚刚遇到了同样的场景,找到了一些解决方案,并看到了一个解决马特上面问题的解决方案,所以我想我会分享给那些遇到这个答案的人。查看:MVC3 不显眼的输入验证组
I know this is an old thread but I just came across the same scenario and found a few solutions and saw one that solves Matt's question above so I thought I would share for those who come across this answer. Check out: MVC3 unobtrusive validation group of inputs