如何将自定义标头从 mvc 项目发送到 Web api 项目?

Posted

技术标签:

【中文标题】如何将自定义标头从 mvc 项目发送到 Web api 项目?【英文标题】:How to send custom headers from mvc project to a web api project? 【发布时间】:2021-10-16 19:58:47 【问题描述】:

我有两个应用程序同时运行。在我的 mvc 项目中,我有一个中间件,它将使用 TempData 来传递 usernameipAddress 的值并将其添加到响应标头中。我想要做的是将这些头文件添加到 mvc 项目的中间件中,将这些头文件传递给 web api 项目,这样我就可以使用用户名和 ipaddress 并具有相同的相关 ID。如何将 mvc 项目中的自定义标头发送/转发到 web api 项目?

Middleware 在 mvc 项目中:

public class CorrelationIdMiddleware

    private readonly RequestDelegate _next;
    private readonly ILogger _logger;
    private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory;
    public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ITempDataDictionaryFactory tempDataDictionaryFactory)
    
        _next = next;
        _logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
        _tempDataDictionaryFactory = tempDataDictionaryFactory;
    

    public async Task Invoke(HttpContext context)
    
        string correlationId = null;
        string userName;
        string ipAddress;

        var tempData = _tempDataDictionaryFactory.GetTempData(context);

        var key = context.Request.Headers.Keys.FirstOrDefault(n => n.ToLower().Equals("x-correlation-id"));
        if (!string.IsNullOrWhiteSpace(key))
        
            correlationId = context.Request.Headers[key];
            _logger.LogInformation("Header contained CorrelationId: @CorrelationId", correlationId);
        
        else
        
            if (tempData.ContainsKey("username") && tempData.ContainsKey("ipaddress"))
            
                userName = tempData.Peek("username").ToString();
            
                ipAddress = tempData.Peek("ipaddress").ToString();

                context.Response.Headers.Append("X-username", userName);
                context.Response.Headers.Append("X-ipAddress", ipAddress);
            

            correlationId = Guid.NewGuid().ToString();
            _logger.LogInformation("Generated new CorrelationId: @CorrelationId", correlationId);
        
        context.Response.Headers.Append("x-correlation-id", correlationId);
        using (LogContext.PushProperty("CorrelationId", correlationId))
        
            await _next.Invoke(context);
        
    

现在转到我的 web api 项目:

起初我的 mvc 中间件有完全相同的代码,但它从未进入 tempdata.containkey 的 if 语句,所以我删除了 tempdata 实现。

public class CorrelationIdMiddleware

    private readonly RequestDelegate _next;
    private readonly ILogger _logger;
    public CorrelationIdMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
    
        _next = next;
        _logger = loggerFactory.CreateLogger<CorrelationIdMiddleware>();
    

    public async Task Invoke(HttpContext context)
    
        string correlationId = null;

        var key = context.Request.Headers.Keys.FirstOrDefault(n => n.ToLower().Equals("x-correlation-id"));
        if (!string.IsNullOrWhiteSpace(key))
        
            correlationId = context.Request.Headers[key];
            _logger.LogInformation("Header contained CorrelationId: @CorrelationId", correlationId);
        
        else
        
            correlationId = Guid.NewGuid().ToString();
            _logger.LogInformation("Generated new CorrelationId: @CorrelationId", correlationId);
        
        context.Response.Headers.Append("x-correlation-id", correlationId);
        using (LogContext.PushProperty("CorrelationId", correlationId))
        
            await _next.Invoke(context);
        
    

【问题讨论】:

在进行 API 调用之前,您需要将标头添加到 HttpClient。您需要主控制器来存储标头,或者在调用 HttpClient 逻辑之前以某种方式将标头传递回主控制器。 谢谢,会尝试其中一个,看看效果如何! 【参考方案1】:

您的 HttpClient 调用独立于您的控制器和中间件工作。

在进行 API 调用之前,您需要将标头添加到 HttpClient。为此,您需要主控制器来存储标头,或者以某种方式将标头传递回主控制器,然后将它们传递给 HttpClient 逻辑

【讨论】:

当涉及到在 mvc 的主控制器中添加标头以获取值/将标头传递给 web api 项目时,您会按照我在帖子更新部分中的方式进行操作吗? 取决于您的用例。我个人尽量避免中间件的复杂性。如果这样做有意义,我可能会尝试将此相关 ID 添加为声明。 对不起,我没有关注,我该怎么做呢?我是新手 :( 您的应用程序目前是否有任何身份验证 - 用户需要登录吗?此页面在最新的 .net 5 中对其进行了描述:docs.microsoft.com/en-us/aspnet/core/security/authentication/…,但在旧版本中类似。 我看到了你的更新,基本上就是这样。现在您需要使用 HttpClient 实际调用 api。 client.GetAsync 或 client.PostAsync 将分别进行 Get 或 Post 调用。

以上是关于如何将自定义标头从 mvc 项目发送到 Web api 项目?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义标头添加到zend Mail Message

如何将自定义事件/信号从一个进程发送到 MacOS 中的另一个进程

如何使用中继将自定义标头发送到graphql服务器?

如何以角度将自定义标头添加到httpRequest

是否可以将自定义错误页面与 MVC 站点一起使用,但不能在 Web API 中使用?

如何在 PowerShell 中运行 appCmd 以将自定义标头添加到默认网站