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

问题描述

我有这个代码

[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,没有修复此警告的建议。

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

解决方法

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

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

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

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

答案是字符串插值会阻止结构化日志记录。当您在消息之后传递变量时,您可以让记录器单独保存它们。如果您只是将日志保存到文件中,您可能看不到任何区别,但是如果您稍后决定将日志记录到数据库或以某种 JSON 格式,您只需更改您的日志记录接收器,您就可以在日志中进行大量搜索无需更改代码中的所有日志语句即可轻松实现。

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