【问题标题】:The JSON value could not be converted to System.Int32JSON 值无法转换为 System.Int32
【发布时间】:2019-12-28 19:31:26
【问题描述】:

我想将对象数据发送到我的 Web API。 API接受一个class的参数,属性是int和string的类型。

这是我的课:

public class deneme
{
   public int ID { get; set; }
   public int sayi { get; set; }
   public int reqem { get; set; }
   public string yazi { get; set; }
}

这是我的 JSON 对象:

{
   "id":0,
   "sayi":"9",
   "reqem":8,
   "yazi":"sss"
}

我希望 api 将属性“sayi”读取为整数。 但是因为它不能,所以它给出了错误:

The JSON value could not be converted to System.Int32. Path: $.sayi

我该如何解决这个问题?

【问题讨论】:

  • 您不能将字符串值分配给 int 变量,请将字符串强制转换为 int
  • 它必须是"sayi": 9(不带引号),或者你必须将它绑定到一个字符串而不是一个int,然后自己转换它。没有其他选择。
  • 在我从 asp.net core 2.2 更新到 3.0 之前,当我输入“9”时它就起作用了。更新后就不行了。
  • 当数值高于或低于整数范围时,这也可能是错误消息,您可能需要将其定义为 long、float、double 等。仅供其他人使用谷歌搜索
  • .NET 5 开始支持,请查看答案stackoverflow.com/a/67153702/3799228

标签: c# json asp.net-core-webapi


【解决方案1】:

从 .NET 5 开始,option to deserialize numbers 表示为 JSON 字符串,而不是引发异常。

using System.Text.Json;
using System.Text.Json.Serialization;

var options = new JsonSerializerOptions()
{
     NumberHandling = JsonNumberHandling.AllowReadingFromString |
     JsonNumberHandling.WriteAsString
};

// serialize
string denemeJson = JsonSerializer.Serialize<Deneme>(deneme, options);

// deserialize
Deneme denemeDeserialized = JsonSerializer.Deserialize<Deneme>(denemeJson, options);

【讨论】:

  • 实际上下文中不存在名称 JsonNumberHandling
  • @JhonHernández 你确定你使用的是 .NET 5 吗?
  • 赞成。这是 .NET 5 项目的答案。
【解决方案2】:

在.net core中可能会遇到这个问题,您可以将数据类型从int更改为int64

【讨论】:

    【解决方案3】:

    更好地将值解析为Integer 并将数据从您的客户端应用程序发送到服务器端应用程序,这对我有用。 编码愉快!!

    {
      "id":parseInt(0),
      "sayi":parseInt(9),
      "reqem":parseInt(8),
      "yazi":"sss"
     }
    

    【讨论】:

      【解决方案4】:

      还有另一种方法:只需使用数字类型的类型字符串创建一个 DTO,并将其转换为控制器或您需要的类型。

      【讨论】:

        【解决方案5】:

        在 js 模型中,确保你的值被格式化为 parseFloat();

        【讨论】:

          【解决方案6】:

          .NET CORE 3.X 中,序列化/反序列化过程是使用System.Text.Json 而不是Newtonsoft Json 完成的。爱德华的回答并不完全适合我:

          1. 从 Nuget Manager Microsoft.AspNetCore.Mvc.NewtonsoftJson 安装不会使第 2 步编译。
          2. 是的,添加启动services.AddControllers().AddNewtonsoftJson(); - 您将收到错误,AddNewtonsoftJson() 无法识别。

          至少这发生在我身上。

          作为修复,卸载您在步骤 1 中安装的内容。在包管理器控制台中,运行:Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.0.0-preview8.19405.7。这对我有用。

          【讨论】:

            【解决方案7】:

            首先你应该为它创建一个JsonConverter

            using System;
            using System.Buffers;
            using System.Buffers.Text;
            using System.Text.Json;
            using System.Text.Json.Serialization;
            
            namespace sample_22_backend.Converters
            {
                public class IntToStringConverter : JsonConverter<int>
                {
                    public override int Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
                    {
                        if (reader.TokenType == JsonTokenType.String)
                        {
                            ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                            if (Utf8Parser.TryParse(span, out int number, out int bytesConsumed) && span.Length == bytesConsumed)
                            {
                                return number;
                            }
            
                            if (int.TryParse(reader.GetString(), out number))
                            {
                                return number;
                            }
                        }
            
                        return reader.GetInt32();
                    }
            
                    public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
                    {
                        writer.WriteStringValue(value.ToString());
                    }
                }
            }
            

            然后以这种方式在模型的属性上使用它:

            [JsonConverter(typeof(IntToStringConverter))]
            public int GenreId { set; get; }
            

            或者你可以全局添加:

            services.AddControllers()
                    .AddJsonOptions(options => 
                            options.JsonSerializerOptions.Converters.Add(new IntToStringConverter()));
            

            【讨论】:

            • 不应该是stringtointconvertor吗?
            • 是否有任何非自定义方法可以做到这一点。我认为他们会解决这个问题并允许人们传递不带引号的整数。这破坏了许多现有的 API。我认为这是最好的答案,因为我觉得使用 Newtonsoft 并没有朝着正确的方向前进
            • 计划用于 .NET 的下一个版本:github.com/dotnet/runtime/issues/30255
            • 您也可以在调用 Deserialize 方法时将其作为 JsonSerializerOptions 的一部分传递:var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new API.Helpers.StringToGuidConverter() } } ; StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream);字符串 json = reader.ReadToEnd(); return JsonSerializer.Deserialize(json, options);
            【解决方案8】:

            对于 Asp.Net Core 3.0,它使用System.Text.Json 进行序列化和反序列化。

            为了使用旧行为,您可以通过引用 Json.NET support 在 ASP.NET Core 3.0 项目中使用 Json.NET。

            简答:

            1. 安装Microsoft.AspNetCore.Mvc.NewtonsoftJson,这是预览版。
            2. 更改为services.AddControllers().AddNewtonsoftJson();

            【讨论】:

            • 完美,谢谢。问题是,为什么微软不能只使用下载次数最多的 NuGet 包……
            • 它没有那么高效或高性能。 Newtonsoft 是一个很棒的软件包,因为它涵盖了大量的用例。有了这么多的用例,就会产生性能开销成本。微软非常专注于他们的。它是 aspnetcore 的性能驱动的。
            • 我只需要走这条路就可以让我的对象正确反序列化。出于某种原因,Microsoft.AspNetCore.Mvc.NewtonsoftJson 没有出现在包管理器中,必须使用Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.0.0 手动安装它。这将表明该软件包可以更新到 3.1.0,但它需要 net core 3.1,在撰写此评论时仍处于预发布状态。写这篇文章希望它可以帮助遇到这个问题的其他人!
            猜你喜欢
            • 2020-03-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-06
            • 2017-06-11
            • 2021-05-06
            • 1970-01-01
            相关资源
            最近更新 更多