JSON.. NET解析可选值而不使用try/catch

本文关键字:try catch NET JSON | 更新日期: 2023-09-27 17:49:27

所以我一直工作的公司要求我为客户公司做一个c#库,他们需要用。net访问我们的API。到目前为止,我有一个工作库,但我一直在解析可选属性时遇到问题。我们在后端使用mongoDB,并且mongoDB不会存储未提供的属性,即使它们在模式中定义。

例如,我的模式可能看起来像:

{
   name:String,
   id:Number,
   phone:String,
   email:String,
   experience:[]
}

创建文档的位置:

{
   name:"joe",
   id:5,
   phone:"222-222-2222",
}

属性emailexperience在我的文档中不存在,所以我的JSON看起来与上面显示的完全一样。然而,这些值不是必需的值,但我仍然需要解析它的其余部分。问题是,当我为所有可能的值解析上面的代码时,当我解析emailexperience时,解析器抛出一个空引用异常,并且有很好的理由,因为我试图解析的值不存在,我引用这些值的方式是这样的:

JObject o=JObject.Parse(json); //parse json to JObject json object
string name=(string)o["name"];
int id=(int)o["id"];
string phone=(string)o["phone"];
string email=(string)o["emain"];
List<string> exp=o["experience"].Select(t => (string)t).ToList();

现在我的代码更加客观,我使用LINQ创建一个名为Job的对象和一个名为Jobs的对象来存储JObject,在这种方式下,您可以使用Jobs对象的方法来查询它的某些值,该方法初始化了原始JSON字符串。

事情是我能想到的处理JSON中的可选属性的唯一方法是尝试/捕获每个值。这看起来很草率,我需要解析的JSON总共有40-50个属性。这看起来会非常慢,而且代码会非常混乱。我想知道我是否可以实现这是一个更干净,更有效的方式。

JSON.. NET解析可选值而不使用try/catch

除非有很好的理由不能使用通用的反序列化/序列化方法,否则我建议您更改方法以使用这些方法。一般来说,我认为您上面所做的条件、属性特定解析类型是非常糟糕的实践。下面是一个例子;

public class Job
{
   public string name;
   public string id;
   public string phone;
   public string email;
   public string[] experience; // can also be a List<string> without any problems
}
Job j = JsonConvert.DeserializeObject<Job>(jsonString);
string output = JsonConvert.SerializeObject(j);
//will include "optional" parameters, meaning if there is no phone value it will be an empty string but the property name will still be there.

如果你真的想确认这一点,比如,一些必需的参数包括在内,但其他一些可选的没有,我建议使用json模式与json.NET结合使用。您可以执行如下操作;

//schema in flat text file I read with File.ReadAllText(path);
{
    "type":"object",
    "$schema": "http://json-schema.org/draft-03/schema",
    "required":true,
    "properties":{
        "name": { "type":"string", "required":true },
        "id": { "type":"string", "required":true },
                "phone": { "type":"string", "required":false },
                "email": { "type":"string", "required":false },
                "experience": { "type":"array", "required":true, "items": { "string" } }
    }
}

然后在代码中有类似;

JObject obj = JObject.Parse(json);
JsonSchema jscheme = JsonSchema.Parse(File.ReadAllText(thatSchemaAbove));
IList<string> errors;
obj.IsValid(jscheme, out errors);
if (errors.Count() > 0)
{
     //json didn't match the schema, do something about it!
}
编辑:处理复杂对象;

假设您的json是一个具有Job对象数组的对象,称为jobs。使用下面的c#类定义;

public class jobsWrapper
{
    public List<Job> jobs;
}

json中使用的任何结构都有c#的等效结构,你只需要分解它并确定它是什么