因此,我一直在为之工作的公司要求我为需要使用.NET访问我们的API的客户公司制作一个C#库。到目前为止,我有一个工作库,但我一直在解析可选属性时遇到问题。我们在后端使用mongoDB,而mongoDB不存储未提供的属性,即使它们已在模式中定义。
例如,我的架构可能如下所示:
{
name:String,
id:Number,
phone:String,
email:String,
experience:[]
}
我在哪里制作文件:
{
name:"joe",
id:5,
phone:"222-222-2222",
}
我的文档中不存在属性email
和experience
,因此我的JSON看起来与上面显示的完全相同。但是,这些值不是必需值,但我仍然需要解析其余的值。问题是,当我在解析email
或experience
时解析上面的代码以获取所有可能的值时,解析器会抛出一个Null Reference Exception,并且有充分的理由因为我正在尝试的值解析不存在,我引用这些值的方式如下:
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,以便您可以使用它来查询某些值使用原始JSON字符串初始化的Jobs
对象的方法。
我认为处理JSON中的可选属性的唯一方法是尝试/捕获每个值。这似乎非常草率,我必须解析的JSON总共约40-50个属性。这似乎是非常缓慢和代码的混乱。我想知道我是否可以实现这是一种更清洁更有效的方式。
答案 0 :(得分:6)
除非有充分的理由不能使用通用的反序列化/序列化方法,否则我建议您改变使用方法。一般来说,我认为你在上面做的有条件的,属性特定的解析类型是非常糟糕的做法。这是一个例子;
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
的{{1}}个对象。使用以下C#类定义;
jobs
json中使用的任何构造都具有C#等价物,你只需要分解它并确定它是什么。