JSON 字符串验证超过一个 class
JSON string validate with more than one class
在我的业务流程中,我可能有 JSON 个不同格式的字符串。
例如:
String jsonSring = readValue();//this JSON String may contain Teacher object or Student Object
目前我正在使用这个简单的方法来验证 JSON 是否相对于 Teacher
或 Student
:
try{
Teacher teacher = om.readValue(jsonSring, Teacher.class);
}catch(Exception e){
Student student = om.readValue(jsonSring, Student.class);
}
有任何验证 JSON 内容的简化方法吗?
解决方案 1:添加一个 Type 字段:
添加指定对象类型的字段可能是最简单的选择,但您必须能够更改对象才能做到这一点。
public Enum UserType { Teacher, Student, /* possibly other types */ }
public interface ISchoolMember
{
public string Name { get; }
..
public UserType Type { get; }
}
然后一旦有了 JSON,就可以将其解析为 JObject 并读取 Type 字段:
public ISchoolMember Deserialize(string jsonString)
{
var o = JObject.Parse(jsonString);
return (UserType)o["Type"] switch
{
UserType.Teacher => JsonConvert.Deserialize<Teacher>(jsonString),
UserType.Student => JsonConvert.Deserialize<Student>(jsonString),
_ => throw new ArgumentException("...")
};
}
解决方案 2:检查特殊字段。
如果无法添加新字段,您可以检查解析后的 JObject 是否包含仅属于两个对象之一的字段:
public void DeserializeAndDoStuff(string jsonString)
{
var teacherOrStudent = JObject.Parse(jsonString);
if (teacherOrStudent["StudentId"] != null) // it is a student!
{
Student s = teacherOrStudent.ToObject<Student>();
// ... do stuff with the student object
}
else if (teacherOrStudent["TeacherId"] != null) // it is a teacher!
{
Teacher t = teacherOrStudent.ToObject<Teacher>();
// ... do stuff with the teacher object
}
else
{
throw new ArgumentException("The given object is neither a teacher or a student.");
}
}
这两种方法看起来比原来的方法更冗长,但有助于摆脱基于异常的编程(总是不建议这样做,因为处理异常在资源方面非常昂贵)。
p.s.
此实现使用 Newtonsoft.Json 库,但我猜其他库也有类似的机制。
在我的业务流程中,我可能有 JSON 个不同格式的字符串。
例如:
String jsonSring = readValue();//this JSON String may contain Teacher object or Student Object
目前我正在使用这个简单的方法来验证 JSON 是否相对于 Teacher
或 Student
:
try{
Teacher teacher = om.readValue(jsonSring, Teacher.class);
}catch(Exception e){
Student student = om.readValue(jsonSring, Student.class);
}
有任何验证 JSON 内容的简化方法吗?
解决方案 1:添加一个 Type 字段:
添加指定对象类型的字段可能是最简单的选择,但您必须能够更改对象才能做到这一点。
public Enum UserType { Teacher, Student, /* possibly other types */ }
public interface ISchoolMember
{
public string Name { get; }
..
public UserType Type { get; }
}
然后一旦有了 JSON,就可以将其解析为 JObject 并读取 Type 字段:
public ISchoolMember Deserialize(string jsonString)
{
var o = JObject.Parse(jsonString);
return (UserType)o["Type"] switch
{
UserType.Teacher => JsonConvert.Deserialize<Teacher>(jsonString),
UserType.Student => JsonConvert.Deserialize<Student>(jsonString),
_ => throw new ArgumentException("...")
};
}
解决方案 2:检查特殊字段。
如果无法添加新字段,您可以检查解析后的 JObject 是否包含仅属于两个对象之一的字段:
public void DeserializeAndDoStuff(string jsonString)
{
var teacherOrStudent = JObject.Parse(jsonString);
if (teacherOrStudent["StudentId"] != null) // it is a student!
{
Student s = teacherOrStudent.ToObject<Student>();
// ... do stuff with the student object
}
else if (teacherOrStudent["TeacherId"] != null) // it is a teacher!
{
Teacher t = teacherOrStudent.ToObject<Teacher>();
// ... do stuff with the teacher object
}
else
{
throw new ArgumentException("The given object is neither a teacher or a student.");
}
}
这两种方法看起来比原来的方法更冗长,但有助于摆脱基于异常的编程(总是不建议这样做,因为处理异常在资源方面非常昂贵)。
p.s.
此实现使用 Newtonsoft.Json 库,但我猜其他库也有类似的机制。