把對象轉化爲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