简体   繁体   English

如何在ASP.NET Core中缓存请求?

[英]How to cache a request in ASP.NET Core?

I am looking for how to cache a request in ASP.NET Core 2.x? 我正在寻找如何在ASP.NET Core 2.x中缓存请求?

I have API proxy which always return a different response using the same request (synonyms composition using an AI, hence that's why I am not looking for caching the response). 我有API代理,它总是使用相同的请求返回不同的响应(使用AI的同义词组成,因此这就是为什么我不打算缓存响应)。

And I would like to cache the request since it's always the same (always the same basic auth and parameters to poke the other API that I am proxy-ing). 我想缓存该请求,因为它始终是相同的(总是使用相同的基本身份验证和参数来戳我正在代理的其他API)。

Since the request use a file input.xml for the parameters, I am wondering where I can cache that one as well 由于请求使用文件input.xml作为参数,所以我想知道在哪里也可以缓存该文件

My controller: 我的控制器:

[Route("api/v1/[controller]")]
public class CompositionController : Controller
{
    [HttpGet]
    public async Task<string> Get(string transformation = "xml")
    {
        var httpClient = new HttpClient();

        const string authScheme = @"Basic";
        const string name = @"myUserName";
        const string password = @"myPassword";
        var authBytes = Encoding.ASCII.GetBytes($@"{name}:{password}");
        var auth64BaseString = Convert.ToBase64String(authBytes);
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authScheme, auth64BaseString);

        const string fileName = @"input.xml";
        var inputBytes = File.ReadAllBytes(fileName);
        var byteArrayContent = new ByteArrayContent(inputBytes);
        const string formDataKey = @"""file""";
        const string formDataValue = @"""input.xml""";
        var multipartFormDataContent = new MultipartFormDataContent()
        {
            { byteArrayContent, formDataKey, formDataValue }
        };

        const string url = @"http://baseurl:port/my/resource/is/there.do?transformation=" + transformation;
        var response = await httpClient.PostAsync(url, multipartFormDataContent);
        return await response.Content.ReadAsStringAsync();
    }
}

You really shouldn't be constructing an HttpClient every time the endpoint is called. 您确实不应该在每次调用端点时都构造一个HttpClient

This is what I would do: 这就是我要做的:

//create a service that caches HttpClient based on url
public interface IHttpClientService
{
    IHttpClient GetClient(string baseHref);
    void AddClient(HttpClient client, string baseHref);
}

//implement your interface
public class HttpClientService : IHttpClientService
{
    private readonly ConcurrentDictionary<string, IHttpClient> _httpClients;

    public HttpClientService()
    {
        _httpClients = new ConcurrentDictionary<string, IHttpClient>();
    }

    public void AddClient(HttpClient client, string baseHref)
    {
        _httpClients.
                .AddOrUpdate(baseHref, client, (key, existingHttpClient) => existingHttpClient);
    }

    public IHttpClient GetClient(string baseHref)
    {
        if (_httpClients.TryGetValue(baseHref, out var client))
            return client;
        return null;
    }
}

//register as singleton Startup.cs
services.AddSingleton<IHttpClientService, HttpClientService>();

//inject into Controller

[HttpGet]
public async Task<string> Get(string transformation = "xml")
{

    const string url = @"http://baseurl:port/my/resource/is/there.do?transformation=" + transformation;


    var httpClient = _httpService.GetClient(url);
    if(httpClient == null)
    {
        httpClient = new HttpClient(url);

        const string authScheme = @"Basic";
        const string name = @"myUserName";
        const string password = @"myPassword";
        var authBytes = Encoding.ASCII.GetBytes($@"{name}:{password}");
        var auth64BaseString = Convert.ToBase64String(authBytes);
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authScheme, auth64BaseString);

        const string fileName = @"input.xml";
        var inputBytes = File.ReadAllBytes(fileName);
        var byteArrayContent = new ByteArrayContent(inputBytes);
        const string formDataKey = @"""file""";
        const string formDataValue = @"""input.xml""";
        var multipartFormDataContent = new MultipartFormDataContent()
        {
            { byteArrayContent, formDataKey, formDataValue }
        };

        _httpClient.AddClient(httpClient, url);

    }
    else
    {
      //You can cache your MultipartFormDataContent in MemoryCache or same cache as HttpClient
     //Get MultipartFormDataContent from cache and
    }

    var response = await httpClient.PostAsync(url, multipartFormDataContent);
    return await response.Content.ReadAsStringAsync();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM