C# 如何在ASP.NET核心中缓存请求?

C# 如何在ASP.NET核心中缓存请求?,c#,.net,asp.net-web-api,asp.net-core,C#,.net,Asp.net Web Api,Asp.net Core,我正在寻找如何在ASP.NET Core 2.x中缓存请求 我有一个API代理,它总是使用相同的请求返回不同的响应(同义词composition使用AI,因此这就是为什么我不寻找缓存响应的原因) 我想缓存请求,因为它总是相同的(总是相同的基本身份验证和参数来戳我正在代理的其他API) 由于请求使用一个文件input.xml作为参数,我想知道在哪里可以缓存该文件 我的控制器: [Route("api/v1/[controller]")] public class CompositionContro

我正在寻找如何在ASP.NET Core 2.x中缓存请求

我有一个API代理,它总是使用相同的请求返回不同的响应(同义词composition使用AI,因此这就是为什么我不寻找缓存响应的原因)

我想缓存请求,因为它总是相同的(总是相同的基本身份验证和参数来戳我正在代理的其他API)

由于请求使用一个文件
input.xml
作为参数,我想知道在哪里可以缓存该文件

我的控制器:

[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();
    }
}
[路由(“api/v1/[控制器]”)]
公共类CompositionController:控制器
{
[HttpGet]
公共异步任务Get(string transformation=“xml”)
{
var httpClient=新的httpClient();
常量字符串authScheme=@“基本”;
常量字符串名称=@“myUserName”;
常量字符串密码=@“myPassword”;
var authBytes=Encoding.ASCII.GetBytes($@“{name}:{password}”);
var auth64BaseString=Convert.ToBase64String(authBytes);
httpClient.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(authScheme,auth64BaseString);
常量字符串文件名=@“input.xml”;
var inputBytes=File.ReadAllBytes(文件名);
var byteArrayContent=新的byteArrayContent(inputBytes);
常量字符串formDataKey=@“文件”;
常量字符串formDataValue=@“input.xml”“;
var multipartFormDataContent=新的multipartFormDataContent()
{
{byteArrayContent,formDataKey,formDataValue}
};
常量字符串url=@“http://baseurl:port/my/resource/is/there.do?transformation=“+转型;
var response=wait httpClient.PostAsync(url,multipartFormDataContent);
return wait response.Content.ReadAsStringAsync();
}
}

您真的不应该每次调用端点时都构造一个
HttpClient

这就是我要做的:

//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();
}
//创建一个基于url缓存HttpClient的服务
公共接口IHttpClientService
{
IHttpClient GetClient(字符串baseHref);
void AddClient(HttpClient-client,string baseHref);
}
//实现您的接口
公共类HttpClientService:IHttpClientService
{
私有只读ConcurrentDictionary\u HttpClient;
公共HttpClientService()
{
_httpClients=新的ConcurrentDictionary();
}
public void AddClient(HttpClient-client,string baseHref)
{
_httpClients。
.AddOrUpdate(baseHref,client,(key,existingHttpClient)=>existingHttpClient);
}
公共IHttpClient GetClient(字符串baseHref)
{
if(_httpClients.TryGetValue(baseHref,out var client))
返回客户;
返回null;
}
}
//注册为singleton Startup.cs
services.AddSingleton();
//注入控制器
[HttpGet]
公共异步任务Get(string transformation=“xml”)
{
常量字符串url=@“http://baseurl:port/my/resource/is/there.do?transformation=“+转型;
var httpClient=\u httpService.GetClient(url);
if(httpClient==null)
{
httpClient=新的httpClient(url);
常量字符串authScheme=@“基本”;
常量字符串名称=@“myUserName”;
常量字符串密码=@“myPassword”;
var authBytes=Encoding.ASCII.GetBytes($@“{name}:{password}”);
var auth64BaseString=Convert.ToBase64String(authBytes);
httpClient.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(authScheme,auth64BaseString);
常量字符串文件名=@“input.xml”;
var inputBytes=File.ReadAllBytes(文件名);
var byteArrayContent=新的byteArrayContent(inputBytes);
常量字符串formDataKey=@“文件”;
常量字符串formDataValue=@“input.xml”“;
var multipartFormDataContent=新的multipartFormDataContent()
{
{byteArrayContent,formDataKey,formDataValue}
};
_AddClient(httpClient,url);
}
其他的
{
//您可以将MultipartFormDataContent缓存在MemoryCache或与HttpClient相同的缓存中
//从缓存中获取MultipartFormDataContent并
}
var response=wait httpClient.PostAsync(url,multipartFormDataContent);
return wait response.Content.ReadAsStringAsync();
}

查看HttpClientFactory也是一个不错的选择。我认为添加逻辑不应该公开,而应该成为Get@MarkG我要检查一下