Я выполняю проверку для группы полей, в моем случае одно из этих трех полей является обязательным.
Я выполняю пользовательскую аннотацию данных.
Мои метаданные следующие. В мои метаданные я поместил эту аннотацию данных, которую я хочу настроить.
public class document
{
[RequireAtLeastOneOfGroupAttribute("group1")]
public long? idPersons { get; set; }
[RequireAtLeastOneOfGroupAttribute("group1")]
public int? idComp { get; set; }
[RequireAtLeastOneOfGroupAttribute("group1")]
public byte? idRegister { get; set; }
public bool other1{ get; set; }
.
public string otherx{ get; set; }
}
С другой стороны, я создал класс с именем RequireAtLeastOneOfGroupAttribute
со следующим кодом.
[AttributeUsage(AttributeTargets.Property)]
public class RequireAtLeastOneOfGroupAttribute : ValidationAttribute, IClientValidatable
{
public string GroupName { get; private set; }
public RequireAtLeastOneOfGroupAttribute(string groupName)
{
ErrorMessage = string.Format("You must select at least one value from group \"{0}\"", groupName);
GroupName = groupName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
foreach (var property in GetGroupProperties(validationContext.ObjectType))
{
var propertyValue = (bool)property.GetValue(validationContext.ObjectInstance, null);
if (propertyValue)
{
// at least one property is true in this group => the model is valid
return null;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
private IEnumerable<PropertyInfo> GetGroupProperties(Type type)
{
IEnumerable<PropertyInfo> query1 = type.GetProperties().Where(a => a.PropertyType == typeof(int?) || a.PropertyType == typeof(long?) || a.PropertyType == typeof(byte?));
var metadataType = type.GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
var metaData = (metadataType != null)
? ModelMetadataProviders.Current.GetMetadataForType(null, metadataType.MetadataClassType)
: ModelMetadataProviders.Current.GetMetadataForType(null, type);
var propertMetaData = metaData.Properties
.Where(e =>
{
var attribute = metaData.ModelType.GetProperty(e.PropertyName)
.GetCustomAttributes(typeof(RequireAtLeastOneOfGroupAttribute), false)
.FirstOrDefault() as RequireAtLeastOneOfGroupAttribute;
return attribute == null || attribute.GroupName == GroupName;
})
.ToList();
RequireAtLeastOneOfGroupAttribute MyAttribute =
(RequireAtLeastOneOfGroupAttribute)Attribute.GetCustomAttribute(type, typeof(RequireAtLeastOneOfGroupAttribute));
if (MyAttribute == null)
{
Console.WriteLine("The attribute was not found.");
}
else
{
// Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.GroupName);
}
return consulta1;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var groupProperties = GetGroupProperties(metadata.ContainerType).Select(p => p.Name);
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage
};
rule.ValidationType = string.Format("group", GroupName.ToLower());
rule.ValidationParameters["propertynames"] = string.Join(",", groupProperties);
yield return rule;
}
}
Код работает правильно, когда вызывается форма, вызывается функция GetClientValidationRules
.
Моя проблема в запросе MyAttribute
, потому что он всегда возвращает null
.
Функция GetCustomAttribute
никогда не дает результатов.
Я безуспешно пробовал разные варианты, как будто аннотации данных не было.
Я только что реализовал запрос с частью представления и javascript, а именно:
jQuery.validator.unobtrusive.adapters.add(
'group',
['propertynames'],
function (options) {
options.rules['group'] = options.params;
options.messages['group'] = options.message;
});
jQuery.validator.addMethod('group', function (value, element, params) {
var properties = params.propertynames.split(',');
var isValid = false;
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
if ($('#' + property).is(':checked')) {
isValid = true;
break;
}
}
return isValid; }, '');
и вид
@Html.TextBoxFor(x=> x.document.idPersons, new { @class= "group1" })
@Html.TextBoxFor(x=> x.document.idComp, new { @class= "group1" })
@Html.TextBoxFor(x=> x.document.idRegister, new { @class= "group1" })
@Html.TextBoxFor(x=> x.document.other1)
@Html.TextBoxFor(x=> x.document.otherx)