Cinchoo ETL - JSON Writer

下载源代码	下载编译文件 (.NET Framework)	下载编译文件 (.NET Standard / .NET Core)

内容

  1. 介绍2。要求3。“Hello World !”样本

3.1。快速写入-数据优先方法3.2。代码优先方法3.3。Configuration First 方法
4. 记录所有记录Write 记录手动6。自定义JSON记录8。自定义JSON字段

8.1。defaultvalue 8.2。chofallbackvalue 8.3。类型转换器

8.3.1。8.3.2声明性方法。8.3.3配置方法。自定义值转换器方法
8.4。验证8.5。choignoremember 8.6。stringlength 8.6。显示8.7。DisplayName
10. 回调机制

10.1使用JSONWriter events 10.2 实现IChoNotifyRecordWrite接口10.1 beginwrite 10.2 endwrite 10.3 beforerecordwrite 10.4 afterrecordwrite 10.5 recordwriteerror 10.6 beforerecordfieldwrite 10.7 afterrecordfieldwrite 10.8 RecordWriteFieldError
11. 定制12。使用动态对象13。异常15。使用元类型注释16。配置选择

手动配置16.2自动映射配置16.3附加元类型类
17. ToTextAll Helper方法17a。18 ToText 辅助方法。写datareaderhelper方法19。编写DataTable Helper方法20。高级的主题

重写转换器格式规范20.2货币支持20.3枚举支持20.4布尔值支持20.5日期时间支持
21. 流利的API

21.1。nullvalue处理21.2. 格式化21.3与字段21.4 与字段21.5. ignorefieldvaluemode 21.6 columncountstrict 21.7。配置21.8。设置
22. 常见问题解答

22.1。如何序列化一个对象?22.2。如何序列化对象的集合?22.3。如何序列化动态对象?22.4。如何序列化匿名对象?22.5。如何序列化集合?22.6。如何序列化字典?22.7。如何序列化数据表?22.8。如何序列化JSON到一个文件?22.9。如何序列化未缩进的JSON?22.10。如何序列化条件属性?22.11。如何序列化的日期时间在自定义日期格式?如何从Json序列化中排除属性?22.13.如何将Xml转换成JSON?22.14.如何将CSV转换成JSON?

  1. 介绍

ChoETL是一个用于。net的开放源码ETL(提取、转换和加载)框架。它是一个基于代码的库,用于在。net环境中从多个数据源提取数据、转换并加载到自己的数据仓库中。您可以在数据仓库中立即拥有数据。

本文讨论如何使用ChoETL框架提供的ChoJSONWriter组件。它是一个将JSON数据保存到文件/外部数据源的简单实用程序类。

相应的ChoJSONReader,一篇JSON阅读器文章可以在这里找到。

特点:

遵循JSON标准文件规则。在生成文件时支持区域性特定的日期、货币和数字格式。支持不同的字符编码。提供良好的控制日期,货币,枚举,布尔,数字格式时写文件。详细和健壮的错误处理,允许您快速发现和修复问题。缩短开发时间。

  1. 要求

这个框架库是用c#编写的,使用。net 4.5 framework /。net core 2.x。

3.“Hello World !”样本

创建一个示例VS.NET(。NET Framework 4.5)控制台应用程序项目安装ChoETL via Package Manager consoleusingnuget命令基于工作。NET版本:

安装包ChoETL。json安装包ChoETL.JSON.NETStandard
使用ChoETL名称空间

让我们从一个简单的示例开始,该示例生成下面有两列的JSON文件

清单3.1示例JSON数据文件(emp.json)

隐藏,复制Code[
{
“Id”: 1,
“Name”: “Mark”
},
{
“Id”: 2,
“Name”: “Jason”
}
]

有许多方法可以通过最小的设置创建JSON文件。

3.1。快速写入-数据优先方法

这是一种从零开始配置的快速创建JSON文件的方法。不需要任何类型的POCO对象。下面的示例代码展示了如何使用动态对象生成示例JSON文件

清单3.1.1将对象列表写入JSON文件

隐藏,复制CodeList objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 2;
rec2.Name = “Jason”;
objs.Add(rec2);

using (var parser = new ChoJSONWriter(“emp.json”))
{
parser.Write(objs);
}

在上面的示例中,我们将动态对象列表一次性提供给JSONWriter,以便将它们写入JSON文件。

清单3.1.2将每个对象写入JSON文件

隐藏,复制Codeusing (var parser = new ChoJSONWriter(“emp.json”))
{
dynamic rec1 = new ExpandoObject();
rec1.Id = 1;
rec1.Name = “Mark”;
parser.Write(item);

dynamic rec1 = new ExpandoObject();
rec1.Id = 2;
rec1.Name = "Jason";
parser.Write(item);

}

在上面的示例中,我们控制构造,将每个动态记录传递给JSONWriter,以使用写重载生成JSON文件。

3.2。代码首先方法

这是使用类型化POCO类生成JSON文件的另一种zeo-config方法。首先定义一个简单的POCO类来匹配底层JSON文件布局

清单3.2.1简单的POCO实体类

隐藏,复制Codepublic partial class EmployeeRecSimple
{
public int Id { get; set; }
public string Name { get; set; }
}

在上面,POCO类定义了两个与示例JSON文件模板匹配的属性。

清单3.2.2保存为JSON文件

隐藏,复制CodeList objs = new List();

EmployeeRecSimple rec1 = new EmployeeRecSimple();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

EmployeeRecSimple rec2 = new EmployeeRecSimple();
rec2.Id = 2;
rec2.Name = “Jason”;
objs.Add(rec2);

using (var parser = new ChoJSONWriter(“emp.json”))
{
parser.Write(objs);
}

上面的示例展示了如何创建来自类型化POCO类对象的JSON文件。

3.3。Configuration First 方法

在这个模型中,我们定义了JSON配置,包括所有必需的参数以及生成示例JSON文件所需的JSON列。

清单3.3.1定义JSON配置

隐藏,复制CodeChoJSONRecordConfiguration config = new ChoJSONRecordConfiguration();
config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Id”));
config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Name”));

在上面,类定义了两个与示例JSON文件模板匹配的JSON属性。

清单3.3.2生成没有POCO对象的JSON文件

隐藏,复制CodeList objs = new List();

dynamic rec1 = new ExpandoObject();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 2;
rec2.Name = “Jason”;
objs.Add(rec2);

using (var parser = new ChoJSONWriter(“emp.json”, config))
{
parser.Write(objs);
}

上面的示例代码展示了如何使用预定义的JSON配置设置从动态对象列表生成JSON文件。在JSONWriter构造函数中,我们指定了JSON配置配置对象,以便在创建文件时遵循JSON布局模式。如果JSON列的名称或计数不匹配,将报告为错误并停止写入过程。

清单3.3.3使用POCO对象保存JSON文件

隐藏,复制CodeList objs = new List();

EmployeeRecSimple rec1 = new EmployeeRecSimple();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

EmployeeRecSimple rec2 = new EmployeeRecSimple();
rec2.Id = 2;
rec2.Name = “Jason”;
objs.Add(rec2);

using (var parser = new ChoJSONWriter(“emp.json”, config))
{
parser.Write(objs);
}

上面的示例代码展示了如何使用JSON配置对象从POCO对象列表生成JSON文件。在JSONWriter构造函数中,我们指定了JSON配置配置对象。

3.4。首先使用声明式配置编写代码

这是定义POCO实体类和声明性附加JSON配置参数的组合方法。id是required列,name是可选值列,默认值为“XXXX”。如果名称不存在,它将采用默认值。

清单3.4.1定义POCO对象

隐藏,复制Codepublic class EmployeeRec
{
[ChoJSONRecordField]
[Required]
public int? Id
{
get;
set;
}

[ChoJSONRecordField]
[DefaultValue("XXXX")]
public string Name
{
    get;
    set;
}

public override string ToString()
{
    return "{0}. {1}.".FormatString(Id, Name);
}

}

上面的代码演示了如何用生成JSON文件所需的nessasary属性定义POCO对象。首先使用ChoJSONRecordFieldAttribute为每个记录字段定义属性,以符合JSON记录映射。Id是必需的属性。我们用要求的贡品装饰了它。Name使用DefaultValueAttribute为其提供默认值。这意味着如果对象中没有设置名称值,JSONWriter就会将默认值‘XXXX’发送给文件。

它非常简单,可以立即保存JSON数据。

清单3.4.2使用POCO对象保存JSON文件

隐藏,复制CodeList objs = new List();

EmployeeRec rec1 = new EmployeeRec();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

EmployeeRec rec2 = new EmployeeRec();
rec2.Id = 2;
rec2.Name = “Jason”;
objs.Add(rec2);

using (var parser = new ChoJSONWriter(“emp.json”))
{
parser.Write(objs);
}

我们首先创建一个chojsonwriterobject的新实例。这是所有。所有从对象生成JSON数据的繁重工作都是由编写器在幕后完成的。

默认情况下,JSONWriter 在保存JSON文件时发现并使用默认配置参数。这些可以根据您的需要进行包装。下面几节将详细介绍每个配置属性。

  1. 写所有的记录

设置与JSON文件结构匹配的POCO对象,构造对象列表并将其传递给JSONWriter的Write方法,就像这样简单。这将在一次调用中将整个对象列表写入JSON文件。

清单4.1写入JSON文件

隐藏,复制CodeList objs = new List();
//Construct and attach objects to this list

using (var parser = new ChoJSONWriter(“emp.json”))
{
parser.Write(objs);
}

或者:

清单4.2编写器到JSON文件流

隐藏,复制CodeList objs = new List();
//Construct and attach objects to this list

using (var tx = File.OpenWrite(“emp.json”))
{
using (var parser = new ChoJSONWriter(tx))
{
parser.Write(objs);
}
}

这个模型使您的代码优雅、干净、易于阅读和维护。

  1. Write 手动记录

当POCO对象以一种断开连接的方式构造时,这是一种将每条记录写入JSON文件的替代方法。

清单5.1编写JSON文件

隐藏,复制Codevar writer = new ChoJSONWriter(“emp.json”);

EmployeeRec rec1 = new EmployeeRec();
rec1.Id = 1;
rec1.Name = “Mark”;

writer.Write(rec1);

EmployeeRec rec2 = new EmployeeRec();
rec1.Id = 2;
rec1.Name = “Jason”;

writer.Write(rec2);

  1. 自定义JSON记录

使用ChoJSONRecordObjectAttribute,您可以声明地定制POCO实体对象。

清单6.1为每条记录定制POCO对象

隐藏,复制Code[ChoJSONRecordObject]
public class EmployeeRec
{
[ChoJSONRecordField]
public int Id { get; set; }
[ChoJSONRecordField]
[Required]
[DefaultValue(“ZZZ”)]
public string Name { get; set; }
}

下面是对文件执行JSON加载操作定制的可用属性。

文化——用于读写的文化信息。ColumnCountStrict——此标志指示如果JSON字段配置与数据对象成员不匹配,是否应抛出异常。特殊的空值文本期望被处理为空值从JSON文件在记录级别。ErrorMode——此标志指示如果写入操作和预期字段写入失败时是否应抛出异常。这可以被每个属性覆盖。可能的值是:

IgnoreAndContinue—忽略错误,记录将被跳过并继续next。ReportAndContinue -向POCO实体报告错误,如果它是IChoNotifyRecordWrite类型throwandstop -抛出错误并停止执行
IgnoreFieldValueMode - N / A。ObjectValidationMode——一个让读者知道记录对象执行的验证类型的标志。可能的值是:

Off -没有执行对象验证。(默认)memberlevel——在将每个JSON属性写入文件之前执行验证。ObjectLevel —在将所有POCO属性写入文件之前执行验证。

  1. 自定义JSON字段

对于每个JSON列,您可以使用ChoJSONRecordFieldAttribute在POCO实体属性中指定映射。

清单6.1为JSON列定制POCO对象

隐藏,复制Codepublic class EmployeeRec
{
[ChoJSONRecordField]
public int Id { get; set; }
[ChoJSONRecordField]
[Required]
[DefaultValue(“ZZZ”)]
public string Name { get; set; }
}

这是可用的会员为每个属性添加一些自定义:

FieldName—JSON字段名。如果没有指定,POCO对象属性名将被用作字段名。大小——JSON列值的大小。NullValue —特殊的空值文本期望在字段级别上作为JSON文件中的空值处理。ErrorMode——这个标志指示如果写入和预期字段转换和写入失败,是否应该抛出异常。可能的值是:

IgnoreAndContinue—忽略错误并继续加载记录的其他属性。ReportAndContinue——如果POCO实体是IChoRecord类型,则向它报告错误。Throw and stop—抛出错误并停止执行。

8.1。DefaultValue

任何POCO实体属性都可以使用System.ComponentModel.DefaultValueAttribute用默认值指定。当JSON值为null时(通过IgnoreFieldValueMode控制),它是用于写入的值。

8.2。ChoFallbackValue

可以使用choet . chofallbackvalueattribute用回退值指定任何POCO实体属性。它是当属性无法写入JSON时使用的值。回退值仅在ErrorMode为IgnoreAndContinue或ReportAndContinue时设置。

8.3。类型转换器

大多数基本类型会自动转换为string/text并保存为JSON文件。如果JSON字段的值不能自动转换为文本值,可以指定一个自定义/内置的. net转换器来将值转换为文本。这些可以是IValueConverter、IChoValueConverteror TypeConverter转换器。

有两种方法可以为每个字段指定转换器

声明式方法配置方法

8.3.1。声明式方法

此模型仅适用于poco实体对象。如果您有POCO 类,您可以为每个属性指定转换器,以对它们执行必要的转换。下面的示例展示了实现方法。

清单8.3.1.1指定类型转换器

隐藏,复制Codepublic class EmployeeRec
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
public int Id { get; set; }
[ChoJSONRecordField]
[Required]
[DefaultValue(“ZZZ”)]
public string Name { get; set; }
}

清单8.3.1.2 IntConverter实现

隐藏,复制Codepublic class IntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    int intValue = (int)value;
    return intValue.ToString("D4");
}

}

在上面的例子中,我们定义了自定义的IntConverter类。并演示了如何用前导零格式化’Id’ JSON属性。

8.3.2。的配置方法

此模型既适用于动态对象,也适用于poco&entity对象。这样就可以在运行时将转换器附加到每个属性上。这优先于POCO类上的声明式转换器。

清单8.3.2.1 指定TypeConverters

隐藏,复制CodeChoJSONRecordConfiguration config = new ChoJSONRecordConfiguration();

ChoJSONRecordFieldConfiguration idConfig = new ChoJSONRecordFieldConfiguration(“Id”);
idConfig.AddConverter(new IntConverter());
config.JSONRecordFieldConfigurations.Add(idConfig);

config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Name”));
config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Name1”));

在上面,我们使用chojsonrecordfieldconfigurationobject中的AddConverter助手方法构造并将IntConverter附加到’Id’字段。

同样,如果您想从其中删除任何转换器,您可以在ChoJSONRecordFieldConfiguration对象上使用RemoveConverter。

8.3.3。自定义值转换器方法

这种方法允许使用Fluenrt API将值转换器附加到每个JSON成员。这是处理任何奇怪的转换过程并避免创建值转换器类的快速方法。

清单8.3.3.1 少类

隐藏,复制Codepublic class EmployeeRec
{
[ChoJSONRecordField]
public int Id { get; set; }
[ChoJSONRecordField(2, FieldName =“Name”, QuoteField = true)]
[Required]
[DefaultValue(“ZZZ”)]
public string Name { get; set; }
}

使用fluent API,下面的示例将展示如何将值转换器附加到Id列

清单8.3.3.2附加值转换器

隐藏,复制Codeusing (var dr = new ChoJSONWriter(@“Test.json”)
.WithField(c => c.Id, valueConverter: (v) => ((int)value).ToString(“C3”, CultureInfo.CurrentCulture))
)
{
Console.WriteLine(rec);
}

8.4。验证

JSONWriter利用both System.ComponentModel。DataAnnotations和Validation Block 验证属性为POCO实体的各个字段指定验证规则。参考MSDN站点获取可用的DataAnnotations验证属性列表。

清单8.4.1在POCO实体中使用验证属性

隐藏,复制Code[ChoJSONRecordObject]
public partial class EmployeeRec
{
[ChoJSONRecordField(1, FieldName = “id”)]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, int.MaxValue, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[Required]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

}

在上面的例子中,使用range验证属性来验证属性。需要验证属性来命名属性。配置时,JSONWriter在将数据保存到文件之前对它们执行验证。ObjectValidationMode设置为ChoObjectValidationMode。MemberLevel或ChoObjectValidationMode.ObjectLevel。

在某些情况下,您可能想在POCO实体类中控制和执行手动的自我验证。这可以通过从IChoValidatable接口继承POCO对象来实现。

清单8.4.2对POCO实体进行手工验证

隐藏,复制Code[ChoJSONRecordObject]
public partial class EmployeeRec : IChoValidatable
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, int.MaxValue, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[Required]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool TryValidate(object target, ICollection<ValidationResult> validationResults)
{
    return true;
}

public bool TryValidateFor(object target, string memberName, ICollection<ValidationResult> validationResults)
{
    return true;
}

}

上面的示例展示了如何在POCO对象中实现自定义验证。

IChoValidatable接口公开了下面的方法

TryValidate—验证整个对象,如果所有验证都通过,则返回true。否则返回假。TryValidateFor -验证对象的特定属性,如果所有验证都通过,则返回true。否则返回假。

8.5。ChoIgnoreMember

如果您想在optout模式下忽略JSON解析中的POCO类成员,请使用ChoIgnoreMemberAttribute对其进行修饰。下面的示例显示标题成员在JSON加载过程中被忽略。

清单8.5.1忽略一个成员

Hide ,复制代码

隐藏,复制Codepublic class EmployeeRec
{
public int Id { get; set; }
public string Name { get; set; }
[ChoIgnoreMember]
public string Title { get; set; }
}

8.6。StringLength

在选择在输出模式下,您可以通过使用System.ComponentModel.DataAnnotations.StringLengthAttribute. 来指定JSON列的大小。

清单8.6.1指定JSON成员的大小

Hide ,复制代码

隐藏,复制Codepublic class EmployeeRec
{
public int Id { get; set; }
[StringLength(25)]
public string Name { get; set; }
[ChoIgnoreMember]
public string Title { get; set; }
}

8.6。显示

在OptOut模式下,您可以使用System.ComponentModel.DataAnnotations.DisplayAttribute. 指定JSON列映射到成员的名称。

清单8.6.1指定JSON列的名称

Hide ,复制代码

隐藏,复制Codepublic class EmployeeRec
{
public int Id { get; set; }
[Display(Name=“FullName”)]
[StringLength(25)]
public string Name { get; set; }
[ChoIgnoreMember]
public string Title { get; set; }
}

8.7。DisplayName

在OptOut模式下,您可以指定JSON列的名称映射到成员使用System.ComponentModel.DataAnnotations.DisplayNameAttribute.

清单8.7.1指定JSON列的名称

隐藏,复制Codepublic class EmployeeRec
{
public int Id { get; set; }
[Display(Name=“FullName”)]
[StringLength(25)]
public string Name { get; set; }
[ChoIgnoreMember]
public string Title { get; set; }
}

  1. 回调机制

JSONWriter提供了开箱即用的行业标准JSON数据文件生成,以处理大多数需求。如果生成过程不处理您的任何需求,您可以使用JSONWriter 提供的回调机制来处理这种情况。为了参与回调机制,您可以使用以下任一种模型

使用JSONWriter通过IChoWriter接口公开的事件处理程序。通过IChoNotifyRecordWrite / IChoNotifyRecordFieldWrite 接口继承DataAnnotation的元类型对象。

为了参与回调机制,POCO实体对象或DataAnnotation的元类型对象都必须被ichonotifyrecordwriteinterface继承。

提示:从这些接口方法中引发的任何异常都将被忽略。

ichorecorder公开了以下方法:

BeginWrite——调用JSON文件编写endwrite的开始——结束时调用JSON文件写beforerecordwrite ——提高JSON记录写afterrecordwrite - JSON记录写recordwriteerror后提出提高当JSON记录错误而写作beforerecordfieldwrite - JSON列值写afterrecordfieldwrite之前提出提高JSON之后列值写recordfieldwriteerror——当JSON列值的错误while 写作

IChoNotifyRecordWrite 暴露以下方法:

BeforeRecordWrite -在JSON记录写入之前提出,afterrecordwritewritewrite -在JSON记录写入错误时提出

IChoNotifyFileWrite 暴露以下方法:

BeginWrite -调用在JSON文件的开始写结束

IChoNotifyRecordFieldWrite 暴露以下方法:

BeforeRecordFieldWrite -在JSON列值写入后上升recordfieldwriteerror -当JSON列值写入错误时上升

IChoNotifyFileHeaderArrange 暴露以下方法:

FileHeaderArrange —在JSON文件头被写入文件之前引发,一个重新排列JSON列的机会

IChoNotifyFileHeaderWrite 暴露以下方法:

FileHeaderWrite -在JSON文件头被写入文件之前引发,一个定制头的机会。

10.1使用JSONWriter事件

这是订阅回调事件和处理解析JSON文件时奇怪情况的更直接和最简单的方法。缺点是代码不能像使用POCO记录对象实现ichonotifyrecor惧那样可重用。

下面的示例展示了如何使用beforerecordloadcallback方法跳过含有’%'字符的语句行。

清单10.1.1使用JSONWriter回调事件

隐藏,复制Codestatic void IgnoreLineTest()
{
using (var parser = new ChoJSONWriter(“emp.json”))
{
parser.BeforeRecordWrite += (o, e) =>
{
if (e.Source != null)
{
e.Skip = ((JObject)e.Source).Contains(“name1”);
}
};

    parser.Write(rec);
}

}

同样,您也可以在JSONWriter中使用其他回调方法。

10.2实现IChoNotifyRecordWrite接口

下面的示例展示了如何实现ichonotifyrecordwriteinterface来指导POCO类。

清单10.2.1直接POCO回调机制实现

隐藏,收缩,复制Code[ChoJSONRecordObject]
public partial class EmployeeRec : IChoNotifyrRecordWrite
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, int.MaxValue, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[Required]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool AfterRecordWrite(object target, int index, object source)
{
    throw new NotImplementedException();
}

public bool BeforeRecordWrite(object target, int index, ref object source)
{
    throw new NotImplementedException();
}

public bool RecordWriteError(object target, int index, object source, Exception ex)
{
    throw new NotImplementedException();
}

}

下面的示例展示了如何通过在POCO类上使用MetadataTypeAttribute将元数据类附加到它。

清单10.2.2基于元类型的回调机制实现

隐藏,收缩,复制Code[ChoJSONRecordObject]
public class EmployeeRecMeta : IChoNotifyRecordWrite
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, int.MaxValue, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[Required]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool AfterRecordWrite(object target, int index, object source)
{
    throw new NotImplementedException();
}

public bool BeforeRecordWrite(object target, int index, ref object source)
{
    throw new NotImplementedException();
}

public bool RecordWriteError(object target, int index, object source, Exception ex)
{
    throw new NotImplementedException();
}

}

[MetadataType(typeof(EmployeeRecMeta))]
public partial class EmployeeRec
{
public int Id { get; set; }
public string Name { get; set; }
}

下面的示例展示了如何通过在其上使用ChoMetadataRefTypeAttribute为密封的或第三方POCO类附加元数据类。

清单10.2.2基于元类型的回调机制实现

隐藏,收缩,复制Code[ChoMetadataRefType(typeof(EmployeeRec))]
[ChoJSONRecordObject]
public class EmployeeRecMeta : IChoNotifyRecordWrite
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, int.MaxValue, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[Required]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool AfterRecordWrite(object target, int index, object source)
{
    throw new NotImplementedException();
}

public bool BeforeRecordWrite(object target, int index, ref object source)
{
    throw new NotImplementedException();
}

public bool RecordWriteError(object target, int index, object source, Exception ex)
{
    throw new NotImplementedException();
}

}

public partial class EmployeeRec
{
public int Id { get; set; }
public string Name { get; set; }
}

10.1 BeginWrite

这个回调在JSON文件写入开始时调用一次。source是JSON文件流对象。在这里,您有机会检查流,返回true以继续JSON生成。用谎言来阻止一代人。

Listing 大家BeginWrite 调样品

隐藏之处;复制Codepublic bool BeginWrite(object source)
{
StreamReader sr = source as StreamReader;
return true;
}

10.2 EndWrite

这个回调在JSON文件生成结束时调用一次。source是JSON文件流对象。在这里,你有机会检查流,做任何张贴步骤,以执行的流。

Listing 10.2.1 EndWrite 调样品

隐藏,复制Codepublic void EndWrite(object source)
{
StreamReader sr = source as StreamReader;
}

10.3 BeforeRecordWrite

这个回调在每个POCO记录对象被写入JSON文件之前被调用。目标是POCO记录对象的实例。index是文件中的行索引。source是JSON记录行。在这里,您有机会检查POCO对象,并在需要时生成JSON记录行。

提示:如果您想要跳过写入记录,请将源设置为null。

返回true继续加载进程,否则返回false停止进程。

Listing 10.3.1 BeforeRecordWrite 调样品

隐藏,复制Codepublic bool BeforeRecordWrite(object target, int index, ref object source)
{
return true;
}

10.4 AfterRecordWrite

这个回调是在每个POCO记录对象被写入JSON文件之后调用的。target是POCO记录对象的实例。index是文件中的行索引。source是JSON记录行。在这里,你有机会用记录线做任何后步操作。

返回true继续加载进程,否则返回false停止进程。

清单10.4.1 AfterRecordWrite回调示例

隐藏,复制Codepublic bool AfterRecordWrite(object target, int index, object source)
{
return true;
}

10.5 RecordWriteError

如果在写POCO记录对象时遇到错误,这个回调函数就会被调用。target是POCO记录对象的实例。index是文件中的行索引。source是JSON记录行。ex是异常对象。在这里,你有机会处理异常。此方法仅在配置时调用。ErrorMode ReportAndContinue。

返回true继续加载进程,否则返回false停止进程。

清单10.5.1 RecordWriteError回调示例

隐藏,复制Codepublic bool RecordLoadError(object target, int index, object source, Exception ex)
{
return true;
}

10.6 BeforeRecordFieldWrite

这个回调在每个JSON记录列被写入JSON文件之前被调用。target是POCO记录对象的实例。index是文件中的行索引,propName 是JSON记录的属性名。value 是JSON列的值。在这里,你有机会检查JSON记录属性值和执行任何自定义验证等。

返回true继续加载进程,否则返回false停止进程。

清单10.6.1 BeforeRecordFieldWrite回调示例

隐藏,复制Codepublic bool BeforeRecordFieldWrite(object target, int index, string propName, ref object value)
{
return true;
}

10.7 AfterRecordFieldWrite

这个回调在每个JSON 记录列值被写入JSON文件之后调用。target是POCO记录对象的实例。index是文件中的行索引,propName 是JSON记录的属性名。value是JSON列的值。任何post字段操作都可以在这里执行,比如计算其他属性、验证等。

返回true继续加载进程,否则返回false停止进程。

清单10.7.1 AfterRecordFieldWrite回调示例

隐藏,复制Codepublic bool AfterRecordFieldWrite(object target, int index, string propName, object value)
{
return true;
}

10.8 RecordWriteFieldError

当写入json记录列值时遇到错误时调用这个回调函数。target是POCO记录对象的实例。index是文件中的行index propName 是JSON记录属性名。value是JSON列的值。ex是异常对象。在这里,你有机会处理异常。该方法仅在JSONWriter执行以下两组步骤之后调用

JSONWriter查找每个JSON属性的回退值。如果有的话,它试着用它来写作。如果FallbackValue值不存在,则配置。错误模式被指定为ReportAndContinue。,此回调将被执行。

返回true继续加载进程,否则返回false停止进程。

清单10.8.1 RecordFieldWriteError回调示例

隐藏,复制Codepublic bool RecordFieldWriteError(object target, int index, string propName, object value, Exception ex)
{
return true;
}

  1. 定制

JSONWriter自动从POCO实体检测和加载配置设置。在运行时,您可以在生成JSON之前定制和调整这些参数。JSONWriter公开配置属性,它属于ChoJSONRecordConfiguration对象。使用此属性,您可以执行定制。

清单11.1在运行时定制JSONWriter

隐藏,复制Codeclass Program
{
static void Main(string[] args)
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

    dynamic rec2 = new ExpandoObject();
    rec2.Id = 2;
    rec2.Name = "Jason";
    objs.Add(rec2);

    using (var parser = new ChoJSONWriter("emp.json"))
    {
        parser.Configuration.ColumnCountStrict = true;
        parser.Write(objs);
    }
}

}

  1. 使用动态对象

到目前为止,本文解释了如何使用JSONWriter和POCO对象。JSONWriter还支持生成没有POCO实体对象的JSON文件,它利用了。net动态特性。下面的示例展示了如何使用动态对象生成JSON流。JSON模式是从第一个对象确定的。如果在动态对象成员值中发现不匹配,则会引发错误并停止生成过程。

下面的例子可以说明:

清单12.1从动态对象生成JSON文件

嗨德,复制Codeclass Program
{
static void Main(string[] args)
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 1;
rec1.Name = “Mark”;
objs.Add(rec1);

    dynamic rec2 = new ExpandoObject();
    rec2.Id = 2;
    rec2.Name = "Jason";
    objs.Add(rec2);

    using (var parser = new ChoJSONWriter("emp.json"))
    {
        parser.Configuration.ColumnCountStrict = true;
        parser.Write(objs);
    }
}

}

  1. 异常

JSONWriter在不同的情况下抛出不同类型的异常。

JSON文件坏了,解析器无法恢复。ChoRecordConfigurationException -指定任何无效配置设置时,将引发此异常。ChoMissingRecordFieldException—JSON列缺少一个属性,将引发此异常。

  1. 使用MetadataType注释

Cinchoo ETL与数据注释的元类型模型一起工作得更好。这是将元数据类附加到数据模型类的方法。在这个关联类中,您提供了数据模型中没有的附加元数据信息。It角色是在不修改类的情况下向类添加属性。您可以将这个带有单个参数的属性添加到具有所有属性的类中。当POCO类由自动工具自动生成(由实体框架、MVC等)时,这是很有用的。这就是为什么第二节课起作用了。您可以在不修改生成的文件的情况下添加新内容。通过将关注点分离到多个类,这也促进了模块化。

更多信息,请在MSDN搜索。

清单15.1元类型注释使用示例

隐藏,收缩,复制Code[MetadataType(typeof(EmployeeRecMeta))]
public class EmployeeRec
{
public int Id { get; set; }
public string Name { get; set; }
}

[ChoJSONRecordObject]
public class EmployeeRecMeta : IChoNotifyRecordWrite, IChoValidatable
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, 1, ErrorMessage = “Id must be > 0.”)]
[ChoFallbackValue(1)]
public int Id { get; set; }

[ChoJSONRecordField]
[StringLength(1)]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool AfterRecordWrite(object target, int index, object source)
{
    throw new NotImplementedException();
}

public bool BeforeRecordWrite(object target, int index, ref object source)
{
    throw new NotImplementedException();
}

public bool RecordWriteError(object target, int index, object source, Exception ex)
{
    throw new NotImplementedException();
}

public bool TryValidate(object target, ICollection<ValidationResult> validationResults)
{
    return true;
}

public bool TryValidateFor(object target, string memberName, ICollection<ValidationResult> validationResults)
{
    return true;
}

}

在上面,雇员建立是数据类。只包含特定于域的属性和操作。将它标记为非常简单的类。

我们将验证、回调机制、配置等分离为元数据类型类、EmployeeRecMeta。

  1. 配置选择

如果POCO entity类是自动生成的类或通过库公开的类,或者它是密封的类,那么它会限制您以声明的方式将JSON模式定义附加到它。在这种情况下,您可以选择下面的选项之一来指定JSON布局配置

手动配置自动映射配置附加元类型类

我将向您展示如何在每种方法上配置下面的POCO实体类

清单16.1密封的poco实体类

隐藏,复制Codepublic sealed class EmployeeRec
{
public int Id { get; set; }
public string Name { get; set; }
}

16.1手动配置

从头定义一个全新的配置对象,并将所有必要的JSON字段添加到ChoJSONConfiguration中。JSONRecordFieldConfigurations集合属性。此选项为您控制JSON解析的配置提供了更大的灵活性。但缺点是,如果JSON文件布局很大,就有可能出错,而且很难管理它们,

清单16.1.1 手动配置

隐藏,复制CodeChoJSONRecordConfiguration config = new ChoJSONRecordConfiguration();
config.ThrowAndStopOnMissingField = true;
config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Id”));
config.JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(“Name”));

16.2,汽车Map 配置

这是另一种自动映射poco&entity类的JSON列的方法,而且这种方法的错误少得多。

首先为EmployeeRec POCO实体类定义一个架构类,如下所示

清单16.2.1自动映射类

隐藏,复制Codepublic class EmployeeRecMap
{
[ChoJSONRecordField]
public int Id { get; set; }

[ChoJSONRecordField]
public string Name { get; set; } 

}

然后您可以使用ChoJSONRecordConfiguration.MapRecordFields 方法来使用它自动映射JSON列

清单16.2.2使用自动映射配置

隐藏,复制CodeChoJSONRecordConfiguration config = new ChoJSONRecordConfiguration();
config.MapRecordFields();

EmployeeRec rec1 = new EmployeeRec();
rec1.Id = 2;
rec1.Name = “Jason”;

foreach (var e in new ChoJSONWriter(“emp.json”, config))
w.Write(rec1);

16.3,附加MetadataType类

这是为POCO实体对象附加元类型类的另一种方法。前面的方法只关心JSON列的自动映射。其他配置属性,如属性转换器、解析器参数、默认/回退值等,不被考虑。

这个模型通过定义元类型类和声明式地指定JSON配置参数来解释所有的事情。当您的POCO实体是密封的而不是部分类时,这是有用的。同时,它也是配置POCO实体的JSON解析的一种有效且较少出错的方法。

清单16.3.1定义元类型类

隐藏,收缩,复制Code[ChoJSONRecordObject]
public class EmployeeRecMeta : IChoNotifyRecordWrite, IChoValidatable
{
[ChoJSONRecordField]
[ChoTypeConverter(typeof(IntConverter))]
[Range(1, 1, ErrorMessage = “Id must be > 0.”)]
public int Id { get; set; }

[ChoJSONRecordField]
[StringLength(1)]
[DefaultValue("ZZZ")]
[ChoFallbackValue("XXX")]
public string Name { get; set; }

public bool AfterRecordWrite(object target, int index, object source)
{
    throw new NotImplementedException();
}

public bool BeforeRecordWrite(object target, int index, ref object source)
{
    throw new NotImplementedException();
}

public bool RecordWriteError(object target, int index, object source, Exception ex)
{
    throw new NotImplementedException();
}

public bool TryValidate(object target, ICollection<ValidationResult> validationResults)
{
    return true;
}

public bool TryValidateFor(object target, string memberName, ICollection<ValidationResult> validationResults)
{
    return true;
}

}

清单16.3.2 Attaching MetadataType类

隐藏,复制Code//Attach metadata
ChoMetadataObjectCache.Default.Attach(new EmployeeRecMeta());

using (var tx = File.OpenWrite(“emp.json”))
{
using (var parser = new ChoJSONWriter(tx))
{
parser.Write(objs);
}
}

  1. ToTextAll辅助方法

这是一个漂亮的助手方法,用于从对象列表生成JSON格式的输出。它帮助您运行和使用不同的选项,以便在测试环境中快速查看JSON输出。

隐藏,复制Codestatic void ToTextTest()
{
List objs = new List();
EmployeeRec rec1 = new EmployeeRec();
rec1.Id = 10;
rec1.Name = “Mark”;
objs.Add(rec1);

EmployeeRec rec2 = new EmployeeRec();
rec2.Id = 200;
rec2.Name = "Lou";
objs.Add(rec2);

Console.WriteLine(ChoJSONWriter.ToTextAll(objs));

}

17一个。ToText 辅助方法

这是一个漂亮的助手方法,用于从对象生成JSON格式的输出。它帮助您运行和使用不同的选项,以便在测试环境中快速查看JSON输出。

隐藏,复制Codestatic void ToTextTest()
{
EmployeeRec rec1 = new EmployeeRec();
rec1.Id = 10;
rec1.Name = “Mark”;
objs.Add(rec1);

Console.WriteLine(ChoJSONWriter.ToText(rec1));

}

  1. 写作DataReader 辅助方法

这个助手方法允许您从ADO创建JSON文件/流。净DataReader。

隐藏,复制Codestatic void WriteDataReaderTest()
{
SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand(“SELECT * FROM Members”, conn);
IDataReader dr = cmd.ExecuteReader();

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json))
{
    parser.Write(dr);
}
Console.WriteLine(json.ToString());

}

  1. 编写DataTable辅助方法

这个助手方法允许您从ADO创建JSON文件/流。净数据表。

隐藏,复制Codestatic void WriteDataTableTest()
{
string connString = @“Data Source=(localdb)\v11.0;Initial Catalog=TestDb;Integrated Security=True”;

SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Members", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(dt);
}

Console.WriteLine(json.ToString());

}

20.高级的主题

重写转换器的格式规格

Cinchoo ETL自动解析并将每个JSON列值无缝地转换为对应的JSON列的底层数据类型。大多数基本的。net类型都是自动处理的完成任何需要的设置。

这是通过ETL系统中的两个关键设置实现的

ChoJSONRecordConfiguration。CultureInfo——表示关于特定区域性的信息,包括区域性的名称、编写系统和使用的日历,以及对特定区域性对象的访问,这些对象为常见操作提供信息,比如格式化日期和对字符串排序。默认设置是“en - us”。ChoTypeConverterFormatSpec -它是一个全局格式说明符类,包含所有内在的。net类型格式规范。

在本节中,我将讨论根据解析需要为每个. net内在数据类型更改默认格式规范。

ChoTypeConverterFormatSpec是单例类,实例通过“instance”静态成员公开。它是线程本地的,这意味着在每个线程上将保留单独的实例副本。

除了布尔型、枚举型、数据时间型之外,每个内在类型都有两组格式规范成员,一组用于加载,另一组用于写入值。这些类型只有一个用于加载和写入操作的成员。

通过ChoTypeConverterFormatSpec指定每个内部数据类型格式规范将影响整个系统。ie。setting ChoTypeConverterFormatSpec。IntNumberStyle = NumberStyles。allow圆括号,将影响JSON对象的所有整数成员以允许圆括号。如果您想要重写此行为并控制特定的JSON数据成员来处理它自己的惟一解析JSON值的全局系统范围设置,可以通过在JSON字段成员级别指定TypeConverter来完成。更多信息请参阅13.4节。

Listing 20.1.1 ChoTypeConverterFormatSpec 成员

隐藏,收缩,复制Codepublic class ChoTypeConverterFormatSpec
{
public static readonly ThreadLocal Instance = new ThreadLocal(() => new ChoTypeConverterFormatSpec());

public string DateTimeFormat { get; set; }
public ChoBooleanFormatSpec BooleanFormat { get; set; }
public ChoEnumFormatSpec EnumFormat { get; set; }

public NumberStyles? CurrencyNumberStyle { get; set; }
public string CurrencyFormat { get; set; }

public NumberStyles? BigIntegerNumberStyle { get; set; }
public string BigIntegerFormat { get; set; }

public NumberStyles? ByteNumberStyle { get; set; }
public string ByteFormat { get; set; }

public NumberStyles? SByteNumberStyle { get; set; }
public string SByteFormat { get; set; }

public NumberStyles? DecimalNumberStyle { get; set; }
public string DecimalFormat { get; set; }

public NumberStyles? DoubleNumberStyle { get; set; }
public string DoubleFormat { get; set; }

public NumberStyles? FloatNumberStyle { get; set; }
public string FloatFormat { get; set; }

public string IntFormat { get; set; }
public NumberStyles? IntNumberStyle { get; set; }

public string UIntFormat { get; set; }
public NumberStyles? UIntNumberStyle { get; set; }

public NumberStyles? LongNumberStyle { get; set; }
public string LongFormat { get; set; }

public NumberStyles? ULongNumberStyle { get; set; }
public string ULongFormat { get; set; }

public NumberStyles? ShortNumberStyle { get; set; }
public string ShortFormat { get; set; }

public NumberStyles? UShortNumberStyle { get; set; }
public string UShortFormat { get; set; }

}

下面的示例展示了如何使用JSONWriter加载具有“se-SE”(瑞典)区域性特定数据的JSON数据流。此外,输入提要带有包含括号的“EmployeeNo”值。为了使加载成功,我们必须设置ChoTypeConverterFormatSpec。IntNumberStyle NumberStyles.AllowParenthesis。

在代码中使用ChoTypeConverterFormatSpec

隐藏,收缩,复制Codestatic void FormatSpecDynamicTest()
{
ChoTypeConverterFormatSpec.Instance.DateTimeFormat = “d”;
ChoTypeConverterFormatSpec.Instance.BooleanFormat = ChoBooleanFormatSpec.YOrN;

List<ExpandoObject> objs = new List<ExpandoObject>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = "Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

20.2,货币支持

Cinchoo ETL提供ChoCurrency对象来读写JSON文件中的货币值。ChoCurrency是一个包装类,用于保存十进制类型的货币值,并支持在JSON加载期间以文本格式序列化它们。

列表20.2.1在动态模型中使用货币成员

隐藏,收缩,复制Codestatic void CurrencyDynamicTest()
{
ChoTypeConverterFormatSpec.Instance.CurrencyFormat = “C2”;

List<ExpandoObject> objs = new List<ExpandoObject>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = "Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

上面的示例展示了如何使用动态对象模型输出货币值。由于货币输出将具有千个逗号分隔符,这将无法生成JSON文件。为了克服这个问题,我们指定写入器引用所有字段。

PS:货币值的格式是JSONWriter通过ChoRecordConfiguration计算出来的。文化和ChoTypeConverterFormatSpec.CurrencyFormat。

下面的示例展示了如何在POCO实体类中使用ChoCurrency JSON字段。

在POCO模型中使用货币成员

隐藏,收缩,复制Codepublic class EmployeeRecWithCurrency
{
public int Id { get; set; }
public string Name { get; set; }
public ChoCurrency Salary { get; set; }
}

static void CurrencyPOCOTest()
{
List objs = new List();
EmployeeRecWithCurrency rec1 = new EmployeeRecWithCurrency();
rec1.Id = 10;
rec1.Name = “Mark”;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

EmployeeRecWithCurrency rec2 = new EmployeeRecWithCurrency();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter<EmployeeRecWithCurrency>(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

20.3, Enum 支持

Cinchoo ETL隐式处理JSON文件中枚举列值的解析/写入。如果您想精确地控制这些值的解析,您可以通过ChoTypeConverterFormatSpec.EnumFormat全局指定它们。缺省为ChoEnumFormatSpec.Value

供您参考,更改此值将影响整个系统。

有3种可能的值可以使用

ChoEnumFormatSpec。Value—枚举值用于解析。ChoEnumFormatSpec。Name—用于解析的枚举键名。ChoEnumFormatSpec。Description——如果每个枚举键都用DescriptionAttribute修饰,那么它的值将用于解析。

清单20.3.1在解析期间指定枚举格式规范

隐藏,收缩,复制Codepublic enum EmployeeType
{
[Description(“Full Time Employee”)]
Permanent = 0,
[Description(“Temporary Employee”)]
Temporary = 1,
[Description(“Contract Employee”)]
Contract = 2
}

static void EnumTest()
{
ChoTypeConverterFormatSpec.Instance.EnumFormat = ChoEnumFormatSpec.Description;

List<ExpandoObject> objs = new List<ExpandoObject>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = "Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
rec1.Status = EmployeeType.Permanent;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
rec2.Status = EmployeeType.Contract;
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

20.4,布尔的支持

Cinchoo ETL隐式处理JSON文件中布尔JSON列值的解析/写入。如果你想更好地控制解析这些值,你可以通过ChoTypeConverterFormatSpec.BooleanFormat全局指定它们,默认值是ChoBooleanFormatSpec.ZeroOrOne

供您参考,更改此值将影响整个系统。

有4个可能的值可以使用

ChoBooleanFormatSpec。0或1 - ‘0’表示false。’ 1 ',真的。ChoBooleanFormatSpec。YOrN - 'Y’表示真,'N’表示假。ChoBooleanFormatSpec。真或假——真用True表示,假用False表示。ChoBooleanFormatSpec。YesOrNo——用Yes表示正确,用No表示错误。

清单20.4.1在解析期间指定布尔格式规范

隐藏,收缩,复制Codestatic void BoolTest()
{
ChoTypeConverterFormatSpec.Instance.BooleanFormat = ChoBooleanFormatSpec.YOrN;

List<ExpandoObject> objs = new List<ExpandoObject>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = "Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
rec1.Status = EmployeeType.Permanent;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
rec2.Status = EmployeeType.Contract;
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

20.5,DateTime支持

Cinchoo ETL隐式处理使用系统区域性或自定义集区域性从JSON文件解析/写入datetime JSON列值。如果您想精确地控制这些值的解析,可以将它们指定为gl显然,via chotypeconverterformat . datetimeformat .缺省值是’d’。

供您参考,更改此值将影响整个系统。

您可以使用任何有效的标准或自定义日期时间。NET格式规范来解析文件中的日期时间JSON值。

清单20.5.1在解析期间指定日期时间格式规范

隐藏,收缩,复制Codestatic void DateTimeDynamicTest()
{
ChoTypeConverterFormatSpec.Instance.DateTimeFormat = “MMM dd, yyyy”;

List<ExpandoObject> objs = new List<ExpandoObject>();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = "Mark";
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

上面的示例展示了如何为JSON文件生成定制的datetime值。

注意:由于日期时间值包含JSON分隔符,我们要求作者引用所有字段。

  1. 流利的API

JSONWriter通过fluent API方法公开很少使用的配置参数。这将使生成JSON文件的编程变得更快。

21.1。NullValueHandling

指定ChoJSONWriter的空值处理选项

Ignore—在编写JSON时忽略null值

默认值——在编写JSON时包含空值

21.2只格式化

指定ChoJSONWriter的格式设置选项

None -不应用任何特殊格式。这是默认值。

Intented—导致子对象缩进。

21.3, WithFields

这个API方法指定编写JSON文件时要考虑的JSON字段列表。其他字段将被丢弃。字段名不区分大小写。

隐藏,收缩,复制Codestatic void QuickDynamicTest()
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = “Mark”;
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    .WithFields("Id", "Name")
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

21.4,WithField

此API方法用于添加带有特定日期类型、引号标志和/或引号字符的JSON列。通过使用适当的数据类型指定每个JSON列,此方法在动态对象模型中很有帮助。,

隐藏,收缩,复制Codestatic void QuickDynamicTest()
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = “Mark”;
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    .WithField("Id", typeof(int))
    .WithField("Name"))
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

21.5只IgnoreFieldValueMode

为ChoJSONWriter指定忽略字段值

None - Ignore字段值被关闭。这是默认值。

DbNull值将被忽略。

Empty -空文本值将被忽略。

空格-空格文本将被忽略。

21.6,ColumnCountStrict

这个API方法用于设置JSONWriter,以便在编写JSON文件之前对列计数进行检查。

隐藏,收缩,复制Codestatic void ColumnCountTest()
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = “Mark”;
rec1.JoinedDate = new DateTime(2001, 2, 2);
rec1.IsActive = true;
rec1.Salary = new ChoCurrency(100000);
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
rec2.JoinedDate = new DateTime(1990, 10, 23);
rec2.IsActive = false;
rec2.Salary = new ChoCurrency(150000);
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    .ColumnCountStrict()
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

21.7。配置

此API方法用于配置所有未通过fluent API公开的配置参数。

隐藏,复制Codestatic void ConfigureTest()
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = “Mark”;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    .Configure(c => c.ErrorMode = ChoErrorMode.ThrowAndStop)
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

21.8。设置

此API方法用于通过fluent API设置写入器的参数/事件。

隐藏,复制Codestatic void SetupTest()
{
List objs = new List();
dynamic rec1 = new ExpandoObject();
rec1.Id = 10;
rec1.Name = “Mark”;
objs.Add(rec1);

dynamic rec2 = new ExpandoObject();
rec2.Id = 200;
rec2.Name = "Lou";
objs.Add(rec2);

StringBuilder json = new StringBuilder();
using (var parser = new ChoJSONWriter(json)
    .Setup(r => r.BeforeRecordWrite += (o, e) =>
    {
    })
    )
{
    parser.Write(objs);
}

Console.WriteLine(json.ToString());

}

  1. 常见问题解答

22.1。如何序列化一个对象?

此示例将对象序列化为JSON

隐藏,复制Codestring json = ChoJSONWriter.Serialize(new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}
});

22.2。如何序列化对象的集合?

此示例将对象集合序列化为JSON

隐藏,复制Codestring json = ChoJSONWriter.SerializeAll(new Account[] {
new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}
}
}
);

22.3。如何序列化动态对象?

这个示例将动态对象序列化为JSON

隐藏,复制Codedynamic obj = new ExpandoObject();
obj.Email = “james@example.com”;
obj.Active = true;
obj.Roles = new List()
{
“DEV”,
“OPS”
};

string json = ChoJSONWriter.Serialize(obj);

Console.WriteLine(json);

22.4。如何序列化匿名对象?

这个示例将匿名对象序列化为JSON

隐藏,复制Codestring json = ChoJSONWriter.Serialize(new
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}
});

Console.WriteLine(json);

22.5。如何序列化集合?

这个示例将集合序列化为JSON

隐藏,复制Codestring json = ChoJSONWriter.SerializeAll(new int[] { 1, 2, 3 });

Console.WriteLine(json);

22.6。如何序列化字典?

这个示例将字典序列化为JSON

隐藏,复制Codestring json = ChoJSONWriter.SerializeAll(new Dictionary<string, int>[] {
new Dictionary<string, int>()
{
[“key1”] = 1,
[“key2”] = 2
}
});

Console.WriteLine(json);

22.7。如何序列化数据表?

这个示例将datatable序列化为JSON

隐藏,复制CodeStringBuilder sb = new StringBuilder();
string connectionstring = @“Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True”;
using (var conn = new SqlConnection(connectionstring))
{
conn.Open();
var comm = new SqlCommand(“SELECT TOP 2 * FROM Customers”, conn);
SqlDataAdapter adap = new SqlDataAdapter(comm);

DataTable dt = new DataTable("Customer");
adap.Fill(dt);

using (var parser = new ChoJSONWriter(sb)
    .Configure(c => c.IgnoreRootName = true)
    )
    parser.Write(dt);

}

Console.WriteLine(sb.ToString());

22.8。如何序列化JSON到一个文件?

这个示例将JSON序列化为一个文件。

隐藏,复制Code// serialize JSON to a string and then write string to a file
File.WriteAllText(@“c:\emp.json”, ChoJSONWriter.Serialize(employee));

下面的示例展示了如何直接写入文件

隐藏,复制Codeusing (StreamWriter file = File.CreateText(@“c:\emp.json”))
{
using (var r = new ChoJSONWriter(file))
r.Write(employee);
}

22.9。如何序列化未缩进的JSON?

这个示例将一个对象序列化为JSON,没有格式化或缩进空格。

隐藏,复制Codestring json = ChoJSONWriter.SerializeAll(new int[] { 1, 2, 3 },
new ChoJSONRecordConfiguration().Configure(c => c.Formatting = Formatting.None));

Console.WriteLine(json);

22.10。如何序列化条件属性?

此示例使用条件属性从序列化中排除属性。

隐藏,收缩,复制Codepublic class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }

public bool ShouldSerializeManager()
{
    // don't serialize the Manager property if an employee is their own manager
    return (Manager != this);
}

}

public static void ConditionalPropertySerialize()
{
Employee joe = new Employee();
joe.Name = “Joe Employee”;
Employee mike = new Employee();
mike.Name = “Mike Manager”;

joe.Manager = mike;

// mike is his own manager
// ShouldSerialize will skip this property
mike.Manager = mike;

string json = ChoJSONWriter.SerializeAll(new[] { joe, mike }, new ChoJSONRecordConfiguration().Configure(c => c.UseJSONSerialization = true));

Console.WriteLine(json);

}

22.11。如何序列化的日期时间在自定义日期格式?

此示例使用DateFormatString设置来控制如何序列化datetime和datetimeoffset。

隐藏,复制CodeIList dateList = new List
{
new DateTime(2009, 12, 7, 23, 10, 0, DateTimeKind.Utc),
new DateTime(2010, 1, 1, 9, 0, 0, DateTimeKind.Utc),
new DateTime(2010, 2, 10, 10, 0, 0, DateTimeKind.Utc)
};

string json = ChoJSONWriter.SerializeAll(dateList, new JsonSerializerSettings
{
DateFormatString = “d MMMM, yyyy”,
Formatting = Formatting.Indented
});

Console.WriteLine(json);

如何从Json序列化中排除属性?

这些示例展示了如何从JSON序列化中排除属性

Sample1:使用ChoIgnoreMemberAttribute

隐藏,复制Codepublic class Account
{
[ChoIgnoreMember]
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList Roles { get; set; }
}

static void ExcludePropertyTest()
{
string json = ChoJSONWriter.Serialize(new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}

});

Console.WriteLine(json);

}

Sample2:使用JsonIgnoreAttribute

隐藏,复制Codepublic class Account
{
[JsonIgnore]
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList Roles { get; set; }
}

static void ExcludePropertyTest()
{
string json = ChoJSONWriter.Serialize(new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}

});

Console.WriteLine(json);

}

Sample3:在ChoJSONConfiguration上使用IgnoreField

隐藏,复制Codepublic class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList Roles { get; set; }
}

static void ExcludePropertyTest()
{
string json = ChoJSONWriter.Serialize(new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}

}, new ChoJSONRecordConfiguration<Account>().Ignore(f => f.Email));

Console.WriteLine(json);

}

Sample4:在ChoJSONWriter上使用IgnoreField

隐藏,收缩,复制Codepublic class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList Roles { get; set; }
}

static void ExcludePropertyTest()
{
StringBuilder json = new StringBuilder();
using (var w = new ChoJSONWriter(json)
.IgnoreField(f => f.Email)
)
{
w.Write(new Account
{
Email = “james@example.com”,
Active = true,
Roles = new List()
{
“DEV”,
“OPS”
}

    });
}

Console.WriteLine(json);

}

22.13.如何将Xml转换成JSON?

这个示例展示了如何将Xml文件转换为JSON。

隐藏,复制Codestring xml = @"<Employees xmlns="“http://company.com/schemas”">

name1
surname1


name2
surname2


name3
surname3

";

StringBuilder json = new StringBuilder();
using (var r = ChoXmlReader.LoadText(xml))
{
using (var w = new ChoJSONWriter(json))
w.Write®;
}

Console.WriteLine(json.ToString());

输出:

隐藏,复制Code[
{
“FirstName”: “name1”,
“LastName”: “surname1”
},
{
“FirstName”: “name2”,
“LastName”: “surname2”
},
{
“FirstName”: “name3”,
“LastName”: “surname3”
}
]

22.14.如何将CSV转换成JSON?

这个示例展示了如何将CSV文件转换为JSON。

隐藏,复制Codestring csv = @“Id, First Name
1, Tom
2, Mark”;

StringBuilder json = new StringBuilder();
using (var r = ChoCSVReader.LoadText(csv)
.WithFirstLineHeader()
.WithMaxScanRows(2)
)
{
using (var w = new ChoJSONWriter(json)
//.Configure(c => c.Formatting = Formatting.None)
//.SupportMultipleContent()
//.SingleElement()
)
{
w.Write(r.Take(2));
}
}

Console.WriteLine(json.ToString());

,

本文转载于:http://www.diyabc.com/frontweb/news127.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值