使用c#解析JSON文件
本文关键字:文件 JSON 解析 使用 | 更新日期: 2023-09-27 18:12:04
我编写了一个c#应用程序,可以逐行读取JSON文件并从中写入csv文件。我已经为每种csv格式创建了模型文件,这些模型的对象在解析时被实例化,然后在最后被写入csv。
For example:如果输入文件名是abc。json,为abc创建并实例化对象,将其存储在List等数据结构中,最后将其写入csv。
JSON文件:
{
"Computer ID": "1697343078",
"Application Name": "Reporting Services Service",
"Date": "8'/25'/2015",
"Count": "1"
}
我要解析的代码如下:
using (System.IO.StreamReader sr = new System.IO.StreamReader(sFile, Encoding.UTF8))
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("Computer ID") && counter == 4)
{
string[] tokens = line.Split(':');
if (tokens.Length >= 2)
{
resourceID = reg.Replace(tokens[1], "");
}
counter = counter - 1;
line = sr.ReadLine();
}
}
由于输入文件中的数据格式或其他字段不一致,解析失败。代码抛出异常,对该特定文件的解析完全失败。我希望我的代码拒绝要解析的记录,并继续解析文件中的其他记录,并最终为其生成csv。
我希望它的行为如下:逐行读取文件如果在解析时发生任何错误,不要实例化该对象,并继续解析该文件的其他行将对象写入csv
任何帮助都会很感激。
可以使用Json。. NET解析JSON数据。为此,您需要:
- 定义与JSON对象相对应的类。
- 当出现
DateTime
属性时,将其声明为可空值。如果遇到像"没有找到日期,所以没有返回数据"这样的字符串,那么可以在属性中存储空值。 - 创建您自己的
DateTimeConverter
,在解析可为空的DateTime
时,尝试您可能遇到的各种日期时间格式。如果遇到无效的格式,返回null
而不是抛出异常。 - 应用到
DateTime
属性使用JsonConverterAttribute
因此,给定以下转换器:
public class DateTimeConverter : IsoDateTimeConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
// For various JSON date formats, see
// http://www.newtonsoft.com/json/help/html/DatesInJSON.htm
// Try in JavaScript constructor format: new Date(1234656000000)
if (token.Type == JTokenType.Constructor)
{
try
{
var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { new JavaScriptDateTimeConverter() } }));
if (result != null)
return result;
}
catch (JsonException)
{
}
}
// Try ISO format: "2009-02-15T00:00:00Z"
if (token.Type == JTokenType.String)
{
try
{
var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat }));
if (result != null)
return result;
}
catch (JsonException)
{
}
}
// Try Microsoft format: "'/Date(1234656000000)'/"
if (token.Type == JTokenType.String)
{
try
{
var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }));
if (result != null)
return result;
}
catch (JsonException)
{
}
}
if (token.Type == JTokenType.String)
{
// Add other custom cases as required.
}
return null;
}
}
你可以这样应用到你的类:
public class ComputerData
{
[JsonProperty("Computer ID")]
public string ComputerID { get; set; }
[JsonProperty("Application Name")]
public string ApplicationName { get; set; }
[JsonConverter(typeof(DateTimeConverter))]
public DateTime? Date { get; set; }
public int Count { get; set; }
}
小提琴例子。
您不需要JSON解析器。您所需要的只是尝试catch块,以在解析数据格式不正确的行中忽略异常。通过检查条件,您应该能够处理这个问题。
这里可能是一个解决方案,我以前做过这样的事情,但我后来在最后自己写了一个JSON解析器....
实体类
public class Info {
public string ComputerID {get;set;}
public string ApplicationName {get;set;}
...
}
用于解析文本,并在解析
时忽略错误。 Info record = null;
var recordSet = new List<Info>();
using (System.IO.StreamReader sr = new System.IO.StreamReader(sFile, Encoding.UTF8))
{
while ((line = sr.ReadLine()) != null)
{
if (record==null){
record = new Info();
recordSet.Add(record)
}
try {
} catch ( Exception e) {
//You either log the data or ignore the exception here
}
//Check your property here, replace with your actual implementation here
if (record.ComputerID!=null && record.ApplicationName!=null) {
record = null;
}
}
}
随着事情变得越来越复杂,您可能仍然需要一个解析器来处理它,但这实际上取决于您的需要。