如何手动触发JsonSerialization错误

4

我的应用程序在启动时,我会注册NewtonSoft并开启错误记录序列化。当我检查我的应用程序日志时,我可以看到有错误日志,但我很难定位或重现错误。

错误信息: 序列化期间失败:MoveNextAction.Method.ReturnTypeCustomAttributes

Startup.cs

.AddControllersAsServices().AddNewtonsoftJson(options =>
{
    options.UseMemberCasing();
    options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    options.AllowInputFormatterExceptionMessages = true;
    options.SerializerSettings.Formatting = Formatting.None;
    options.SerializerSettings.ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = null
    };
    options.SerializerSettings.Error = (sender, args) =>
    {
        _logger.LogError($"Failed during serialization: {args.ErrorContext.Path}", args.ErrorContext.Error);
        args.ErrorContext.Handled = true;
    };
})

我在我的应用程序中搜索了串行

  • 有几个类具有[Serializable]属性

我还使用DeserializeObject

JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonValue); 

我尝试将jsonValue设置为null,但不幸的是这并没有触发SerializerSettings.Error。

如果您有任何提示或建议来生成SerializerSettings错误或进行调试,将不胜感激。


“_logger.LogError ($"Failed during serialization: {args.ErrorContext.Path}", args.ErrorContext.Error)” 实际上会打印什么?你能把它加到你的问题里吗?基本上,args.ErrorContext.Error 应该向你展示正在被序列化并失败的类型(在堆栈跟踪的底部)。 - OfirD
嗨,我已在顶部添加。序列化期间失败:MoveNextAction.Method.ReturnTypeCustomAttributes - Master
那是 args.ErrorContext.Path 的值。但 args.ErrorContext.Error 的值是多少呢? - OfirD
2个回答

1
你可以通过传递一个与控制器参数中指定的模型类不匹配的无效JSON请求正文来实现此操作。
定义一个具有int字段的模型类,然后发送一个HTTP请求,在该字段的JSON中存在字符串值。
这将作为默认值传递到控制器,并且在你的情况下,错误处理程序也应该被执行。
以下是一个可行的示例:
public class HomeController : Controller
{
    public class MyRequest
    {
        public int MyField { get; set; }
    }

    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    [HttpPost]
    public IActionResult Test([FromBody] MyRequest myRequest)
    {
        return Ok();
    }
}

如果您向 /Home/Test 发送 POST 请求,则值为:
{
    "MyField": "test"
}

那么您的错误处理程序将被调用,并且args.ErrorContext.Path的值将为MyField

虽然,args.ErrorContext.Error的值将为Message = "无法将字符串转换为整数:test。路径 'MyField',行2,位置18。"我认为我需要更深入地了解您的代码才能精确重现错误,但希望这有所帮助。


0
当您添加 .AddControllersAsServices().AddNewtonsoftJson... 时,它仅在操作的输入和输出期间触发(实际上是在模型绑定和返回操作结果时)。
因此,如果您想在整个项目中触发json序列化错误,则必须在启动时显式设置JsonSerializerSettings,如下所示:
var defaultJsonConvertSetting = new JsonSerializerSettings
            {
                Formatting = Formatting.None,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                ContractResolver = new DefaultContractResolver {NamingStrategy = null},
               
                Error = (sender, args) =>
                {
                    Console.WriteLine($"**********************Failed during serialization: {args.ErrorContext.Path}");
                    args.ErrorContext.Handled = true;
                }
                // other settings
            };

            JsonConvert.DefaultSettings = () => defaultJsonConvertSetting;

                .AddControllersAsServices().AddNewtonsoftJson(options =>
            {
                options.UseMemberCasing();
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.AllowInputFormatterExceptionMessages = true;
                options.SerializerSettings.Formatting = Formatting.None;
                options.SerializerSettings.ContractResolver = new DefaultContractResolver
                {
                    NamingStrategy = null
                };
                options.SerializerSettings.Error = (sender, args) =>
                {
                    _logger.LogError($"Failed during serialization: {args.ErrorContext.Path}", args.ErrorContext.Error);
                    args.ErrorContext.Handled = true;
                };
            });

感谢您提供的信息丰富的回复,我可以问一下如何触发错误吗? - Master
@大师,我在答案中已经说了!您应该在启动时定义“JsonSerializerSettings”。经过测试,可以正常工作。 - sa-es-ir
嗨,我看到在默认设置中,有额外的错误逻辑。但是这并没有完全说明如何触发实际的错误。换句话说,我怎样才能让控制台输出那一行?这是我帖子的主要问题。 - Master

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接