【发布时间】:2021-12-19 04:06:25
【问题描述】:
我正在实现一个自定义验证属性。此属性不仅查看应用它的属性的值,还查看另一个属性的值。另一个属性由其名称指定。
我需要找到一种方法来获取其他属性的输入将在最终 HTML 输出中具有的完整 id。
这是我的验证属性的简化版本:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MyCustomValidationAttribute : ValidationAttribute, IClientModelValidator
{
private string _otherPropertyName;
public MyCustomValidationAttribute(string otherPropertyName)
{
_otherPropertyName = otherPropertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var otherProperty = context.ObjectInstance.GetType().GetProperty(_otherPropertyName);
var otherPropertyValue = Convert.ToString(otherProperty.GetValue(context.ObjectInstance, null));
// Validation logic...
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-mycustomvalidation", errorMessage);
// THIS ROW NEEDS TO BE FIXED
MergeAttribute(context.Attributes, "data-val-mycustomvalidation-otherpropertyname", _otherProperyName);
}
private void MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (!attributes.ContainsKey(key))
{
attributes.Add(key, value);
}
}
}
这演示了它是如何在模型类中使用的:
public class Report
{
[MyCustomValidation("Value2", ErrorMessage = "Error...")]
public string Value1 { get; set; }
public string Value2 { get; set; }
}
这是确保验证也在客户端完成的 JavaScript:
$.validator.addMethod('mycustomvalidation',
function (value, element, parameters) {
var otherPropertyValue = $('#' + parameters.otherpropertyname).val();
// Validation logic...
});
$.validator.unobtrusive.adapters.add('mycustomvalidation', ['otherpropertyname'],
function (options) {
options.rules.mycustomvalidation = options.params;
options.messages['mycustomvalidation'] = options.message;
});
带有表单的页面/视图的视图模型如下所示:
public MyViewModel
{
public Report MyReport { get; set; }
}
请注意,我没有使用 Report 作为我的视图模型,而是作为视图模型中属性的类型。这很重要,因为这是我问题的根源......
视图中显示 Value1 输入的代码并不奇怪(我使用的是 Razor Pages):
<div>
<label asp-for="MyReport.Value1"></label>
<input asp-for="MyReport.Value1" />
<span asp-validation-for="MyReport.Value1"></span>
</div>
然后输出变成:
<label for="MyReport_Value1">Value1</label>
<input
type="text"
id="MyReport_Value1"
name="MyReport.Value1"
data-val="true"
data-val-mycustomvalidation="Error..."
data-val-mycustomvalidation-otherpropertyname="Value2"
value=""
>
<span
data-valmsg-for="MyReport.Value1"
data-valmsg-replace="true"
class="text-danger field-validation-valid"
></span>
所以问题在于,在 HTML 输出中我需要 data-val-mycustomvalidation-otherpropertyname 为“MyReport_Value2”,而不仅仅是“Value2”。否则验证代码将无法找到第二个 HTML 输入(id 为 MyReport_Value2)并执行验证。
我认为这必须在属性类的 AddValidation() 方法中完成,但我如何获得 HTML 输入将收到的全名?
我猜有一些方法可以通过使用 context 参数来获得它。我见过类似“*.TemplateInfo.GetFullHtmlFieldId(PropertyName)”的例子,但我无法让它工作。
感谢任何帮助!
【问题讨论】:
标签: asp.net-core validation razor-pages