A log placeholder is a named, brace-delimited marker whose value is supplied by a runtime parameter. Logging replaces the marker in the displayed message and can preserve its name and value for structured logging. section 26.2 section 26.2.3
Use placeholders consistently when writing log messages:
- Match placeholders with parameters by position: the first placeholder uses the first parameter, the second uses the second. section 26.2
- Provide at least as many parameters as placeholders; otherwise, logging throws an exception at runtime. section 26.2.3
- Prefer placeholders over string interpolation because providers can retain named values such as UserId and RecipeId. section 26.2 section 26.2.3
Counting loaded recipes
_log.LogInformation("Loaded {RecipeCount} recipes", Recipes.Count);\n\nIf Recipes.Count is 3, the rendered message is "Loaded 3 recipes". A structured provider can additionally record RecipeCount=3. section 26.2 section 26.2.3
Listing 26.2 Injecting ILogger into a class and writing a log message
public class IndexModel : PageModel
{
private readonly RecipeService _service;
private readonly ILogger<IndexModel> _log; #1
public ICollection<RecipeSummaryViewModel> Recipes { get; set; }
public IndexModel(
RecipeService service,
ILogger<IndexModel> log) #1
{
_service = service;
_log = log; #1
}
public void OnGet()
{
Recipes = _service.GetRecipes();
_log.LogInformation( #2
"Loaded {RecipeCount} recipes", Recipes.Count); #2
}
}
#1 Injects the generic ILogger<T> using DI, which implements ILogger
#2 Writes an Information-level log. The RecipeCount variable is substituted in the message.
See the complete Razor Page example, including ILogger injection, dependency injection, and the Information-level log call. section 26.2






