Jquery 在ASP MVC3和ViewModels中使用[RequiredIf]

Jquery 在ASP MVC3和ViewModels中使用[RequiredIf],jquery,asp.net-mvc-3,validation,conditional,Jquery,Asp.net Mvc 3,Validation,Conditional,我正在MVC应用程序中使用 我有一个viewmodel,它被传递到视图,如下所示: public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule requiredIfRule = new ModelClientValidationRule()

我正在MVC应用程序中使用

我有一个viewmodel,它被传递到视图,如下所示:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    ModelClientValidationRule requiredIfRule = new ModelClientValidationRule();
    requiredIfRule.ErrorMessage = ErrorMessageString;
    requiredIfRule.ValidationType = "requiredif";
    requiredIfRule.ValidationParameters.Add("dependprop", this._propertyName);
    requiredIfRule.ValidationParameters.Add("value", Json.Encode(this._value));     

    yield return requiredIfRule;
}
公共类历史视图模型
{
公共联系人联系人模型{get;set;}
公共帐户帐户模型{get;set;}
公众人物模型{get;set;}
}
我有一堆模型,里面有所有的道具(即contact.cs、account.cs、person.cs)

公共类人物
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共bool IsAdult{get;set;}
[RequiredIf(“IsAdult”、“Yes”、Errormessage=“请留下评论”)]
公共字符串注释{get;set;}
}
RequiredIf
验证在通过viewmodel时似乎不起作用。如果我直接将属性移动到viewmodel
中,效果很好。所有其他
[Required]`属性从模型通过viewmodel工作

那么,我是否需要将所有需要RequiredIf的属性移动到viewmodel中?或者有别的办法吗?

你试过了吗?它支持RequiredIf(以及其他一些),并提供客户端支持。它有时可能有点问题,但最新版本也不错

工作原理与上述相同(我在切换到万无一失之前尝试过)

问题 如果您查看razor视图发出的html,您将看到这里有什么问题

如果没有viewmodel,我们应该生成以下代码(稍微清理):


使用viewmodel,我们可以得到以下结果:


每当一个属性嵌套在另一个属性中时,MVC将构建一个前缀堆栈来生成唯一的ID和名称。您可以看到,在第一种情况下,
IsAdult
足以识别字段,但是一旦它被嵌套,id就发生了变化。在不引人注目的验证(存储在属性中的规则)中,我们需要知道的关于如何验证元素的所有信息都需要在
数据属性中发送,包括如何定位其他属性

解决方案 类上的数据属性永远不应该知道或关心它在什么上下文下被调用,因此它将继续盲目地指出它所依赖的相对属性:

public bool IsAdult{get;set;}
[RequiredIf(“IsAdult”、“Yes”、Errormessage=“请留下评论”)]
公共字符串注释{get;set;}
因此,我们必须在服务器或客户机上建立上下文

服务器上的-不

作为
公共类RequiredIfAttribute:ValidationAttribute,IClientValidatable
的一部分,您将拥有一个发出客户端验证规则的方法,该规则如下所示:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    ModelClientValidationRule requiredIfRule = new ModelClientValidationRule();
    requiredIfRule.ErrorMessage = ErrorMessageString;
    requiredIfRule.ValidationType = "requiredif";
    requiredIfRule.ValidationParameters.Add("dependprop", this._propertyName);
    requiredIfRule.ValidationParameters.Add("value", Json.Encode(this._value));     

    yield return requiredIfRule;
}
请注意,这仍然只是采用普通的旧属性名,并假定它可以用作查找对象的ID

通过做出一些合理的假设,我们可以构建完整的依赖属性id。在这种情况下,requiredif调用元素应该与我们标识的属性在同一范围内(这就是我们如何通过反射在服务器上找到它)

因此,我们将从发送方获取该上下文,删除该属性的名称,并在
$.validator.unobtrusive.adapters.add中添加我们自己的内容,如下所示:

var curId=options.element.id;//获取完整id,即ViewModel_注释
var context=curId.replace(/[^]+$/,“”);//移除最后一个道具,即ViewModel_
var targetProp=options.params['dependprop']//目标名称,即IsAdult
var targetId='#'+context+targetProp;//构建目标ID,即#视图模型#IsAdult
选项.规则[“requiredif”]={
id:targetId,
value:JSON.parse(options.params.value)
};

这将有助于找到正确的客户端属性,然后编写您需要满足的任何其他条件。

如果禁用客户端验证,它是否有效?如果是这样,那么很可能是客户端javascript在嵌套时无法正常工作的问题。另外,您使用的是Mvc.ValidationToolkit代码还是文章中的代码?谢谢(很抱歉延迟重播)我查看了《万无一失》,它太棒了!很高兴它起了作用,但它可能是一辆马车。当你有机会的时候,你可以随意增加答案投票:-)我试着投票,但我还没有15个代表。当我回来时,我会尽量记得回来。