来自控制器外部的访问属性

时间:2019-09-27 07:32:16

标签: api asp.net-core .net-core formatting asp.net-core-webapi

是否可以从该控制器外部访问该控制器动作的自定义属性?我有一个自定义输出格式化程序,该格式化程序应返回具有特定名称的文件。我制作了一个接受字符串(文件名)的自定义属性,我想尝试从自定义输出格式化程序中访问该属性的值。

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 :(得分:0)

在中间件管道的特定于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;

            // ...
        }
    }
}