Проверка JSON перед десериализацией в объект C #

1

Если объект JavaScript в JSON не собирается десериализоваться в объект С#, который я хочу, как я могу допросить его, чтобы предоставить сообщение об ошибке, объясняющее, что не так с вводом? (Предполагая, что формат JSON верен, данные недействительны.)

Мой класс С#: (упрощенный)

public class Dependent
{
    public Dependent()
    {
    }
    public string FirstName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

Тестовый код для десериализации:

string dependents = @"[
                            {
                                ""FirstName"": ""Kenneth"",
                                ""DateOfBirth"": ""02-08-2013""
                            },
                            {
                                ""FirstName"": ""Ronald"",
                                ""DateOfBirth"": ""08-07-2011""
                            }
                      ]";

JavaScriptSerializer jss = new JavaScriptSerializer();

List<Dependent> deps = new List<Dependent>();
deps = jss.Deserialize<List<Dependent>>(dependents);

Все это работает. ЗА ИСКЛЮЧЕНИЕМ, если в качестве дня рождения передается не-дата, он не будет десериализован.

Я хочу предоставить сообщение об ошибке типа "Зависимая дата рождения 2 не является допустимой датой". или "Зависимый 2 должен быть моложе 18 лет".

Как я могу проверить детали JSON, если он не будет десериализоваться в моем объекте?

Возможное решение:

public class SerializableDependent
{
    public SerializableDependent()
    {
    }
    public string FirstName { get; set; }
    public string DateOfBirth { get; set; }
}

И тогда я не должен ошибаться, имея все как строку, и я могу прокручивать объекты и выполнять мою проверку. Однако это кажется неправильным.

  • 0
    Разве исключение не объясняет проблему?
Теги:
serialization
javascriptserializer

2 ответа

2
Лучший ответ

JavaScriptSerializer не поддерживает расширенную обработку ошибок. Я предлагаю вам использовать библиотеку Json.NET. Вы можете использовать JsonSerializerSettings объект Error обработчик событий, чтобы захватить более подробную информацию о том, что пошло не так. Информация об использовании этого члена содержится в документации.

Для вашего вышеописанного фрагмента кода обработчик, который заполняет массив сообщений об ошибках, может быть записан следующим образом:

public class Dependent
{
    public Dependent()
    {
    }
    public string FirstName { get; set; }
    public DateTime? DateOfBirth { get; set; } // Use a nullable object to hold the error value
}

void DeserializeTest()
{
   string dependents = @"[
                            {
                                ""FirstName"": ""Kenneth"",
                                ""DateOfBirth"": ""02-08-2013""
                            },
                            {
                                ""FirstName"": ""Ronald"",
                                ""DateOfBirth"": ""asdf""
                            }
                      ]";

    var messages = new List<string>();

    var settings = new JsonSerializerSettings(){
        Error = (s,e)=>{
            var depObj = e.CurrentObject as Dependent;
            if(depObj != null)
            {
                messages.Add(string.Format("Obj:{0} Message:{1}",depObj.FirstName, e.ErrorContext.Error.Message));
            }
            else 
            {
                messages.Add(e.ErrorContext.Error.Message);
            }
            e.ErrorContext.Handled = true; // Set the datetime to a default value if not Nullable
        }
    };
    var ndeps = JsonConvert.DeserializeObject<Dependent[]>(dependents, settings);
    //ndeps contains the serialized objects, messages contains the errors
}
  • 0
    Я закончил тем, что изменил DateOfBirth на string. Это неправильно, но делает DateTime обнуляемым, когда оно действительно не должно быть нулевым. Но я попробовал это и сработал бы отлично. Спасибо!
0

Вы можете проверить JSON на C# используя JSON Schema (инфраструктура, предоставленная Newtonsoft). Он позволяет проверять данные JSON. Ниже приведен код, иллюстрирующий, как он выглядит. Для получения дополнительной информации вы можете прочитать статью " Проверка JSON с помощью схемы JSON в С#

string myschemaJson = @"{'description': 'Сотрудник', 'type': 'object', 'properties': {'name': {'type': 'string'}, 'id': {'type': 'string'}, 'company': {'type': 'string'}, 'role': {'type': 'string'}, 'skill': {'type': 'array', 'items': {'type': 'string'}}} ";

     JsonSchema schema = JsonSchema.Parse(myschemaJson);

     JObject employee = JObject.Parse(@"{
        'name': 'Tapas', 'id': '12345', 'company': 'TCS',
        'role': 'developer',
        'skill': ['.NET', 'JavaScript', 'C#', 'Angular',
        'HTML']
     }");
     bool valid = employee.IsValid(schema);
     // True

     JsonSchema schema1 = JsonSchema.Parse(myschemaJson);

     JObject employee1 = JObject.Parse(@"{
        'name': null, 'id': '12345', 'company': 'TCS',
        'role': 'developer',
        'skill': ['.NET', 'JavaScript', 'C#', 'Angular',
        'HTML']
     }");

     IList<string> messages;
     bool valid1 = employee1.IsValid(schema1, out messages);
     // False
     // "Invalid type. Expected String but got Null. Line 2,
     // position 24."


     JsonSchema schema2 = new JsonSchema();
     schema2.Type = JsonSchemaType.Object;
     schema2.Properties = new Dictionary<string, JsonSchema>
     {
        { "name", new JsonSchema
           { Type = JsonSchemaType.String } },
        { "id", new JsonSchema
           { Type = JsonSchemaType.String } },
        { "company", new JsonSchema
           { Type = JsonSchemaType.String } },
        { "role", new JsonSchema
           { Type = JsonSchemaType.String } },
        {
           "skill", new JsonSchema
           {
              Type = JsonSchemaType.Array,
              Items = new List<JsonSchema>
                 { new JsonSchema
                    { Type = JsonSchemaType.String } }
           }
        },
     };

     JObject employee2 = JObject.Parse(@"{
        'name': 'Tapas', 'id': '12345',
        'company': 'TCS', 'role': 'developer',
        'skill': ['.NET', 'JavaScript', 'C#', 'Angular',
        'HTML']
     }");
     bool valid2 = employee2.IsValid(schema2);
     // True
  • 0
    эта библиотека не бесплатна более 1000 вызовов в час : The free-quota limit of 1000 schema validations per hour has been reached. Please visit http://www.newtonsoft.com/jsonschema to upgrade to a commercial license.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню