JSON проверка строки с более чем одним классом - PullRequest
1 голос
/ 28 января 2020

В моем бизнес-потоке у меня могут быть 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 Ответ

1 голос
/ 28 января 2020

Решение 1 : Добавить Тип поле:

Добавление поля, в котором указан тип объекта, вероятно, самый простой выбор, но вы должны иметь возможность изменить объекты, чтобы сделать это.

public Enum UserType { Teacher, Student, /* possibly other types */ }

public interface ISchoolMember 
{
    public string Name { get; }
    ..
    public UserType Type { get; }
}

Затем, получив JSON, вы можете проанализировать его в JObject и прочитать поле Тип:

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.");
    }
}

Эти два метода кажутся более многословными, чем исходный, но помогают отойти от программирования на основе исключений (это всегда не учитывается, поскольку обработка исключений очень затратна с точки зрения ресурсов) .

ps
эта реализация использует библиотеку Newtonsoft. Json, но я предполагаю, что другие библиотеки имеют аналогичные механизмы.

...