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

Message template should be compile time constant

我有这个代码

[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}"

Message template should be compile time constant

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

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

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

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

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

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

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

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

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

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

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

现在,检查 为什么会出现警告。