Подтвердить что ты не робот

Получить член, к которому был применен атрибут из внутреннего конструктора атрибутов?

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

4b9b3361

Ответ 1

Атрибуты не работают, боюсь. Они всего лишь "маркеры", прикрепленные к объектам, но неспособные взаимодействовать с ними.

Атрибуты сами по себе должны быть лишены поведения, просто содержащие метаданные для типа, к которому они привязаны. Любое поведение, связанное с атрибутом, должно предоставляться другим классом, который ищет наличие атрибута и выполняет задачу.

Если вас интересует тип, к которому применяется атрибут, эта информация будет доступна в то же время, что и вы, чтобы получить атрибут.

Ответ 2

Вы можете сделать следующее. Это простой пример.

//target class
public class SomeClass{

    [CustomRequired(ErrorMessage = "{0} is required", ProperytName = "DisplayName")]
    public string Link { get; set; }

    public string DisplayName { get; set; }
}
    //custom attribute
    public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
    public string ProperytName { get; set; }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var propertyValue = "Value";
        var parentMetaData = ModelMetadataProviders.Current
             .GetMetadataForProperties(context.Controller.ViewData.Model, context.Controller.ViewData.Model.GetType());
        var property = parentMetaData.FirstOrDefault(p => p.PropertyName == ProperytName);
        if (property != null)
            propertyValue = property.Model.ToString();

        yield return new ModelClientValidationRule
        {
            ErrorMessage = string.Format(ErrorMessage, propertyValue),
            ValidationType = "required"
        };
    }
}

Ответ 3

Это возможно из .NET 4.5 с помощью CallerMemberName:

[SomethingCustom]
public string MyProperty { get; set; }

Затем ваш атрибут:

[AttributeUsage(AttributeTargets.Property)]
public class SomethingCustomAttribute : Attribute
{
    public StartupArgumentAttribute([CallerMemberName] string propName = null)
    {
        // propName = "MyProperty"
    }
}