加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 23:35:26 所属栏目:安全 来源:网络整理
导读:?Demo下载: http://files.cnblogs.com/lxinxuan/wa.rar ?????? 最近一个项目要用到webservice调用业务层类,刚开始的时候遇到了一点小麻烦,经过这两天的总结和实践,终于总结出几个比较常见的情况下的解决方法。 ??????? 不知道大家是怎么解决,可能太
?Demo下载: http://files.cnblogs.com/lxinxuan/wa.rar
?????? 最近一个项目要用到webservice调用业务层类,刚开始的时候遇到了一点小麻烦,经过这两天的总结和实践,终于总结出几个比较常见的情况下的解决方法。
??????? 不知道大家是怎么解决,可能太简单了,所以没有觉得它是一个问题。反正我在博客园中没有搜索到相关的帖子。
??????? 说实话,以前并没有真正开发过涉及webservice的项目,顶多也就是看看msdn,写点小程序,当时并没有发现问题,因为传递的参数和返回值都是简单数据类型,所以并没有发现本文提及的问题——使用自定义类。
?????????所谓自定义类,不知道我有没有表达清楚,这里指的就是petshop中的Model层实体类了。
???????? 比如以下代码:

using ?System;

?System.Collections;

?System.Collections.Generic;

?System.Text;


namespace ?Model

{

????[Serializable]

????
public?class?Student

????
{

????????
privatestring?stuName;


????????
?Student()

????????
{?}


????????
?StuName

????????
{

????????????
get?{?returnthis.stuName;?}

????????????
set?.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();

????????????
?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)

????????
{

????????????
?str?"";


????????????localhost.Student?stuInfo1?
?localhost.Student();

????????????stuInfo1.StuName?
"lxinxuan;

????????????localhost.Student?stuInfo2?
?localhost.Student();

????????????stuInfo2.StuName?
www.cnblogs.com/lxinxuan;


????????????IList
<localhost.Student>?stuList??List();

????????????stuList.Add(stuInfo1);

????????????stuList.Add(stuInfo2);


????????????
object[]?array?.ConvertToArray(stuList);//这是一个将集合转换为Objec[]的泛型方法????????????str??ser.HelloStus(array);传递Object[],返回值是StuName的值

????????????MessageBox.Show(str);

????????}

// 这是一个将集合转换为Objec[]的泛型方法 []?ConvertToArray < T > (IList ?tList)

????????
[tList.Count];

????????????
int?i?0;

????????????
foreach?(T?t?in?tList)

????????????
{

????????????????array[i]?
?t;

????????????????i
++;

????????????}

????????????
?array;

????????}
2、 传递单个实体类,使用WebService中的实体类
这种情况下,可以看作是情况1的特例——只有一个元素的数组。
当然,这种情况下我们可以换一种做法——使用WebService中的实体类。
先看webservice中的代码:
?HelloStu(Student?stuInfo)

???????? ?stuInfo.StuName;

????????}
同样必须添加这一行代码 [XmlInclude( typeof (Student))]。
然后调用代码是:

? ?传递单个实体类,使用WebService中的实体类

????????

???????? 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]

???????? ?HelloStusByList(Collection Student ?stuList) 这里参数类型是Collection

???????? 方法的参数是Collection,在添加了webservice之后,Reference.cs中的对应方法的参数变成了student[],数组!!webservice和数组走得真近阿。。。这里将Reference.cs中的方法HelloStusByList的参数类型student[]改为Collection < localhost.Student >,如下所示。
表示层调用代码:

?传递实体类构成的Collection,通过修改Reference.cs的代码,不过每次更新WebService之后都要重新修改,而且必须每个类修改,麻烦

????????
?button3_Click(

????????
;


????????????Collection
?Collection();

????????????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序列化。这里不再罗列出来。谢谢“代码乱了”]
?HelloStusByCollection( ?sXml)

????????
?BLL.Class1();

????????????Collection
Student?cls.DeSerializerCollection(sXml,?typeof(Collection));//先反序列化为Collection

????????????
DeserializerCollection方法代码如下:

????????
?

????????
<typeparam?name="T"></typeparam><param?name="sXml"></param><param?name="type"></param><returns></returns>?Collection ?DeSerializerCollection ( ?sXml,?Type?type)

????????
{

????????????XmlReader?reader?
?XmlReader.Create(?StringReader(sXml));

????????????System.Xml.Serialization.XmlSerializer?serializer?
?System.Xml.Serialization.XmlSerializer(type);

???????????

????????????
?obj??serializer.Deserialize(reader);

????????????
?(CollectionT)obj;

????????}

表现层调用代码如下:

?先将实体类集合序列化为string,然后在webservice中反序列化成Collection<>,然后再传递给业务层对象

????????
?button4_Click(

????????
;


????????????Student?stuInfo1?
?Student();

????????????stuInfo1.StuName?
;

????????????Student?stuInfo2?
?Student();

????????????stuInfo2.StuName?
?stuString?.SerializerCollection>>(stuList);//先序列化为xml文件格式的string

????????????str?
?ser.HelloStusByCollection(stuString);

????????????MessageBox.Show(str);

????????}
Serialize方法代码如下:

?实体类集合序列化为字符串

????????
<param?name="objToXml"></param>?Serializer (T?objToXml)

????????
{

????????????System.IO.StringWriter?writer?
?System.IO.StringWriter();

????????????System.Xml.Serialization.XmlSerializer?serializer?
?System.Xml.Serialization.XmlSerializer(objToXml.GetType());

????????????serializer.Serialize(writer,?objToXml);

????????????
?writer.GetStringBuilder().ToString();

????????}

5、这种情况就是情况4的特例,序列化一个实体类并传递,方法类似,就不写出来,参见Demo代码。


大概就是这些了,当然传递DataSet是最传统最好的办法了,呵呵~

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读