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

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

发布时间:2020-12-17 00:29:23 所属栏目:安全 来源:网络整理
导读:所谓自定义类,不知道我有没有表达清楚,这里指的就是petshop中的Model层实体类了。 比如以下代码:? using System; using System.Collections; using System.Collections.Generic; using System.Text; namespace Model { ??? [Serializable] ??? public cla

所谓自定义类,不知道我有没有表达清楚,这里指的就是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> 网管论坛bbs_bitsCN_com?
??????? /// 传递单个实体类,使用WebService中的实体类
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>?

??????? private void button2_Click(object sender,EventArgs e)
??????? { 中国网管论坛bbs.bitsCN.com?
??????????? 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 网管下载dl.bitscn.com?
??????? {??
??????????? 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 = " ??????????? 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?

?????????????Collection<Student> stuList = cls.DeSerializerCollection<Student>(sXml,typeof(Collection<Student>));????????????

??????????? 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 = " ??????????? Collection<Student> stuList = new Collection<Student>();?

??????????? 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是最传统最好的办法了,呵呵~?



博主测试:

上面的介绍写的很详细,按照步骤可以完成webservice传递自定义参数的目的。通过上面几种方法的启示,博主自己写想到一个方法。

在webservice方法中参数全部通过字符串来传递,然后在自定义类型中添加对象和字符串互相转换的方法,需要传递自定义对象时,将对象转换为字符串,然后接收方收到字符串后将字符串再转换为自定义对象。

这种方法和序列化方法差不多,但是简单易懂,不过可能安全性可能不好。

(编辑:李大同)

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

    推荐文章
      热点阅读