1 json自定义转化类型
指定实列类型的属性序列化
在.Net中把对象转为json字符串主要有四种,具体参考
1自己转化灵活,但难度大,能实现。
2使用Newtonsoft.Json,看了一下官方文档,似乎不能实现,能忽略默认,空值等属性,也可以控制json时输出那些属性,但需要使用特性,也就是说,对于指定的类型,json输出的属性是确定的,不能动态改变。
3使用JavaScriptSerializer类,查看了官方文档,没找到方法,不能实现
4也是使用的是特性,没找到方法,不能实现。
.net中如何实现json转化时只处理部分属性
private static readonly List<Type> TypeCodeList = new List<Type>{
{ typeof(char)},
{ typeof(char?)},
{ typeof(bool)},
{ typeof(bool?)},
{ typeof(sbyte)},
{ typeof(sbyte?)},
{ typeof(short)},
{ typeof(short?)},
{ typeof(ushort)},
{ typeof(ushort?)},
{ typeof(int)},
{ typeof(int?)},
{ typeof(byte)},
{ typeof(byte?)},
{ typeof(uint)},
{ typeof(uint?)},
{ typeof(long)},
{ typeof(long?)},
{ typeof(ulong)},
{ typeof(ulong?)},
{ typeof(float)},
{ typeof(float?)},
{ typeof(double) },
{ typeof(double?)},
{ typeof(DateTime)},
{ typeof(DateTime?)},
{ typeof(DateTimeOffset)},
{ typeof(DateTimeOffset?)},
{ typeof(decimal)},
{ typeof(decimal?)},
{ typeof(Guid)},
{ typeof(Guid?)},
{ typeof(TimeSpan)},
{ typeof(TimeSpan?)},
{ typeof(Uri)},
{ typeof(string)},
{ typeof(byte[])},
{ typeof(DBNull)}
};
/// <summary>
/// 把对象转化为json字符串,依然不能处理属性是泛型,数组,对象等类型
/// </summary>
/// <typeparam name="T">需要转化的对象的类型</typeparam>
/// <param name="t">需要转化的对象</param>
/// <param name="propertyInfos">需要转换的字段列表,用逗号分隔</param>
/// <returns></returns>
public static string ConvertFromModeTojson<T>(T t, string propertyInfos) where T : class
{
StringWriter sw = new StringWriter();
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.WriteStartObject();
string[] cols = propertyInfos.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string col in cols)
{
Type type = t.GetType();
PropertyInfo pinfo = type.GetProperty(col);//使用反射获得属性
if (pinfo != null)
{
object v = pinfo.GetValue(t, null);//使用反射获得属性的值
Type pinfoType = pinfo.PropertyType;
if (TypeCodeList.Contains(pinfoType))
{
writer.WritePropertyName(col);
writer.WriteValue(v);
}
else
{ //其他类型的忽略,避免异常
}
}
else
{
throw new Exception("不存在属性" + col);
}
}
writer.WriteEndObject();
writer.Flush();
}
string jsonText = sw.GetStringBuilder().ToString();
return jsonText;
}
二 自定义Json序列化只序列化部分前缀相同的
实现:将post参数输出文件帮助写文档
需求:因为写post接口文档,所以想直接把类型属性输出到文件,复制
指定实列类型的属性名称前缀序列化
比如 实列有CodeA ,CodeB,CodeC, OrderA 我只想要Code前缀属性序列化
作了一下修改,使用了StartsWith方法
public string ConvertFromModeTojsonConatin<T>(T t, params string[] cols) where T : class
{
StringWriter sw = new StringWriter();
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.WriteStartObject();
foreach (string col in cols)
{
var pinfos = t.GetType().GetProperties(); //使用反射获得属性
foreach (var item in pinfos)
{
string name = item.Name;
var pinfo = name.StartsWith(col);
if (pinfo)
{
object v = item.GetValue(t, null);//使用反射获得属性的值
Type pinfoType = item.PropertyType;
if (TypeCodeList.Contains(pinfoType)) //其他类型的忽略,避免异常
{
processValue(pinfoType,ref v);
writer.WritePropertyName(name);
writer.WriteValue(v);
}
}
}
}
writer.WriteEndObject();
writer.Flush();
}
string jsonText = sw.GetStringBuilder().ToString();
return jsonText;
}
private void processValue(Type type, ref object value)
{
if(value==null)
{
if (type == typeof(string))
{
value = "";
}
}
}
获取前缀为Code属性 json为:
{"CodeA":"","CodeB":"","CodeC":"","CodeD":""}
异步调用获取JSON数据时非常不直观,每次都需要格式化一次,才能直观的看到数据集合的结构,现在需要实现输出带缩进的格式。
把JSON字符串格式化:
private string ConvertJsonString(string str)
{
//格式化json字符串
JsonSerializer serializer = new JsonSerializer();
TextReader tr = new StringReader(str);
JsonTextReader jtr = new JsonTextReader(tr);
object obj = serializer.Deserialize(jtr);
if (obj != null)
{
StringWriter textWriter = new StringWriter();
JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
{
Formatting = Formatting.Indented,
Indentation = 4,
IndentChar = ' '
};
serializer.Serialize(jsonWriter, obj);
return textWriter.ToString();
}
else
{
return str;
}
}
json格式化变为:
{
"CodeA": "",
"CodeB": ""
}
最后输出代码:
private void ModelTolocalJson<T>(string pathname, params string[] cols) where T: class
{
var model = Activator.CreateInstance<T>();
string json = ConvertFromModeTojsonConatin<T>(model, cols);
json = ConvertJsonString(json);
string path = Common.ExcelRootPath + pathname + ".doc";
System.IO.File.WriteAllText(path, json);
}
三 获取url字符串参数,转化为实列,输出到Excel文档
1把 URL字符串参数转化到实列里面
/// 获取url字符串参数,返回参数值字符串
/// </summary>
/// <param name="name">参数名称</param>
/// <param name="url">url字符串</param>
/// <returns></returns>
private static string GetQueryString(string name, string url)
{
url = url.ToLower();
System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", System.Text.RegularExpressions.RegexOptions.Compiled);
System.Text.RegularExpressions.MatchCollection mc = re.Matches(url);
foreach (System.Text.RegularExpressions.Match m in mc)
{
if (m.Result("$2").Equals(name))
{
return m.Result("$3");
}
}
return "";
}
private void urlToModel<T>(T Model, string url) where T : new()
{
var property = Model.GetType().GetProperties();
foreach (var item in property)
{
var value = GetQueryString(item.Name.ToLower(), url);
if (value != "")
{
var type = item.PropertyType;
if (type == typeof(int))
{
item.SetValue(Model, int.Parse(value));
}
else if (type == typeof(Decimal))
{
item.SetValue(Model, decimal.Parse(value));
}
else if (type == typeof(Double))
{
item.SetValue(Model, Double.Parse(value));
}
else if (type == typeof(bool))
{
item.SetValue(Model, Boolean.Parse(value));
}
else if (type == typeof(byte))
{
item.SetValue(Model, byte.Parse(value));
}
else if (type == typeof(DateTime))
{
if (value.Length <= 10)
{
value = value + " 00:00:00";
}
item.SetValue(Model, DateTime.Parse(value));
}
else
{
item.SetValue(Model, value.ToString());
}
}
}
}
2 把当前实列写出到EXCEL文件
private void createDeclareExcel<T>(string pathname)
{
//创建Excel文件的对象
NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
//添加一个sheet
NPOI.SS.UserModel.ISheet sheet1 = book.CreateSheet("Sheet1");
NPOI.SS.UserModel.IRow row1 = sheet1.CreateRow(0);
row1.CreateCell(0).SetCellValue("字段名");
row1.CreateCell(1).SetCellValue("类型");
row1.CreateCell(2).SetCellValue("是否必要");
row1.CreateCell(3).SetCellValue("说明");
int i = 0;
var property = typeof(T).GetProperties();
foreach (var item in property)
{
var column = item.GetCustomAttributes(typeof(ColumnAttribute), false).SingleOrDefault() as ColumnAttribute;
if (column != null )
{
string name = column.Name;
i++;
NPOI.SS.UserModel.IRow rowtemp = sheet1.CreateRow(i);
rowtemp.CreateCell(0).SetCellValue(item.Name);
rowtemp.CreateCell(1).SetCellValue(item.PropertyType.Name);
rowtemp.CreateCell(3).SetCellValue(name);
}
}
string fileName = Common.ExcelRootPath + pathname + ".xls";
using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
{
book.Write(fs);
}
}
扩展:
params 是C#的关键字, 可变长参数,是在声明方法时参数类型或者个数不确定时使用
关于params 参数数组,需掌握以下几点:
一.参数数组必须是一维数组
二.不允许将params修饰符与ref和out修饰符组合起来使用
三.与参数数组对应的实参可以是同一类型的数组名,也可以是任意多个与该数组的元素属于同一类型的变量
四.若实参是数组则按引用传递,若实参是变量或表达式则按值传递
五.形式为:方法修饰符 返回类型 方法名(params 类型[ ] 变量名)
六.params参数必须是参数表的最后一个参数
总结:
1 可以使用JsonTextWriter写Json数据,用WritePropertyName,WriteValue写属性名和值
2 可以使用JsonTextWriter的Formatting 格式化
3 HSSFWorkbook 的write就直接可以写入文件流
参考文献:
C#序列化只处理部分类型:https://blog.csdn.net/xuexiaodong009/article/details/46998695
格式化代码:https://www.cnblogs.com/unintersky/p/3884712.html
params:https://blog.csdn.net/wcc27857285/article/details/80991824