Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# JSON.NET不使用try/catch解析可选值_C#_Json_Linq_Json.net - Fatal编程技术网

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

C# JSON.NET不使用try/catch解析可选值,c#,json,linq,json.net,C#,Json,Linq,Json.net,因此,我工作的公司要求我为需要使用.NET访问API的客户公司制作一个C#库。到目前为止,我有一个可用的库,但在解析可选属性时一直遇到问题。我们在后端使用mongoDB,并且mongoDB不存储未提供的属性,即使这些属性是在模式中定义的 例如,我的模式可能如下所示: { name:String, id:Number, phone:String, email:String, experience:[] } 在我制作文件时: { name:"joe", i

因此,我工作的公司要求我为需要使用.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
解析上述代码时,解析程序会抛出空引用异常,这是有充分理由的,因为我试图解析的值不存在,并且我引用这些值的方式是这样的:

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();
JObject o=JObject.Parse(json)//将json解析为JObject json对象
字符串名称=(字符串)o[“名称”];
int id=(int)o[“id”];
字符串phone=(字符串)o[“phone”];
字符串email=(字符串)o[“emain”];
List exp=o[“experience”]。选择(t=>(string)t.ToList();
现在我的代码更加客观了,我使用LINQ创建了一个名为
Job
的对象和一个
Jobs
的对象来存储JObject,在这种方式下,您可以使用
Jobs
对象的方法从中查询某些值,该对象使用原始JSON字符串初始化


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

除非有充分的理由不能使用通用的反序列化/序列化方法,否则我建议您改变使用这些方法的方法。一般来说,我认为您在上面所做的条件式、特定于属性的解析是非常糟糕的做法。这是一个例子

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.
然后,在代码中,您有如下内容:

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中使用的任何构造都有一个C#等价物,您只需分解它并确定它是什么。

您是否尝试过
var job=JsonConvert.DeserializeObject(json)?我不确定我是否理解。MongoDB是无模式的,对吗?你不应该解析任何东西。您可以将其作为BSON文档转储到Mongo@mason这是Json.Net的类。@tsturzl您似乎遗漏了什么。goto first_评论@tsturzl您的问题在于您试图手动反序列化,然后这是Json.NET开箱即用的功能,正如第一条评论和evan的回答中所示。谢谢您C#绝对不是我的强项。如果我想将经验设置为列表而不是数组,那会有问题吗?@tsturzl一点也不会。只要在你的类中做到这一点,所有的东西都会一样工作。我怎样才能解析嵌入的对象呢?我在数组中嵌入对象,在其他对象中嵌入对象。这个JSON非常复杂。@tsturzl所以它只是将JSON中的数据模型转换为C#中的类。我将用另一个小片段进行编辑,这可能会让您朝着正确的方向前进。我会包括更多的细节,但这是非常乏味的,我不能复制/粘贴任何实际工作的明显原因。
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!
}
public class jobsWrapper
{
    public List<Job> jobs;
}