WebService中使用自定义类的解决方法

日期: 2008-04-21 来源:TechTarget中国

  所谓自定义类,不知道我有没有表达清楚,这里指的就是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< >),然后再传递给业务层对象。


         [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();


  }

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 如何在.NET4中用jQuery调用WCF?

    在我们之前的开发中,对于ajax程序,都是通过jQuery调用标记为[System.Web.Script.Services.ScriptService]的WebService……

  • Webservice之Axis实践

    由于解决方案需要,必须发布一个可以供使用的Webservice。今天按照说明做了一axis的简单实践。

  • IT高速发展时代SOA怎么了

    ERP,企业资源计划。以企业资源的角度来组织企业的人、财、物、信息。此概念产生于大生产时代MRP之后,号召把企业的上下游也纳入到企业通盘战略考虑当中……

  • SOA中的“S”

    这些天一直在关注WebService,SOA的核心理念是”S”,即服务。当我们的构件完成之后,究竟如何发布为何种服务,这就设计到了SCA绑定的问题……