Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用字符串或int字段反序列化JSON对象的最佳实践是什么?_C#_.net_Json_Serialization_Deserialization - Fatal编程技术网

C# 用字符串或int字段反序列化JSON对象的最佳实践是什么?

C# 用字符串或int字段反序列化JSON对象的最佳实践是什么?,c#,.net,json,serialization,deserialization,C#,.net,Json,Serialization,Deserialization,我正在尝试使用Newton Json反序列化程序反序列化Json对象,如下所示: { "grades": 97 } Or this: { "grades": "" } public class Student { [JsonProperty("grades"), JsonConverter(typeof(IntConverter))] public int Grades; } 我想知道我应该如何在C#中正确定义一个类来表示这个对象?谢谢 请尝试使用动态关

我正在尝试使用Newton Json反序列化程序反序列化Json对象,如下所示:

{
  "grades": 97
}

Or this:

{
  "grades": ""
}
public class Student
{
    [JsonProperty("grades"), 
    JsonConverter(typeof(IntConverter))]
    public int Grades;
}

我想知道我应该如何在C#中正确定义一个类来表示这个对象?谢谢

请尝试使用
动态
关键字:

public class Rootobject
{
     public dynamic grades { get; set; }
}
它将与
string
int
一起使用。有关更多信息,请参阅

更新:

然后要转换成
int
string
我将使用
convert.ToString()
,因为它处理
null
值,对于
int
我将使用
Int32.TryParse()
,因为如果输入
drades
格式不正确,我可以更好地控制转换成
int

更新:


如果等级为“”,则C#中的任何可空类型将变为
null
。为此,可以使用
int?
。但是,如果等级类似于“3ds”,那么您必须使用一些动态方法。

我宁愿在POCO上使用自定义JsonConverter,这将确保对象被反序列化为一种预期类型,而不是使用
对象
动态
,然后必须在整个代码库中以怀疑的态度对待该属性

我会这样做:

public class IntConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value.GetType() == typeof(int))
            writer.WriteValue((int)value);
        else
            writer.WriteValue(value.ToString());
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => 
        ParseInt(reader.Value.ToString());

    public override bool CanConvert(Type objectType) =>
        objectType == typeof(int) || objectType == typeof(string);

    private static int ParseInt(string value)
    {
        int parsedInt = 0;
        int.TryParse(value, out parsedInt);
        return parsedInt;
    }
}
然后在POCO中使用此JsonConverter,如下所示:

{
  "grades": 97
}

Or this:

{
  "grades": ""
}
public class Student
{
    [JsonProperty("grades"), 
    JsonConverter(typeof(IntConverter))]
    public int Grades;
}

我会发现这是解决这些问题的“最佳实践”。

为什么不在类中将等级定义为对象?但这取决于反序列化器可以在内部成功地将等级反序列化为适当的类型(int或string)并将其分配给对象字段,对吗?我想知道是否会发生这种情况?一个int不能容纳一个字符串,但一个字符串可以容纳一个int。你是要求任意字符串还是空字符串
“”
?好吧,对于一般情况,没有比使用
对象
动态
更优雅的解决方案了。但是对于您的特定情况,您可以简单地使用
int?
而不是如何将其转换为正确的类型?通过尝试捕获运行时转换异常或任何更优雅的方式?谢谢很抱歉,意外编辑了您的答案,请忽略它。这不重要,但让我们说string。对于
string
我将使用
Convert.ToString()
,因为它处理
null
值,对于
int
我将使用
Int32.TryParse()
因为您可以更好地控制到
int
的转换。第二次更新确实是正确的答案。你的答案中应该有一个这样的代码示例,而不是动态。我认为为了匹配这个问题,应该使用
int?
为什么要将其设为空,@cypienautexier从他的用例中了解到,“
表示与0不同的
无等级
。在您的DTO和转换器中,“”被视为0。@CyprienAutexier让我们同意不同意这一点。在我看来,空值是邪恶的。好吧,我的观点不是讨论它们是否邪恶,而是你正在考虑
0===”
,但事实并非如此,并让你对OP所示的模型做出部分回答。