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

C# API中AddJsonConsole日志输出Unicode而非字符的配置方案

问题

我在为C# API实现AddJsonConsole日志组件,目前已正常运行,但日志中的特殊字符会以Unicode值形式输出(例如用\u003E代替>)。请问是否可以通过配置让其输出实际字符?

我的Program.cs配置如下:

builder.Logging.ClearProviders();
builder.Logging.AddJsonConsole(options =>  
{
    options.IncludeScopes = false;
    options.TimestampFormat = "HH:mm:ss"; 
    options.JsonWriterOptions = new() 
    { 
        Indented = true,
    };
});

当前输出的日志示例(Exception字段存在大量Unicode转义值):

{
  "Timestamp": "11.26.19",
  "EventId": 0,
  "LogLevel": "Error",
  "Category": "Mixorama.Server.Controllers.CocktailsController",
  "Message": "Failed to create cocktail",
  "Exception": "System.InvalidOperationException: The type of navigation \u0027CocktailEntity.Ingredients\u0027 is \u0027SelectListIterator\u003CIngredientEntity, IngredientEntity\u003E\u0027 which does not implement \u0027ICollection\u003CIngredientEntity\u003E\u0027. Collection navigations must implement \u0027ICollection\u003C\u003E\u0027 of the target type.\r\n   at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor\u00603.GetCollection(Object instance)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor\u00603.GetOrCreateCollection(Object instance, Boolean forMaterialization)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor\u00603.Add(Object entity, Object value, Boolean forMaterialization)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.AddToCollection(INavigationBase navigationBase, Object value, Boolean forMaterialization)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.AddToCollection(InternalEntityEntry entry, INavigationBase navigation, InternalEntityEntry value, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.SetReferenceOrAddToCollection(InternalEntityEntry entry, INavigationBase navigation, InternalEntityEntry value, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.ToDependentFixup(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, InternalEntityEntry duplicateEntry, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.FireStateChanged(EntityState oldState)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable\u00601 forceStateWhenUnknownKey, Nullable\u00601 fallbackState)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode\u00601 node)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode\u00601 node, Func\u00602 handleNode)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.NavigationCollectionChanged(InternalEntityEntry entry, INavigationBase navigationBase, IEnumerable\u00601 added, IEnumerable\u00601 removed)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.NavigationCollectionChanged(InternalEntityEntry entry, INavigationBase navigationBase, IEnumerable\u00601 added, IEnumerable\u00601 removed)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectNavigationChange(InternalEntityEntry entry, INavigationBase navigationBase)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.LocalDetectChanges(InternalEntityEntry entry)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges(IStateManager stateManager)\r\n   at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges()\r\n   at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges()\r\n   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)\r\n   at Mixorama.Server.Controllers.CocktailsController.CreateCocktail(CreateCocktailRequest request) in c:\Users\busks\Code\Mixorama\Mixorama.Server\Controllers\CocktailsController.cs:line 75",
  "State": {
    "Message": "Failed to create cocktail",
    "{OriginalFormat}": "Failed to create cocktail"
  }
}
解决方案

可以通过配置JsonWriterOptions中的Encoder属性禁用Unicode转义,让日志直接输出实际字符。具体做法是将Encoder设置为JavaScriptEncoder.UnsafeRelaxedJsonEscaping,该编码器会直接输出ASCII范围内的特殊字符,而非转成Unicode值。

修改后的Program.cs配置如下:

using System.Text.Encodings.Web; // 需引入此命名空间

builder.Logging.ClearProviders();
builder.Logging.AddJsonConsole(options =>  
{
    options.IncludeScopes = false;
    options.TimestampFormat = "HH:mm:ss"; 
    options.JsonWriterOptions = new() 
    { 
        Indented = true,
        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping // 新增配置项
    };
});

说明

  • JavaScriptEncoder.UnsafeRelaxedJsonEscaping允许输出'、>、<等更多字符而不转义,提升日志可读性。
  • 注意名称中的"Unsafe":若日志内容可能包含不可信的用户输入,该配置存在XSS风险,但后端日志场景通常无此问题,可安全使用。

内容的提问来源于stack exchange,提问作者Jakob Busk Sørensen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:59:50