mvc 5 пользовательских аннотаций данных GetCustomAttributes не найдено результатов - PullRequest
0 голосов
/ 03 мая 2018

Я выполняю проверку для группы полей, в моем случае одно из этих трех полей является обязательным.

Я выполняю пользовательскую аннотацию данных.

Мои метаданные следующие. В мои метаданные я поместил эту аннотацию данных, которую я хочу настроить.

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)
...