.net调用web Service时集合序列化的解决方案

在.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,因为这是一个重新序列化后的数组集合。

省去了对象转换的烦恼!

邀月工作室

posted @ 2010-03-12 20:19  邀月  阅读(1651)  评论(2编辑  收藏  举报