Kin*_*sin 5 c# reflection validation asp.net-mvc custom-attributes
在我的MVC项目中,我有不同的自定义验证属性.其中之一是检查属性的值与另一个属性的值.
正如许多文章中所述,我添加了类似的内容
result.ValidationParameters.Add("otherproperty", _otherPropertyHtml);
result.ValidationParameters.Add("comparetype", _compareType);
result.ValidationParameters.Add("equalitytype", _equalityType);
Run Code Online (Sandbox Code Playgroud)
返回的ModelClientValidationRule对象.
我现在的问题是,如果我要检查的属性被封装在另一个对象中,验证将无效.
如果我创造类似的东西
@Html.TextBoxFor(m => m.ValueOne)
@Html.TextBoxFor(m => m.ValueTwo)
Run Code Online (Sandbox Code Playgroud)
验证将在呈现时正常工作
data-val-otherproperty="ValueTwo"
Run Code Online (Sandbox Code Playgroud)
我的问题是以下几点
@Html.TextBoxFor(m => m.IntermediateObject.ValueOne)
@Html.TextBoxFor(m => m.IntermediateObject.ValueTwo)
Run Code Online (Sandbox Code Playgroud)
这将呈现两个带有名称IntermediateObject_ValueOne和的文本框IntermediateObject.ValueTwo.但仍然是第一个文本框的data-val-otherproperty ="ValueOne".
如何才能实现,这data-val-otherproperty一直是其他财产的正确名称?
我的想法类似于HtmlHelper <>.NameFor(m => ...)或使用反射的东西?
更新1 - 根据评论的要求添加代码
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)]
public class CustomCompareToOther : ValidationAttribute, IClientValidatable
{
// private backing-field
private readonly string _otherPropertyName;
// constructor
public OemCompareToOther(string otherPropertyName)
{
_otherPropertyName = otherPropertyName;
}
// implementation of IClientValidatable
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var result = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "customcomparetoother"
};
// add the property-name so it is known when rendered for client-side validation
result.ValidationParameters.Add("otherproperty", _otherPropertyHtml); // here I would need IntermediateObject.ValueTwo instead of only ValueTwo
yield return result;
}
}
Run Code Online (Sandbox Code Playgroud)
模型级的用法是
public class MyModel
{
[CustomCompareToOther("ValueOTwo", CompareType.NotEqual, PropertyType.String)]
public string ValueOne { get; set; }
[CustomCompareToOther("ValueTwo", CompareType.NotEqual, PropertyType.String)]
public string ValueTwo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
而我将在我的视图中添加的内容就像是
public class ViewModel
{
public MyModel IntermediateObject { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
用过例如return View(new ViewModel()).所以,在渲染的HTML中我会有一个输入
<input type="text" name="IntermediateObject_ValueOne" id="IntermediateObject.ValueOne" data-val-customcomparetoother-otherpropertyname="ValueTwo" />
<input type="text" name="IntermediateObject_ValueTwo" id="IntermediateObject.ValueTwo" data-val-customcomparetoother-otherpropertyname="ValueOne" />
Run Code Online (Sandbox Code Playgroud)
但是我需要
<input type="text" name="IntermediateObject_ValueOne" id="IntermediateObject.ValueOne" data-val-customcomparetoother-otherpropertyname="IntermediateObject.ValueTwo" />
<input type="text" name="IntermediateObject_ValueTwo" id="IntermediateObject.ValueTwo" data-val-customcomparetoother-otherpropertyname="IntermediateObject.ValueOne" />
Run Code Online (Sandbox Code Playgroud)
在HTML中,所以javascript-validation可以正确获取其他属性.
小智 2
您可以使用[Compare("PropertyName")]数据注释。
视图模型中的示例:
[Display(Name = "New Password")]
[DataType(DataType.Password)]
public string NewPassword { get; set; }
[Display(Name = "Confirm Password")]
[DataType(DataType.Password)]
[Compare("NewPassword")]
public string PasswordConfirmation { get; set; }
Run Code Online (Sandbox Code Playgroud)
只需记住将 System.ComponentModel.DataAnnotations 命名空间添加到您的 using 语句中