首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >没有注册自定义呈现布局的.Net 6

没有注册自定义呈现布局的.Net 6
EN

Stack Overflow用户
提问于 2022-09-15 15:00:43
回答 1查看 63关注 0票数 0

在使用.Net 6 NLog的Web中,我如何拦截发布的主体,以便在记录它之前对其进行操作?

,这是我得到的:

我有一个.Net框架4.7.2WebAPI和一个DelegatingHandler来拦截请求的主体。然后,我遍历每个键,如果键位于字符串列表中,则替换该值。例如:如果键是PasswordPwd,则将值替换为xxx,这样就可以在不考虑安全性的情况下记录全文。效果很好。我正在尝试在一个.Net 6 Web项目上复制这一点。

,这是我所做的:

我已经通过NLog源代码查看了他们是如何得到aspnet-request-posted-body的。我相信我找到了一些东西,但我没有看到NLog在调用/使用我的RenderLayout

代码语言:javascript
运行
复制
[LayoutRenderer("aspnet-request-posted-body-2")]
public class TestRender : AspNetLayoutRendererBase {
    protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) {
        var items = HttpContextAccessor.HttpContext?.Items;
        if (items == null || items.Count == 0) {
            return;
        }

        if (items.TryGetValue("aspnet-request-posted-body-2", out var value)) {
            builder.Append(value as string);
        }
    }
}

我的Middleware

代码语言:javascript
运行
复制
public class RequestLoggerMiddleware {
    private readonly RequestDelegate _next;
    private readonly ILogger<RequestLoggerMiddleware> _logger;

    public RequestLoggerMiddleware(RequestDelegate next, ILogger<RequestLoggerMiddleware> logger) {
        _next = next;
        _logger = logger;
    }

    public async Task Invoke(HttpContext context) {
        var requestBody = await new HttpContextExtensions().PeekBodyAsync(context);
        var contentType = context.Request.ContentType;

        // Not done yet, but adding this for testing
        switch (contentType) {
            case "application/x-www-form-urlencoded":
                // Clean data
                ...
                // Add to context
                context.Items.Add("aspnet-request-posted-body-2", requestBody);
                break;
            case "application/*+json":
            case "application/json":
            case "text/json":
                // Clean data
                ...
                // Add to context
                context.Items.Add("aspnet-request-posted-body-2", JsonSerializer.Serialize(requestBody));
                break;
            default:
                break;
        }

        _logger
            .LogInformation("TESTING");
        
        // With a breakpoint I checked that `content` does have the item listed above
        await _next.Invoke(context);
    }
}

这是我的Program.cs文件

代码语言:javascript
运行
复制
var logger = LogManager
            .LoadConfiguration(string.Concat(Directory.GetCurrentDirectory(), "/Configs/NLog/nlog.config"))
            .Setup()
            .SetupExtensions(x => {
                x.RegisterLayoutRenderer<TestRender>("aspnet-request-posted-body-2");
            })
            .GetCurrentClassLogger();
logger.Debug("init main");

try {
    var builder = WebApplication.CreateBuilder(args);

    builder.Logging.ClearProviders();
    builder.Host.UseNLog();

    var app = builder.Build();

    // Register NLog's Request Body Layout
    app.UseMiddleware<NLogRequestPostedBodyMiddleware>();
    // Register my custom layout
    app.UseMiddleware<RequestLoggerMiddleware>();

    app.UseHttpsRedirection();

    app.UseAuthorization();

    app.MapControllers();

    app.Run();
} catch (Exception exception) {
    logger.Error(exception, "Stopped program because of exception");
    throw;
} finally {
    LogManager.Shutdown();
}
EN

Stack Overflow用户

回答已采纳

发布于 2022-09-16 05:06:04

当您将请求体存储在HttpContext.Items-dictionary中时,不需要注册自定义布局。只需在${aspnet-item:aspnet-request-posted-body-2}中使用NLog.config即可。另见:https://github.com/NLog/NLog/wiki/AspNet-HttpContext-Item-Layout-Renderer

也许可以考虑删除NLogRequestPostedBodyMiddleware,因为您已经有了自己的RequestLoggerMiddleware

顺便说一句。在加载依赖于这些扩展的日志配置之前,请确保连接SetupExtensions。例如。LogManager.Setup().SetupExtensions(...).LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/Configs/NLog/nlog.config")

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73733414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档