在.net core中使用Refit时如何记录HTTP请求?

问题描述 投票:0回答:2

我想使用 Refit 来查询 API。首先,我需要获取一个访问令牌,它是一个返回状态 400 的 POST 请求。我不知道是什么原因导致了问题,因此我想查看发送到 API 的实际原始请求。不幸的是,我还没有设法让它发挥作用,而且很可能在开发过程中我会更频繁地需要它。

我发现了这个帅气的记录器,并认为我可以在我的

program.cs
中使用它作为 DelegatingHandler,如下所示:

builder.Services.AddRefitClient<IVismaConnect>().ConfigureHttpClient(config =>
{
    config.BaseAddress = new Uri("https://ENDPOINT");
    config.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "SOMECREDENTIALSTHATEVENTUALLYWILLBEREADFROMACONFIGFILE");
    config.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/x-www-form-urlencoded");
}).AddHttpMessageHandler<HttpLoggingHandler>();

现在我收到一条奇特的错误消息,告诉我“没有注册类型的服务...HttpLoggingHandler”:

所以我用谷歌搜索了一下,发现一个提示,我需要将 HttpLoggingHandler 注册为单例,因此我将这一行放在program.cs中我的代码的正上方(也在下面尝试过,没有任何区别):

builder.Services.AddTransient<HttpLoggingHandler>();

现在我收到另一个异常,说“'InnerHandler'属性必须为空。提供给'HttpMessageHandlerBuilder'的'DelegatingHandler'实例不得重用或缓存”:

经过更多谷歌搜索后,我找到了一些文档有关 Microsoft 的 ASP.NET core 中的 HTTP 日志记录

这并没有改变任何东西,异常仍然弹出,所以我只尝试了MS的建议,没有我之前尝试过的HttpLoggingHandler,但这并没有生成任何输出。

任何有关如何正确记录 Refit 发送到服务器的原始请求的建议将不胜感激。请参阅下面的完整

program.cs
文件:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
});

// Add services to the container.

builder.Services.AddTransient<HttpLoggingHandler>();

builder.Services.AddRefitClient<IVismaConnect>().ConfigureHttpClient(config =>
{
    config.BaseAddress = new Uri("https://ENDPOINT");
    config.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "SOMECREDENTIALSTHATEVENTUALLYWILLBEREADFROMACONFIGFILE");
    config.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/x-www-form-urlencoded");
}); //.AddHttpMessageHandler<HttpLoggingHandler>();

builder.Configuration
    .SetBasePath(Environment.CurrentDirectory)
    .AddJsonFile("appsettings.json", true)
    .AddUserSecrets(Assembly.GetExecutingAssembly(), true)
    .AddEnvironmentVariables()
    .Build();


ConfigurationManager configuration = builder.Configuration;
C.Instance.SetConfiguration(configuration);


builder.Logging.ClearProviders();
builder.Logging.AddConfiguration(configuration).AddConsole().AddDebug().AddSimpleConsole();

IWebHostEnvironment environment = builder.Environment;


// Add services to the container.
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      builder =>
                      {
                          builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
                      });
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpLogging();

app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
    new string[] { "My Response Header Value" };

await next();
});

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");

app.MapFallbackToFile("index.html"); ;

app.Run();
c# asp.net-core httpclient refit
2个回答
1
投票

从自定义处理程序中删除构造函数就可以了。处理程序的当前实现始终使用参数化构造函数来初始化自身,这使得

InnerHandler
不为 null。


0
投票

我不知道这是否仍然有帮助,但我编写了一个简化了这一点的包:nuget.org/packages/RefitLogCalls

© www.soinside.com 2019 - 2024. All rights reserved.