把对象转化为json字符串,很经常使用,但若是由于如今大部分项目都是用了ORM映射,致使一个对象的属性特别多,若是前台只须要部分属性如何实现?html
固然最简单是全部属性都json化,前台只处理须要的属性,多余的无论。那有没有一种方式能够实现,对于同一种类型,按照前台的须要只处理json须要的属性呢?shell
在.Net中把对象转为json字符串主要有四种方式:具体参考json
1本身转化灵活,但难度大,能实现。数组
2使用Newtonsoft.Json,看了一下官方文档,彷佛不能实现,能忽略默认,空值等属性,也能够控制json时输出那些属性,但须要使用特性,也就是说,对于指定的类型,json输出的属性是肯定的,不能动态改变。
ide
具体可参考ui
3使用JavaScriptSerializer类,查看了官方文档,没找到方法,不能实现spa
4也是使用的是特性,没找到方法,不能实现。.net
没有现成的方法,也就只能本身实现了。咱们知道把对象转化为json字符串,核心天然是使用反射获得须要的属性和属性的值。但若是属性是一个类对象呢?,数组或者是泛型呢?code
另外若是字符串中包含特殊字符如何处理?orm
因而本身也就实现了一个简单的
-
-
-
-
-
-
-
-
public
static
string ConvertFromModeTojson<T>(T t,
string propertyInfos)
where T :
class
-
-
string[] cols = propertyInfos.Split(
new
char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
-
System.Text.StringBuilder sb =
new System.Text.StringBuilder(
300);
-
-
foreach (
string col
in cols)
-
-
string str = GetOneProperty<T>(t, col);
-
-
-
result += sb.ToString().TrimEnd(
',');
-
-
-
-
private
static
string GetOneProperty<T>(T t,
string pname)
where T :
class
-
-
-
PropertyInfo pinfo = type.GetProperty(pname);
-
-
-
object v = pinfo.GetValue(t,
null);
-
string tt = PropertyTypeValue(pinfo.PropertyType, v, pname);
-
-
-
-
-
throw
new Exception(
"不存在属性" + pname);
-
-
-
-
-
-
-
private
static
readonly List<Type> TypeNumCodeList =
new List<Type>{
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
private
static
readonly List<Type> TypeStrCodeList =
new List<Type>{
-
-
-
-
-
-
-
-
-
-
-
-
-
private static string PropertyTypeValue(Type propertytype, object value, string propertyName)
-
-
string valueStr =
value !=
null ?
value.ToString() :
"";
-
-
if (TypeNumCodeList.Contains(propertytype))
-
-
if (!
string.IsNullOrEmpty(valueStr))
-
-
returnStr =
string.Format(
"\"{0}\":{1},", propertyName, valueStr);
-
-
-
else
if (TypeStrCodeList.Contains(propertytype))
-
-
if (!
string.IsNullOrEmpty(valueStr))
-
-
returnStr =
string.Format(
"\"{0}\":\"{1}\",", propertyName, valueStr);
-
-
-
else
if (propertytype ==
typeof(
string))
-
-
if (!
string.IsNullOrEmpty(valueStr))
-
-
returnStr =
string.Format(
"\"{0}\":\"{1}\",", propertyName, String2Json(valueStr));
-
-
-
-
-
-
returnStr =
string.Format(
"\"{0}\":\"{1}\",", propertyName, String2Json(valueStr));
-
-
-
-
-
-
-
-
-
-
private static string String2Json(string s)
-
-
StringBuilder sb =
new StringBuilder();
-
for (
int i =
0; i < s.Length; i++)
-
-
char c = s.ToCharArray()[i];
-
-
-
-
sb.Append(
"\\\"");
break;
-
-
sb.Append(
"\\\\");
break;
-
-
sb.Append(
"\\/");
break;
-
-
sb.Append(
"\\b");
break;
-
-
sb.Append(
"\\f");
break;
-
-
sb.Append(
"\\n");
break;
-
-
sb.Append(
"\\r");
break;
-
-
sb.Append(
"\\t");
break;
-
-
-
-
-
-
if ((c >=
0 && c <=
31) || c ==
127)
-
-
-
-
-
-
-
-
-
-
-
-
很显然,这个实现有很大的问题,字符串中包含的特殊字符不必定处理完了,泛型,数组等属性都没有处理,可是简单对象仍是能够处理的。
既然Newtonsoft.Json是开源的,那能不能利用它实现呢?
因而使用Newtonsoft.Json改进了以上代码
-
private
static
readonly List<Type> TypeCodeList =
new List<Type>{
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
typeof(DateTimeOffset)},
-
{
typeof(DateTimeOffset?)},
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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)
-
-
-
PropertyInfo pinfo = type.GetProperty(col);
-
-
-
object v = pinfo.GetValue(t,
null);
-
Type pinfoType = pinfo.PropertyType;
-
if (TypeCodeList.Contains(pinfoType))
-
-
writer.WritePropertyName(col);
-
-
-
-
-
-
-
-
-
-
throw
new Exception(
"不存在属性" + col);
-
-
-
-
-
-
string jsonText = sw.GetStringBuilder().ToString();
-
-
在前面的文章中使用的json方法,能够按照须要只处理须要的属性,但却要求属性不能是复杂的类型,例如泛型,数组,其余用户自定义的类等,限制太多,因而本身看看能不能改进,想不到Newtonsoft.Json提供有相关的接口,只须要实现就能够了。只须要继承DefaultContractResolver,并改写一个方法就能够了。
核心代码:
-
-
-
-
-
-
-
public
static
string ObjToJsonString<ObjType>(ObjType obj)
where ObjType :
class
-
-
string s = JsonConvert.SerializeObject(obj);
-
-
-
-
-
-
-
-
-
-
public
static
string ObjToJsonString<T>(T t,
string propertyInfos)
where T :
class
-
-
string[] cols = propertyInfos.Split(
new
char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
-
List<
string> _propertyNames =
new List<
string>();
-
foreach (
string col
in cols)
-
-
string colTemp = col.ToLower().Trim();
-
if (!_propertyNames.Contains(colTemp))
-
-
_propertyNames.Add(colTemp);
-
-
-
string s = JsonConvert.SerializeObject(t, Formatting.Indented,
new JsonSerializerSettings { ContractResolver =
new DynamicContractResolver(_propertyNames) });
-
-
-
-
-
-
-
-
-
public
static ObjType JsonStringToObj<ObjType>(
string JsonString)
where ObjType :
class
-
-
ObjType s = JsonConvert.DeserializeObject<ObjType>(JsonString);
-
-
-
class
DynamicContractResolver :
DefaultContractResolver
-
-
-
private
readonly List<
string> _propertyNames;
-
public DynamicContractResolver(List<string> propertyNames)
-
-
_propertyNames = propertyNames;
-
-
-
-
-
-
-
-
-
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
-
-
IList<JsonProperty> properties =
base.CreateProperties(type, memberSerialization);
-
IList<JsonProperty> propertiesReturn =
new List<JsonProperty>();
-
foreach (JsonProperty item
in properties)
-
-
-
string PropertyNameTemp = item.PropertyName.ToLower().Trim();
-
if (_propertyNames.Contains(PropertyNameTemp))
-
-
propertiesReturn.Add(item);
-
-
-
-
-
-
出处:
https://blog.csdn.net/xuexiaodong009/article/details/46998695 https://blog.csdn.net/xuexiaodong009/article/details/47004105