在.net中调用Web Service时,如果要返回一个集合,一般使用Dataset或DataTable(Framework 2.0后DataTable也可以序列化了)
DataSet的优势是可以与XML实现自由转换,可以被.net以外的其他平台调用。
可以参考MSDN:通过 XML Web Services 使用数据集 (ADO.NET) http://msdn.microsoft.com/zh-cn/library/s5xy331f.aspx
遗憾的是,如果客户端无法传递特定序列化的集合,如自定义的对象集合。
曾经看到萤火虫这样用:XmlSerializer 序列化实体类来操作xml文件 http://www.cnblogs.com/Marvel/archive/2009/01/20/1379041.html
以前有做法是转化为DataSet,今天试了下,发现可以不用DataSet也可以实现WebSercice传递序列集合。
新建一个web service,并建一个三个类:
代码
using
System;
using
System.Collections.Generic;
using
System.Collections;
using
System.Xml;
namespace
DemoListsByWebService
{
#region
Area
public
class
Area
{
private
string
m_Area_ID;
///
<summary>
///
Area_ID
///
</summary>
public
string
Area_ID
{
get
{
return
m_Area_ID; }
set
{ m_Area_ID
=
value; }
}
private
string
m_Area_Name;
///
<summary>
///
Area_Name
///
</summary>
public
string
Area_Name
{
get
{
return
m_Area_Name; }
set
{ m_Area_Name
=
value; }
}
private
double
m_Area_Order;
///
<summary>
///
Area_Order
///
</summary>
public
double
Area_Order
{
get
{
return
m_Area_Order; }
set
{ m_Area_Order
=
value; }
}
}
#endregion
#region
AreaCollection
[Serializable]
public
class
AreaCollection : CollectionBase
{
public
AreaCollection()
{
}
public
AreaCollection(Area[] value)
{
}
public
Area
this
[
int
index]
{
get
{
return
((Area)(
this
.List[index])); }
}
public
int
Add(Area value)
{
return
this
.List.Add(value);
}
public
void
AddRange(Area[] value)
{
for
(
int
i
=
0
; (i
<
value.Length); i
=
(i
+
1
))
{
this
.Add(value[i]);
}
}
public
void
AddRange(AreaCollection value)
{
for
(
int
i
=
0
; (i
<
value.Count); i
=
(i
+
1
))
{
this
.Add((Area)value.List[i]);
}
}
public
bool
Contains(Area value)
{
return
this
.List.Contains(value);
}
public
void
CopyTo(Area[] array,
int
index)
{
this
.List.CopyTo(array, index);
}
public
int
IndexOf(Area value)
{
return
this
.List.IndexOf(value);
}
public
void
Insert(
int
index, Area value)
{
List.Insert(index, value);
}
public
void
Remove(Area value)
{
List.Remove(value);
}
private
int
_maxItems
=
0
;
public
int
MaxItems
{
get
{
return
this
._maxItems; }
set
{
this
._maxItems
=
value; }
}
public
Area FindByID(
string
id)
{
for
(
int
i
=
0
; (i
<
Count); i
++
)
{
if
(
this
[i].Area_ID
==
id)
{
return
this
[i];
}
}
return
null
;
}
public
string
FindNameByID(
string
id)
{
for
(
int
i
=
0
; (i
<
Count); i
++
)
{
if
(
this
[i].Area_ID
==
id)
{
return
this
[i].Area_Name;
}
}
return
null
;
}
public
string
FindIDByName(
string
cateName)
{
for
(
int
i
=
0
; (i
<
Count); i
++
)
{
Area tempArea
=
this
[i];
if
(tempArea.Area_Name.Trim()
==
cateName.Trim())
{
return
tempArea.Area_ID;
}
}
return
null
;
}
}
[Serializable]
public
class
AreaLists : List
<
Area
>
{
//
Extend your properties and methods by Tony . for more Help to
//
http://msdn.microsoft.com/zh-cn/library/s6hkc2c4.aspx
private
int
_maxItems
=
0
;
public
int
MaxItems {
get
{
return
this
._maxItems; }
set
{
this
._maxItems
=
value; } }
}
#endregion
}
注意对象集合必须添加属性 [Serializable]
再建一测试方法:
代码
using
System;
using
System.Collections.Generic;
using
System.Web;
namespace
DemoListsByWebService
{
public
class
MyMethods
{
#region
Methods
public
static
AreaLists GetTestArea()
{
AreaLists al
=
new
AreaLists();
for
(
int
i
=
1
; i
<
11
; i
++
)
{
Area a
=
new
Area();
a.Area_ID
=
i.ToString();
a.Area_Name
=
"
第
"
+
i.ToString()
+
"
名
"
;
al.Add(a);
}
return
al;
}
public
static
AreaCollection GetTestAreaCollection()
{
AreaCollection al
=
new
AreaCollection();
for
(
int
i
=
1
; i
<
11
; i
++
)
{
Area a
=
new
Area();
a.Area_ID
=
i.ToString();
a.Area_Name
=
"
第
"
+
i.ToString()
+
"
名
"
;
al.Add(a);
}
return
al;
}
#endregion
}
}
web Service提供的方法:
代码
using
System;
using
System.Collections.Generic;
using
System.Web;
using
System.Web.Services;
namespace
DemoListsByWebService
{
///
<summary>
///
Summary description for Service1
///
</summary>
[WebService(Namespace
=
"
http://tempuri.org/
"
)]
[WebServiceBinding(ConformsTo
=
WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(
false
)]
public
class
Service1 : System.Web.Services.WebService
{
[WebMethod(Description
=
"
Get Areas
"
)]
public
AreaLists GetTestArea()
{
try
{
AreaLists ac
=
MyMethods.GetTestArea();
return
ac;
}
catch
(Exception e)
{
return
null
;
}
}
[WebMethod(Description
=
"
Get AreaCollections
"
)]
public
AreaCollection GetTestAreaCollection()
{
try
{
AreaCollection ac
=
MyMethods.GetTestAreaCollection();
return
ac;
}
catch
(Exception e)
{
return
null
;
}
}
}
}
服务OK!
新建一 Winform窗体项目,添加web service引用,http://localhost/DemoListsByWebService/Service1.asmx
在主窗体中调用方法:
private
void
BindAreaList()
{
DemoWebServiceList.Service1 dl
=
new
TestWebServiceOfLists.DemoWebServiceList.Service1();
DemoWebServiceList.Area[] ac
=
dl.GetTestArea();
cbArea.DataSource
=
ac;
cbArea.DisplayMember
=
"
Area_Name
"
;
cbArea.ValueMember
=
"
Area_ID
"
;
cbArea.SelectedValue
=
"
5
"
;
lbResult.Text
=
"
集合共:
"
+
ac.Length.ToString()
+
"
个元素!
"
;
}
private
void
BindAreaCollection()
{
DemoWebServiceList.Service1 dl
=
new
TestWebServiceOfLists.DemoWebServiceList.Service1();
DemoWebServiceList.Area[] ac
=
dl.GetTestAreaCollection();
cbArea.DataSource
=
ac;
cbArea.DisplayMember
=
"
Area_Name
"
;
cbArea.ValueMember
=
"
Area_ID
"
;
cbArea.SelectedValue
=
"
5
"
;
lbResult.Text
=
"
集合共:
"
+
ac.Length.ToString()
+
"
个元素!
"
;
}
注意: DemoWebServiceList.Area[]的集合个数不用Count,MaxItems,而用Length,因为这是一个重新序列化后的数组集合。
省去了对象转换的烦恼!