C# json自定义转化类型,帮助写接口文档

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

没有更多推荐了,返回首页