У меня есть настраиваемый атрибут внутри конструктора моего настраиваемого атрибута. Я хочу установить значение свойства моего атрибута для типа свойства, к которому был применен мой атрибут, есть ли какой-нибудь доступ к члену, который атрибут был применен изнутри моего класса атрибутов?
Получить член, к которому был применен атрибут из внутреннего конструктора атрибутов?
Ответ 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"
}
}