JSON 值无法转换为 System.Int32

问题描述 投票:0回答:10

我想将对象的数据发送到我的 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

我该如何解决这个问题?

c# json asp.net-core-webapi
10个回答
120
投票

对于Asp.Net Core 3.0,它使用

System.Text.Json
进行序列化和反序列化。

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

简短回答:

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

39
投票

从 .NET 5 开始,有一个用于反序列化数字的选项,这些数字表示为 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);

30
投票

首先你应该为它创建一个

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()));

10
投票

.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
。这对我有用。


3
投票

更好地将值解析为

Integer
并将数据从客户端应用程序发送到服务器端应用程序,这对我有用。 快乐编码!!

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

2
投票

仅供参考,我认为我已经实现了建议的答案,因为我的 Program.cs 中有以下内容

builder.Services.AddControllersWithViews().AddJsonOptions(opt =>
                {
                    opt.JsonSerializerOptions.PropertyNamingPolicy = null;
                    opt.JsonSerializerOptions.AllowTrailingCommas = true;
                    opt.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString |
                        JsonNumberHandling.WriteAsString;                    
                    opt.JsonSerializerOptions.IncludeFields = true;
                });

由于某种原因,它在我的控制器中被忽略,我不知道为什么,我必须实施 HRKoder 建议的修复才能工作。


1
投票

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


1
投票

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


0
投票

只需检查对象属性类型是否为 int 而不是 double。我将 int 更改为 double 在我的情况下它对我有用


-3
投票

在.net core中可能会遇到这个问题,尝试使用

  1. parseFloat() 或 parseInt() 或
  2. 使用自定义属性
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class YOUR_CLASS
{
   public int ID { get; set; }
   [JsonConverter(typeof(IntFromStringConverter))]
   public int Sayi { get; set; }
   public int Reqem { get; set; }
   public string Yazi { get; set; }
}

public class IntFromStringConverter : JsonConverter<int>
{
    public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        string stringValue = reader.Value.ToString();

        // Parse the string to int
        if (int.TryParse(stringValue, out int parsedInt))
        {
            return parsedInt;
        }
        else
        {
            throw new JsonSerializationException("Failed to convert string to int.");
        }
    }

    public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString());
    }
}

3.在JSON级别要求我们可以使用“sayi”:9作为数字。 而不是对 C# 进行任何更改。

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

  1. 使用动态对象和 TryParse
       // Deserialize JSON to dynamic object
        dynamic jsonObj = JsonConvert.DeserializeObject(jsonData);
        int sayi;
        if (jsonObj.sayi != null && int.TryParse(jsonObj.sayi.ToString(), out sayi))
        {
            // Parsing successful
        }
        else
        {
            sayi = 0; // handle null/assign default value
        }
© www.soinside.com 2019 - 2024. All rights reserved.