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

C# WebAPI集成Jil序列化器反序列化抛出Expected digit异常求助

解决Jil反序列化时的"Expected digit"错误

这个错误Jil.DeserializationException: 'Expected digit'通常发生在Jil尝试将非数字内容反序列化为数值类型(比如你的long类型的UserId或MobileDeviceId)时。结合你的代码和异常栈,我来帮你排查和解决问题:

可能的原因及对应解决方案

1. 请求JSON中的数值字段格式无效

最常见的情况是你的POST请求里,UserId或MobileDeviceId字段的值不是有效的整数:

  • 比如传了字符串("UserId": "123"而不是"UserId": 123)
  • 传了null(但你的模型里这两个字段是值类型long,不能为null)
  • 传了空字符串或其他非数字格式

解决方法:

  • 检查测试请求的JSON格式,确保这两个字段是纯数字类型,比如:
    {
      "UserId": 12345,
      "MobileDeviceId": 67890,
      "IsInitialLoad": true
    }
    
  • 如果业务上允许这两个字段为null,将模型改成可空类型:
    public class ReuestTest {
        public long? UserId { get; set; }
        public long? MobileDeviceId { get; set; }
        public bool IsInitialLoad { get; set; }
    }
    

2. JilFormatter的流读取逻辑问题

你的ReadFromStreamAsync方法直接同步读取流,没有考虑异步场景下的流完整性,可能导致读取到不完整的JSON内容,进而引发反序列化错误。

修复后的ReadFromStreamAsync方法:

public override async Task<object> ReadFromStreamAsync(Type type, Stream input, HttpContent content, IFormatterLogger formatterLogger)
{
    using (var reader = new StreamReader(input, SupportedEncodings.First(), true))
    {
        var json = await reader.ReadToEndAsync();
        var deserialize = TypedDeserializers.GetTyped(type);
        using (var stringReader = new StringReader(json))
        {
            var result = deserialize(stringReader, _options);
            return result;
        }
    }
}

这里做了两个关键改进:

  • 使用async/await异步读取流到末尾,确保获取完整的JSON内容
  • 将读取到的完整字符串用StringReader传给Jil的反序列化方法,避免流读取的潜在问题

3. 检查Jil版本兼容性

如果你的Jil版本比较旧,可能存在某些数值类型反序列化的bug。建议升级到最新稳定版,通过NuGet更新:

Install-Package Jil -Version [最新版本号]

4. 验证TypedDeserializers的委托创建

你的TypedDeserializers类通过反射创建反序列化委托,逻辑本身没问题,但可以添加校验提前发现反射问题:

private static Func<TextReader, Options, object> CreateDelegate(Type type)
{
    var genericMethod = _method.MakeGenericMethod(type);
    if(genericMethod == null)
    {
        throw new InvalidOperationException($"Failed to create generic deserialize method for type {type.FullName}");
    }
    return (Func<TextReader, Options, object>)genericMethod.CreateDelegate(typeof(Func<TextReader, Options, object>));
}

这样可以提前排查反射过程中的异常,避免后续反序列化时的隐性错误

额外调试技巧

在ReadFromStreamAsync方法里添加日志,输出读取到的原始JSON内容,这样可以快速定位是否是请求数据的问题:

var json = await reader.ReadToEndAsync();
// 添加日志输出json内容,比如用内置Trace或日志框架
System.Diagnostics.Trace.WriteLine($"Received JSON: {json}");

内容的提问来源于stack exchange,提问作者Satheeshkumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:41:03