【问题标题】:Message template should be compile time constant消息模板应该是编译时间常数
【发布时间】:2021-04-28 16:07:11
【问题描述】:

我有这个代码

[HttpGet("average/{videoGuid}")]
public async Task<IActionResult> AverageRatingOfVideo([FromRoute] string videoGuid)
{
    _logger.LogInformation($"Finding average rating of video : {videoGuid}");
    var avg = await _ratingService.GetVideoRatingAverageAsync(videoGuid);
    return Ok(avg);
}

我在这里收到警告$"Finding average rating of video : {videoGuid}"

消息模板应该是编译时常量

我正在使用 Rider,没有建议修复此警告。

我不明白为什么这会给我一个警告,我该如何解决这个问题?

【问题讨论】:

  • 不,我不这么认为,我的问题与c#有关
  • 尝试将这个 $"Finding average rating of video : {videoGuid}" 提取到某个变量,例如 var msg = $"Finding average rating of video : {videoGuid}";并将此消息用作 LogInformation 参数
  • @godot 试过了,但警告仍然存在
  • 它是 Serilog 的一个特性,见讨论here
  • 试试_logger.LogInformation("Finding average rating of video : {videoGuid}", videoGuid)_logger.LogInformation("Finding average rating of video : " + videoGuid)。我会说它的原因是结构化日志记录,它使用相同的大括号进行模板和分析器缺少插值字符串部分。

标签: c# .net-core rider


【解决方案1】:

摆脱警告的方法是单独提供变量videoGuid,如下所示:

_logger.LogInformation("Finding average rating of video : {VideoGuid}", videoGuid);

在这里,我首先删除了 $ 符号,从而关闭了 C# 执行的字符串插值。字符串中的{videoGuid} 现在变成了“属性”,因此我将变量作为第二个参数传递给 LogInformation。 Rider 还抱怨字符串中的属性应该以大写字母开头,所以我将其更改为 {VideoGuid}

现在是真正的问题:为什么会有警告?

答案是字符串插值可以防止结构化日志记录。当您在消息后传递变量时,记录器可以单独保存它们。如果您只是将日志保存到文件中,您可能看不出有什么不同,但如果您后来决定将日志记录到数据库或以某种 JSON 格式,您只需更改日志接收器,您就可以在日志中搜索很多更容易,无需更改代码中的所有日志语句。

Software Engineering Stack Exchange 对此进行了很好的讨论。

【讨论】:

  • 这是 Serilog 的一个功能吧?您是在使用它还是他们在 .net 5 中引入了结构化日志记录?无论如何,澄清一下可能会很好。
  • Yamaç Kurtuluş,我正在使用NLog,至少目前是这样。我猜 IntelliJ 团队在某处保留了一个支持结构化日志记录的框架列表,以知道何时激活此警告(或者他们可能有更复杂的算法 - 必须有 很多 的努力和代码他们的工具生成的许多警告)。
  • 对我来说,解决方案(Rider/MS/C# 创建者提供的?)没有意义,它可能会误导代码,因为命名参数只是有序参数 - 没有名称匹配,所以代码 @987654326 @ 将记录 hey bar, hi foo,更多重命名变量 barfoo 会使代码变得奇怪 ...("hey {Foo}, hi {Bar}", big, bang); - Rider/ReSharper 也不支持在 {} 中重命名 atm。
  • @svonidze 在字符串中使用{} 可以简单地视为与使用string.Format() 相同。您可以添加命名变量以使其更易于阅读,但您也可以使用logger.LogDebug("hey {0}, hi {1}", bar, foo) - 它是一样的。请记住这一点,它可能会对您有所帮助。
  • @svonidze 如果您是库开发人员,请务必不要忽略此警告,因为您将使用无法正确删除或压缩的消息淹没下游日志记录系统。在这种情况下,是否“更干净”无关紧要,因为在使用结构化日志框架时非常量模板是错误的。
【解决方案2】:

这是 Rider 的 Serilog 扩展中的误报,但删除此警告的其他方法是禁用一次警告(或在您的类文件中全局禁用)。

// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
_logger.LogInformation(messageTemplate);

不是最好的解决方案,但它也是一种选择。

现在,检查Rof's answer 警告的原因。

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2015-09-15
    相关资源
    最近更新 更多