【问题标题】:Error converting value "null" to type 'System.Nullable`1[System.Int64]'将值“null”转换为类型“System.Nullable`1[System.Int64]”时出错
【发布时间】:2020-01-20 23:50:03
【问题描述】:

我有一个 JSON 对象,其中包含一个 null 作为字符串,这是无法避免的,当我将此对象发送到我的 API 时,我收到此错误提示

将值“null”转换为类型时出错 'System.Nullable`1[System.Int64]'

我的 JSON 示例

{ 
  Name:'Test',
  Id:'null'
}

我的模型/DTO

class Class1{
  public string Name {get;set;}
  public long? Id {get;set;}
}

【问题讨论】:

  • 在你的 json 对象中,'null' 是一个字符串。
  • 如何在 JSON 中填充值?数字也会有引号,还是只有空?
  • 是的,它包含字符串数字,例如 '1' 或 '2' @ColinM
  • 您是在使用 JSON.NET 还是 System.Text.Json 进行序列化/反序列化?

标签: c# json


【解决方案1】:

您可以通过使用JsonConverter 来处理将string 解析为可以为空的long? 的逻辑来实现此目的。

第一个使用 Newtonsoft.Json 的例子

public class NewtonsoftStringToLongJsonConverter : Newtonsoft.Json.JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        var value = (string)reader.Value;
        if (string.Equals("null", value, StringComparison.InvariantCultureIgnoreCase))
        {
            return null;
        }

        if (!long.TryParse(value, out var parsedValue))
        {
            return null;
        }

        return parsedValue;
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

您的模型更新为

public class Class1
{
    public string Name { get; set; }

    [Newtonsoft.Json.JsonConverter(typeof(NewtonsoftStringToLongJsonConverter))]
    public long? Id { get; set; }
}

第二个选项使用 System.Text.Json 实现。

public class SystemTextStringToLongJsonConverter : System.Text.Json.Serialization.JsonConverter<long?>
{
    public override bool CanConvert(Type typeToConvert)
        => typeToConvert == typeof(long?);

    public override long? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var value = reader.GetString();
        if(string.Equals("null", value, StringComparison.InvariantCultureIgnoreCase))
        {
            return null;
        }

        if(!long.TryParse(value, out var parsedValue))
        {
            return null;
        }

        return parsedValue;
    }

    public override void Write(Utf8JsonWriter writer, long? value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

最后,您的模型更新为

public class Class1
{
    public string Name { get; set; }

    [Newtonsoft.Json.JsonConverter(typeof(NewtonsoftStringToLongJsonConverter))]
    public long? Id { get; set; }
}

【讨论】:

  • 这是无法避免的,我已经在我的问题中提到过,无论如何感谢您的建议
  • @ANRUpgradedVersion 我已经根据您的标准更新了我的答案,对于略过这个问题,我深表歉意。
  • 感谢您的建议,我真的很感激,但我正在寻找一个解决模型/ DTO 的解决方案,而这需要在所有可以为空的长属性和每个类中的所有类上实现API 模型,这是一个接受它的问题。 @ColinM
  • @ANRUpgradedVersion 使用 Newtonsoft(我假设您正在使用)您还可以通过 JsonSerializerSettings 将转换器添加到序列化程序,这将跳过将属性应用于模型的需要。请用所有您的要求更新您的问题。
【解决方案2】:

获取json字符串。执行string.Replace("'null'", "null") 然后将其映射到您的dto

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2020-10-05
    • 2017-06-11
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    相关资源
    最近更新 更多