好久没有做web了,JSON目前比较流行,闲得没事,所以动手试试将对象序列化为JSON字符(尽管DotNet Framework已经有现成的库,也有比较好的第三方开源库),而且只是实现了处理简单的类型,并且DateTime处理的也不专业,有兴趣的筒子可以扩展,代码比较简单,反序列化木有实现:( ,直接贴代码吧,都有注释了,所以废话不多说 :)
测试类
///
<summary>
///
Nested class of Person.
///
</summary>
public
class
House
{
public
string
Name
{
get
;
set
;
}
public
double
Price
{
get
;
set
;
}
}
///
<summary>
///
Person dummy class
///
</summary>
public
class
Person
{
public
string
Name
{
get
;
set
;
}
public
int
Age
{
get
;
set
;
}
public
string
Address
{
get
;
set
;
}
private
int
h
=
12
;
public
bool
IsMarried
{
get
;
set
;
}
public
string
[] Names
{
get
;
set
;
}
public
int
[] Ages
{
get
;
set
;
}
public
House MyHouse
{
get
;
set
;
}
public
DateTime BirthDay
{
get
;
set
;
}
public
List
<
string
>
Friends
{
get
;
set
;
}
public
List
<
int
>
LoveNumbers
{
get
;
set
;
}
}
接口定义
///
<summary>
///
IJsonSerializer interface.
///
</summary>
interface
IJsonSerializer
{
///
<summary>
///
Serialize object to json string.
///
</summary>
///
<typeparam name="T">
The type to be serialized.
</typeparam>
///
<param name="obj">
Instance of the type T.
</param>
///
<returns>
json string.
</returns>
string
Serialize(
object
obj);
///
<summary>
///
Deserialize json string to object.
///
</summary>
///
<typeparam name="T">
The type to be deserialized.
</typeparam>
///
<param name="jsonString">
json string.
</param>
///
<returns>
instance of type T.
</returns>
T Deserialize
<
T
>
(
string
jsonString);
}
接口实现,还有待完善..
///
<summary>
///
Implement IJsonSerializer, but Deserialize had not been implemented.
///
</summary>
public
class
JsonSerializer : IJsonSerializer
{
///
<summary>
///
Serialize object to json string.
///
</summary>
///
<typeparam name="T">
The type to be serialized.
</typeparam>
///
<param name="obj">
Instance of the type T.
</param>
///
<returns>
json string.
</returns>
public
string
Serialize(
object
obj)
{
if
(obj
==
null
)
{
return
"
{}
"
;
}
//
Get the type of obj.
Type t
=
obj.GetType();
//
Just deal with the public instance properties. others ignored.
BindingFlags bf
=
BindingFlags.Instance
|
BindingFlags.Public;
PropertyInfo[] pis
=
t.GetProperties(bf);
StringBuilder json
=
new
StringBuilder(
"
{
"
);
if
(pis
!=
null
&&
pis.Length
>
0
)
{
int
i
=
0
;
int
lastIndex
=
pis.Length
-
1
;
foreach
(PropertyInfo p
in
pis)
{
//
Simple string
if
(p.PropertyType.Equals(
typeof
(
string
)))
{
json.AppendFormat(
"
\"{0}\":\"{1}\"
"
, p.Name, p.GetValue(obj,
null
));
}
//
Number,boolean.
else
if
(p.PropertyType.Equals(
typeof
(
int
))
||
p.PropertyType.Equals(
typeof
(
bool
))
||
p.PropertyType.Equals(
typeof
(
double
))
||
p.PropertyType.Equals(
typeof
(
decimal
))
)
{
json.AppendFormat(
"
\"{0}\":{1}
"
, p.Name, p.GetValue(obj,
null
).ToString().ToLower());
}
//
Array.
else
if
(isArrayType(p.PropertyType))
{
//
Array case.
object
o
=
p.GetValue(obj,
null
);
if
(o
==
null
)
{
json.AppendFormat(
"
\"{0}\":{1}
"
, p.Name,
"
null
"
);
}
else
{
json.AppendFormat(
"
\"{0}\":{1}
"
, p.Name, getArrayValue((Array)p.GetValue(obj,
null
)));
}
}
//
Class type. custom class, list collections and so forth.
else
if
(isCustomClassType(p.PropertyType))
{
object
v
=
p.GetValue(obj,
null
);
if
(v
is
IList)
{
IList il
=
v
as
IList;
string
subJsString
=
getIListValue(il);
json.AppendFormat(
"
\"{0}\":{1}
"
, p.Name, subJsString);
}
else
{
//
Normal class type.
string
subJsString
=
Serialize(p.GetValue(obj,
null
));
json.AppendFormat(
"
\"{0}\":{1}
"
, p.Name, subJsString);
}
}
//
Datetime
else
if
(p.PropertyType.Equals(
typeof
(DateTime)))
{
DateTime dt
=
(DateTime)p.GetValue(obj,
null
);
if
(dt
==
default
(DateTime))
{
json.AppendFormat(
"
\"{0}\":\"\"
"
, p.Name);
}
else
{
json.AppendFormat(
"
\"{0}\":\"{1}\"
"
, p.Name, ((DateTime)p.GetValue(obj,
null
)).ToString(
"
yyyy-MM-dd HH:mm:ss
"
));
}
}
else
{
//
TODO: extend.
}
if
(i
>=
0
&&
i
!=
lastIndex)
{
json.Append(
"
,
"
);
}
++
i;
}
}
json.Append(
"
}
"
);
return
json.ToString();
}
///
<summary>
///
Deserialize json string to object.
///
</summary>
///
<typeparam name="T">
The type to be deserialized.
</typeparam>
///
<param name="jsonString">
json string.
</param>
///
<returns>
instance of type T.
</returns>
public
T Deserialize
<
T
>
(
string
jsonString)
{
throw
new
NotImplementedException(
"
Not implemented :(
"
);
}
///
<summary>
///
Get array json format string value.
///
</summary>
///
<param name="obj">
array object
</param>
///
<returns>
js format array string.
</returns>
string
getArrayValue(Array obj)
{
if
(obj
!=
null
)
{
if
(obj.Length
==
0
)
{
return
"
[]
"
;
}
object
firstElement
=
obj.GetValue(
0
);
Type et
=
firstElement.GetType();
bool
quotable
=
et
==
typeof
(
string
);
StringBuilder sb
=
new
StringBuilder(
"
[
"
);
int
index
=
0
;
int
lastIndex
=
obj.Length
-
1
;
if
(quotable)
{
foreach
(var item
in
obj)
{
sb.AppendFormat(
"
\"{0}\"
"
, item.ToString());
if
(index
>=
0
&&
index
!=
lastIndex)
{
sb.Append(
"
,
"
);
}
++
index;
}
}
else
{
foreach
(var item
in
obj)
{
sb.Append(item.ToString());
if
(index
>=
0
&&
index
!=
lastIndex)
{
sb.Append(
"
,
"
);
}
++
index;
}
}
sb.Append(
"
]
"
);
return
sb.ToString();
}
return
"
null
"
;
}
///
<summary>
///
Get Ilist json format string value.
///
</summary>
///
<param name="obj">
IList object
</param>
///
<returns>
js format IList string.
</returns>
string
getIListValue(IList obj)
{
if
(obj
!=
null
)
{
if
(obj.Count
==
0
)
{
return
"
[]
"
;
}
object
firstElement
=
obj[
0
];
Type et
=
firstElement.GetType();
bool
quotable
=
et
==
typeof
(
string
);
StringBuilder sb
=
new
StringBuilder(
"
[
"
);
int
index
=
0
;
int
lastIndex
=
obj.Count
-
1
;
if
(quotable)
{
foreach
(var item
in
obj)
{
sb.AppendFormat(
"
\"{0}\"
"
, item.ToString());
if
(index
>=
0
&&
index
!=
lastIndex)
{
sb.Append(
"
,
"
);
}
++
index;
}
}
else
{
foreach
(var item
in
obj)
{
sb.Append(item.ToString());
if
(index
>=
0
&&
index
!=
lastIndex)
{
sb.Append(
"
,
"
);
}
++
index;
}
}
sb.Append(
"
]
"
);
return
sb.ToString();
}
return
"
null
"
;
}
///
<summary>
///
Check whether t is array type.
///
</summary>
///
<param name="t"></param>
///
<returns></returns>
bool
isArrayType(Type t)
{
if
(t
!=
null
)
{
return
t.IsArray;
}
return
false
;
}
///
<summary>
///
Check whether t is custom class type.
///
</summary>
///
<param name="t"></param>
///
<returns></returns>
bool
isCustomClassType(Type t)
{
if
(t
!=
null
)
{
return
t.IsClass
&&
t
!=
typeof
(
string
);
}
return
false
;
}
}
测试代码:
class
Program
{
static
void
Main(
string
[] args)
{
Person ps
=
new
Person()
{
Name
=
"
Leon
"
,
Age
=
25
,
Address
=
"
China
"
,
IsMarried
=
false
,
Names
=
new
string
[] {
"
wgc
"
,
"
leon
"
,
"
giantfish
"
},
Ages
=
new
int
[] {
1
,
2
,
3
,
4
},
MyHouse
=
new
House()
{
Name
=
"
HouseName
"
,
Price
=
100.01
,
},
BirthDay
=
new
DateTime(
1986
,
12
,
20
,
12
,
12
,
10
),
Friends
=
new
List
<
string
>
() {
"
friend1
"
,
"
friend2
"
},
LoveNumbers
=
new
List
<
int
>
() {
1
,
2
,
3
}
};
IJsonSerializer js
=
new
JsonSerializer();
string
s
=
js.Serialize(ps);
Console.WriteLine(s);
Console.ReadKey();
}
}
生成的 JSON字符串 :
{
"
Name
"
:
"
Leon
"
,
"
Age
"
:
25
,
"
Address
"
:
"
China
"
,
"
IsMarried
"
:
false
,
"
Names
"
:[
"
wgc
"
,
"
leon
"
,
"
giantfish
"
],
"
Ages
"
:[
1
,
2
,
3
,
4
],
"
MyHouse
"
:{
"
Name
"
:
"
HouseName
"
,
"
Price
"
:
100.01
},
"
BirthDay
"
:
"
1986-12-20 12:12:10
"
,
"
Friends
"
:[
"
friend1
"
,
"
friend2
"
],
"
LoveNumbers
"
:[
1
,
2
,
3
]}
嗯 ,就这样子,没有研究开源的JSON代码是如何实现的,应该也是拼接字符串吧,上面的代码再多测试,完善下,应该也差不多可以投产了 :)