C# CustomAttributeData класс для атрибута
У меня есть следующий код, расположенный в Swashbuckle.Swagger.IOperationFilter
учебный класс.
List<CustomAttributeData> controllerAttributes = apiDescription
.ActionDescriptor
.ControllerDescriptor
.ControllerType
.CustomAttributes
.Where(a => a.AttributeType == typeof(SwaggerFileInFormDataAttribute))
.ToList();
Я успешно получаю коллекцию. Я хочу преобразовать коллекциюList<CustomAttributeData>
в коллекцию моего настраиваемого атрибута List<SwaggerFileInFormDataAttribute>
.
Я хочу преобразовать System.Reflection.CustomAttributeData
класс к моему настраиваемому атрибуту SwaggerFileInFormDataAttribute
.
Изменить 1:
вот как мойSwaggerFileInFormDataAttribute
атрибут выглядит.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple =false, Inherited =false)]
public class SwaggerFileInFormDataAttribute: Attribute
{
private ICollection<string> displayNames;
public SwaggerFileInFormDataAttribute()
{
this.DisplayNames = new List<string> { "File" };
}
public SwaggerFileInFormDataAttribute(params string[] displayNames)
{
this.DisplayNames = displayNames;
}
public ICollection<string> DisplayNames
{
get
{
if (this.displayNames == null)
return new List<string> { "File" };
else
return this.displayNames;
}
set => displayNames = value;
}
}
После успешного преобразования List<CustomAttributeData>
к List<SwaggerFileInFormDataAttribute>
Я буду использовать свойство, показанное в классе SwaggerFileInFormDataAttribute
названный DisplayNames
.
2 ответа
Первое решение:
List<SwaggerFileInFormDataAttribute> customControllerAttributes = apiDescription
.ActionDescriptor
.ControllerDescriptor
.ControllerType
.CustomAttributes
.Where(a => a.AttributeType == typeof(SwaggerFileInFormDataAttribute))
.Select(a =>
{
ReadOnlyCollection<CustomAttributeTypedArgument> costuctorArgumentsReadOnlyCollection = (ReadOnlyCollection<CustomAttributeTypedArgument>)a.ConstructorArguments.Select(x => x.Value).FirstOrDefault();
string[] contructorParams = costuctorArgumentsReadOnlyCollection?.ToArray().Select(x => x.Value.ToString()).ToArray();
SwaggerFileInFormDataAttribute myCustomAttr = (SwaggerFileInFormDataAttribute)Activator.CreateInstance(a.AttributeType, contructorParams);
return myCustomAttr;
})
.ToList();
Объяснение: Обе переменныеcostuctorArgumentsReadOnlyCollection
а также contructorParams
можно пропустить, если желаемый атрибут имеет пустой конструктор.
В этом случае достаточно будет только этой строки:(SwaggerFileInFormDataAttribute)Activator.CreateInstance(a.AttributeType, null);
Второе решение:
Это гораздо более чистое решение. Мы можем полностью пропуститьCustomAttributeData
класс в IOperationFilter
как это:
List<SwaggerFileInFormDataAttribute> controllerAttributes = apiDescription
.ActionDescriptor
.ControllerDescriptor
.GetCustomAttributes<SwaggerFileInFormDataAttribute>()
.ToList();
После вашего .Where
, добавьте выберите и переведите соответствующим образом. Самым простым было бы создать в своем пользовательском классе конструктор, который принимаетSwaggerFileInFormDataAttribute
в качестве параметра и при необходимости сопоставляется с вашим пользовательским классом. Тогда твойSelect
было бы:
.Where(a => a.AttributeType == typeof(SwaggerFileInFormDataAttribute))
.Select(a => new CustomAttributeData(a))
.ToList();