Атрибут доступа извне контроллера - PullRequest
0 голосов
/ 27 сентября 2019

Возможно ли получить доступ к пользовательскому атрибуту действия контроллера из-за пределов этого контроллера?У меня есть пользовательский форматировщик вывода, который должен возвращать файл с определенным именем.Я создал собственный атрибут, который принимает строку (имя файла), и я хотел бы попытаться получить доступ к значению этого атрибута из пользовательского выходного форматера.

public class FileAttribute : Attribute
{
public ExcelTemplateAttribute(string fileName)
{
    FileName = fileName;
}

    public string FileName { get; }
}

Мой OutputFormatter выглядит следующим образом:

public class FileOutputFormatter : OutputFormatter
{
    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) 
    {
        // string filename = ???
    }
}

Мое действие API возвращает сервис

[File("Template.txt")]
public IActionResult Get([FromQuery]int Id)
{
    IEnumerable<int> data = _kenoReport.GetReportData(Id);

    return Ok(data);
}

1 Ответ

0 голосов
/ 27 сентября 2019

Информация о контроллере и / или действиях не легко доступна вне специфичных для MVC частей конвейера промежуточного программного обеспечения, не прибегая к сложному (и простому для взлома) коду, основанном на отражении.

Однако одинОбходной путь - использовать фильтр действий, чтобы добавить сведения об атрибуте в словарь HttpContext.Items (который доступен во всем конвейере промежуточного программного обеспечения), и чтобы средство форматирования вывода получило его позже в конвейере промежуточного программного обеспечения.

Например,вы можете сделать ваш FileAttribute производным от ActionFilterAttribute и добавить его в HttpContext.Items (используя уникальную ссылку на объект в качестве ключа) при выполнении:

public sealed class FileAttribute : ActionFilterAttribute
{
    public FileAttribute(string filename)
    {
        Filename = filename;
    }

    public static object HttpContextItemKey { get; } = new object();

    public string Filename { get; }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        context.HttpContext.Items[HttpContextItemKey] = this;
    }
}

Затем в выходном форматере выможет получить экземпляр атрибута и получить доступ к имени файла:

public sealed class FileOutputFormatter : OutputFormatter
{
    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
    {
        if (context.HttpContext.Items.TryGetValue(FileAttribute.HttpContextItemKey, out var item)
            && item is FileAttribute attribute)
        {
            var filename = attribute.Filename;

            // ...
        }
    }
}
...