【问题标题】:Capturing and caching headers for each request为每个请求捕获和缓存标头
【发布时间】:2017-07-26 01:12:21
【问题描述】:

我们通过强制客户端通过我们的应用程序进行 CRUD 调用来限制对企业系统的访问,然后我们的应用程序会将相同的请求转发到其目的地,并保存标头信息。

  1. 客户端向ApiController 发出请求
  2. 我们将请求传递给服务层
  3. 服务层将请求转发到其预期的企业系统目的地。

详细说明以上几点:

客户端对此发出请求:

    [HttpGet]
    [Route("opportunities({id:guid})")]
    [Route("opportunities")]
    public async Task<HttpResponseMessage> GetOpportunity()
    {
        var query = Request.RequestUri.AbsolutePath.Split('/').Last() + Request.RequestUri.Query;
        var response = await _opportunityService.GetOpportunity(query);
        return response;
    }

服务方法GetOpportunity定义为:

    public async Task<HttpResponseMessage> GetOpportunity(string query)
    {//at the line below is where i want to send the same headers that were passed in originally at step 1
        var response = Client.Instance.GetAsync(Client.Instance.BaseAddress + query); //this is just using HttpClient to make this call
        var responseType = response.Result.StatusCode;
        if (responseType == HttpStatusCode.NotFound)
            return new HttpResponseMessage
            {
                StatusCode = responseType
            };
        return await response;
    }

我们如何保存第 1 步的标头信息?

通过使用以下中间件,我已经能够获取所有标题信息;但是,我不确定如何缓存它们或使它们可用于服务层:

public class HeaderAuthenticationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var headers = actionContext.Request.Headers;
    }

}

【问题讨论】:

    标签: c# asp.net .net asp.net-web-api visual-studio-2017


    【解决方案1】:

    您基本上是在充当代理。我看到了一些可能的选择。

    一种方法是将原始请求作为显式依赖项传递给服务

    [HttpGet]
    [Route("opportunities({id:guid})")]
    [Route("opportunities")]
    public async Task<HttpResponseMessage> GetOpportunity() {
        var response = await _opportunityService.GetOpportunity(this.Request);
        return response;
    }
    

    并在那里提取信息

    public async Task<HttpResponseMessage> GetOpportunity(HttpRequestMessage Request) {
        //at the line below is where i want to send the same headers that were passed in originally at step 1
        var query = Request.RequestUri.AbsolutePath.Split('/').Last() + Request.RequestUri.Query;
        var headers = Request.Headers;
        var url = Client.Instance.BaseAddress + query;
        //create new request and copy headers
        var proxy = new HttpRequestMessage(HttpMethod.Get, url);
        foreach (var header in headers) {
            proxy.Headers.Add(header.Key, header.Value);
        }
        var response = await Client.Instance.SendAsync(proxy);//This is an assumption.
        var responseType = response.StatusCode; //Do not mix blocking calls. It can deadlock
        if (responseType == HttpStatusCode.NotFound)
            return new HttpResponseMessage {
                StatusCode = responseType
            };
        return response;
    }
    

    如果您不想混合层和关注点,您可以将所需的信息提取到您自己的模型中并将其传递给服务以重新创建所需的请求。

    【讨论】:

    • 酷!在这种情况下,我们可以合并两层
    • 他们将同时处理 HttpRequestMessages 和 HttpResponseMessages 所以我不明白为什么不这样做。它简化了控制器,因为它只是一个传递服务。
    • 还有改进的余地,但我相信这是一个开始。
    • 我想知道这里是否需要更实用的方法,比如 Reader monad weblogs.asp.net/dixin/…
    • 哇。我需要更多时间来查看它,以便更好地了解它的作用以及它与您的问题的关系。
    猜你喜欢
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    相关资源
    最近更新 更多