asp.net-core - 如何在 Controller 中注入(inject)HttpHeader值?

标签 asp.net-core asp.net-core-webapi

我有使用 ASP.NET Core API 开发的 Web API。每个传入请求都插入了一个自定义 header 值。例如x-correlationid。 Controller 使用该值来记录和跟踪请求。 目前我正在读取每个 Controller 中的值,如下所示

[Route("api/[controller]")]
public class DocumentController : Controller
{
    private ILogger<TransformController> _logger;
    private string _correlationid = null;

    public DocumentController(ILogger<DocumentController > logger)
    {
        _logger = logger;
        _correlationid = HttpContext.Request.Headers["x-correlationid"];
    }

    [HttpPost]
    public async Task<intTransform([FromBody]RequestWrapper request)
    {
        _logger.LogInformation("Start task. CorrelationId:{0}", _correlationid);

         // do something here

        _logger.LogInformation("End task. CorrelationId:{0}", _correlationid);

        return result;
    }
}

我认为这违反了 DI 规则。

我不想读取 Controller 构造函数中的值,而是想将值注入(inject) Controller 构造函数中。
或者
中间件能否读取 x-correlationid*以某种方式* 使其可供所有 Controller 使用,这样我们就不必将其注入(inject)到任何 Controller 中?

这里什么是更好的选择?

最佳答案

Instead of reading the value inside the controller's constructor, I want to inject the value in the controller's constructor.

您无法将值本身注入(inject) api Controller 的构造函数中,因为在构造时,HttpContext 将为 null

一个“注入(inject)式”选项是在您的操作中使用 FromHeaderAttribute:

[HttpPost]
public async Task<int> Transform(
    [FromBody]RequestWrapper request,
    [FromHeader(Name="x-correlationid")] string correlationId)
{
    return result;
}

Can middleware read the x-correlationid and somehow make it available to all the controllers so we don't have to inject it in any controller?

我认为中间件解决方案可能无法满足您的需求。相反,您可以创建一个派生自 Controller 的自定义基类,并让所有 Api Controller 都派生自该基类。

public class MyControllerBase : Controller
{
    protected string CorrelationId =>
        HttpContext?.Request.Headers["x-correlationid"] ?? string.Empty;
}

[Route("api/[controller]")]
public class DocumentController : MyControllerBase 
{
    private ILogger<TransformController> _logger;

    public DocumentController(ILogger<DocumentController> logger)
    {
        _logger = logger;
    }

    [HttpPost]
    public async Task<intTransform([FromBody]RequestWrapper request)
    {
        _logger.LogInformation($"Start task. CorrelationId:{CorrelationId}");

        // do something here

        _logger.LogInformation($"End task. CorrelationId:{CorrelationId}");
        return result;
    }
}

关于asp.net-core - 如何在 Controller 中注入(inject)HttpHeader值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39459705/

相关文章:

c# - 为什么 asp.net core 发送空对象作为响应?

asp.net-core - Serilog 日志记录 web-api 方法,在中间件中添加上下文属性

c# - 将请求传递给另一个 API

asp.net-core - 如何导航到 Blazor Server 应用程序中文件夹的默认页面 (.razor)?

c# - 使用 aspnetcore 2.2 联合 Azure AD 登录后,User.Identity.Name 为空

c# - 等同于 asp.net-core 中的 AntiForgery.Validate() 的命令

asp.net-core - 如何在 F# Asp Core Web API 中序列化 F# 可区分的联合类型

c# - ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色

asp.net-core - 在 ASP.NET Core 3.1 中设置值比较器

c# - 如何在发布中包含 asp.net core 2 依赖项