You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

日志记录是否存在可插入换行等通用值的预留插值关键字/字符?

问题解答

微软官方的Microsoft.Extensions.Logging日志体系,以及Serilog、NLog等主流.NET日志框架,均没有内置预留{NewLine}这类全局通用的常量插值占位符。

这类占位符没有被内置的核心原因是:日志框架的占位符设计核心目的是支撑结构化日志的参数绑定,所有占位符都会被解析为独立的日志属性,如果内置这类全局常量占位符,很容易和业务自定义的属性命名产生冲突。

你可以通过以下两种常用方案实现需求:

方案1:封装日志扩展方法(最通用,兼容所有日志框架)

自定义日志扩展方法,在输出前统一替换资源字符串中的自定义占位符:

public static class LoggerResxExtensions
{
    public static void LogErrorWithResx(this ILogger logger, string resxTemplate, params object[] args)
    {
        // 统一替换所有自定义的通用占位符
        string processedTemplate = resxTemplate
            .Replace("{NewLine}", Environment.NewLine);
            // 后续有其他通用常量也可以在这里加替换逻辑
        logger.LogError(processedTemplate, args);
    }
}

使用方式完全符合你的预期:

  • resx字符串直接写:Failed to deserialize an object of type '{0}' from the following string:{NewLine}{1}
  • 调用时仅需要传业务参数:
_logger.LogErrorWithResx(Resources.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);

方案2:扩展资源类的属性访问逻辑

如果你不想修改日志的调用方法,也可以通过扩展资源类的partial类,在资源字符串读取时自动替换占位符:

// 与项目自动生成的Resources类同命名空间的自定义partial类
partial class Resources
{
    public static string FailedToDeserialize 
    {
        get
        {
            return _resourceManager.GetString(nameof(FailedToDeserialize), _resourceCulture)
                .Replace("{NewLine}", Environment.NewLine);
        }
    }
}

该方案下可以直接使用原生的LogError方法,不需要额外调整调用逻辑。

内容的提问来源于stack exchange,提问作者Arthur Edgarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:57:01