WebService中使用自定义类的解决方法(5种)

本文介绍使用Webservice传递自定义类的五种方法,包括序列化为Object数组、直接传递单个实体类、修改引用文件传递实体集合、序列化为XML字符串及传递单一实体类的XML表示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Demo下载: http://www.cnblogs.com/Files/lxinxuan/wa.rar        最近一个项目要用到webservice调用业务层类,刚开始的时候遇到了一点小麻烦,经过这两天的总结和实践,终于总结出几个比较常见的情况下的解决方法。         不知道大家是怎么解决,可能太简单了,所以没有觉得它是一个问题。反正我在博客园中没有搜索到相关的帖子。         说实话,以前并没有真正开发过涉及webservice的项目,顶多也就是看看msdn,写点小程序,当时并没有发现问题,因为传递的参数和返回值都是简单数据类型,所以并没有发现本文提及的问题——使用自定义类。          所谓自定义类,不知道我有没有表达清楚,这里指的就是petshop中的Model层实体类了。          比如以下代码:
using  System; using  System.Collections; using  System.Collections.Generic; using  System.Text; namespace  Model {     [Serializable]     public class Student     {         private string stuName;         public Student()         { }         public string StuName         {             get return this.stuName; }             set this.stuName = value; }         }     } }
webservice传递的内容必须是可序列化的,不管是参数还是返回值。上面定义的实体类Student,在类定义之前标示了 [Serializable], 指明可序列化的。但当涉及到实体类集合的时候,如果使用IList<Student>来表示,就会抱错,原因是IList是不可以序列化的, 这种情况下,我们就可以使用System.Collections.ObjectModel.Collection<Student>来表示 一个实体类集合。这里给出了两种可能出现的实体类和实体类集合,以下就开始说明各种解决方法: 1、把实体类集合,作为Object[]传递。       这种情况下,我们必须使用webservice中的实体类,传递的是实体类集合对应的Object[]传递,WebService中方法的参数类型是ArrayList。 比如WebService中的方法是:
[XmlInclude( typeof (Student))]         [WebMethod]          public   string  HelloStus(ArrayList stuList)          {             BLL.Class1 cls = new BLL.Class1();             return cls.GetName(stuList);         }
别漏了 [XmlInclude( typeof (Student))]这一行,不然在表现层就引用不到WebService中的实体类了。 这个时候,在表现层添加web引用,表现层中的调用代码如下:(参考Demo中的button1_Click()方法)
/// <summary>         /// 必须使用webservice中的实体类,传递实体类集合,作为Object[]传递,WebService中的参数类型是ArrayList,并提供一个将集合转化为Object[]的公共类         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>          private   void  button1_Click( object  sender, EventArgs e)          {             string str = "";             localhost.Student stuInfo1 = new localhost.Student();             stuInfo1.StuName = "lxinxuan";             localhost.Student stuInfo2 = new localhost.Student();             stuInfo2.StuName = "www.cnblogs.com/lxinxuan";             IList<localhost.Student> stuList = new List<localhost.Student>();             stuList.Add(stuInfo1);             stuList.Add(stuInfo2);             object[] array = this.ConvertToArray<localhost.Student>(stuList);//这是一个将集合转换为Objec[]的泛型方法             str = ser.HelloStus(array);//传递Object[],返回值是StuName的值             MessageBox.Show(str);         } // 这是一个将集合转换为Objec[]的泛型方法   private   object [] ConvertToArray < T > (IList < T >  tList)          {             object[] array = new object[tList.Count];             int i = 0;             foreach (T t in tList)             {                 array[i] = t;                 i++;             }             return array;         }
2、 传递单个实体类,使用WebService中的实体类 这种情况下,可以看作是情况1的特例——只有一个元素的数组。 当然,这种情况下我们可以换一种做法——使用WebService中的实体类。 先看webservice中的代码:
[XmlInclude( typeof (Student))]         [WebMethod]          public   string  HelloStu(Student stuInfo)          {             return stuInfo.StuName;         }
同样必须添加这一行代码 [XmlInclude( typeof (Student))]。 然后调用代码是:
  /// <summary>         /// 传递单个实体类,使用WebService中的实体类         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>          private   void  button2_Click( object  sender, EventArgs e)          {             string str = "";             localhost.Student stuInfo1 = new localhost.Student();//注意,这里调用了webservice中的实体类,而不是Model中的实体类。否则出错。             stuInfo1.StuName = "lxinxuan";             str = ser.HelloStu(stuInfo1);//传递webservice中的实体类             MessageBox.Show(str);         }
3、 传递实体类构成的Collection。这是和情况1类似的情形,只是传递的类型不一样。可以对照一下。 这 种情况下,必须通过修改Reference.cs的代码,不过每次更新都要重新修改,而且必须每个类修改,比较麻烦!不推荐使用,这不知道是哪位仁兄想出 来的方法,我也是看了人家的做法才总结出来的,不过能去修改Reference.cs的代码,已经说明钻研精神了,鼓励下。 同样先给出webservice中方法的代码:
[WebMethod]          public   string  HelloStusByList(Collection < Student >  stuList) // 这里参数类型是Collection          {             BLL.Class1 cls = new BLL.Class1();             return cls.GetName(stuList);         }
方法的参数是Collection,在添加了webservice之后,Reference.cs中的对应方法的参数变成了student[],数组!! webservice和数组走得真近阿。。。这里将Reference.cs中的方法HelloStusByList的参数类型student[]改为 Collection < localhost.Student >,如下所示。 表示层调用代码:
/// <summary>         /// 传递实体类构成的Collection,通过修改Reference.cs的代码,不过每次更新WebService之后都要重新修改,而且必须每个类修改,麻烦         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>          private   void  button3_Click( object  sender, EventArgs e)          {             string str = "";             localhost.Student stuInfo1 = new localhost.Student();             stuInfo1.StuName = "lxinxuan";             localhost.Student stuInfo2 = new localhost.Student();             stuInfo2.StuName = "www.cnblogs.com/lxinxuan";             Collection<localhost.Student> stuList = new Collection<localhost.Student>();             stuList.Add(stuInfo1);             stuList.Add(stuInfo2);             str = ser.HelloStusByList(stuList);//默认情况下,这里HelloStusByList方法的参数是Student[],通过手动修改为Collection,就可以了             MessageBox.Show(str);         }
4、先将实体类集合序列化为表现为xml格式的string,然后在webservice中反序列化成Collection<>(注意:不可以是IList<>),然后再传递给业务层对象。 [2007-5-25修改:博友“代码乱了”提出,可以采用二进制序列化。确实是的,这里的xml序列化和binary序列化都是可以的,只是我为了调试时跟踪信息方便,才用了xml序列化。这里不再罗列出来。谢谢“代码乱了”]
[WebMethod]          public   string  HelloStusByCollection( string  sXml)          {             BLL.Class1 cls = new BLL.Class1();             Collection<Student> stuList = cls.DeSerializerCollection<Student>(sXml, typeof(Collection<Student>));//先反序列化为Collection             return cls.GetName(stuList);         }
DeserializerCollection方法代码如下:
         /// <summary>         ///          /// </summary>         /// <typeparam name="T"></typeparam>         /// <param name="sXml"></param>         /// <param name="type"></param>         /// <returns></returns>          public  Collection < T >  DeSerializerCollection < T > ( string  sXml, Type type)          {             XmlReader reader = XmlReader.Create(new StringReader(sXml));             System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);                         object obj = serializer.Deserialize(reader);             return (Collection<T>)obj;         }
表现层调用代码如下:
/// <summary>         /// 先将实体类集合序列化为string,然后在webservice中反序列化成Collection<>,然后再传递给业务层对象         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>          private   void  button4_Click( object  sender, EventArgs e)          {             string str = "";             Student stuInfo1 = new Student();             stuInfo1.StuName = "lxinxuan";             Student stuInfo2 = new Student();             stuInfo2.StuName = "www.cnblogs.com/lxinxuan";             Collection<Student> stuList = new Collection<Student>();             stuList.Add(stuInfo1);             stuList.Add(stuInfo2);             string stuString = this.Serializer<Collection<Student>>(stuList);//先序列化为xml文件格式的string             str = ser.HelloStusByCollection(stuString);             MessageBox.Show(str);         }
Serialize方法代码如下:
/// <summary>         /// 实体类集合序列化为字符串         /// </summary>         /// <typeparam name="T"></typeparam>         /// <param name="objToXml"></param>         /// <returns></returns>          public   string  Serializer < T > (T objToXml)          {             System.IO.StringWriter writer = new System.IO.StringWriter();             System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(objToXml.GetType());             serializer.Serialize(writer, objToXml);             return writer.GetStringBuilder().ToString();         }
5、这种情况就是情况4的特例,序列化一个实体类并传递,方法类似,就不写出来,参见Demo代码。 大概就是这些了,当然传递DataSet是最传统最好的办法了,呵呵~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值