WebService中使用自定义类进行传输的一些方法
对工作、学习中的一些问题和方法做个记录和总结,以自省。
这里所指的自定义类是指在WebServer端定义的一些类。在WebService中使用自定义类作为参数或返回值来进行传输。
首先,定义一个类,该类是必须可序列化的,所以在定义类的时候需使用特性[Serializable]。例如定义一个类Person来作为传输类型,
Person类的定义代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 [Serializable] 2 public class Person 3 { 4 public string Name { get; set; } 5 public string Sex { get; set; } 6 public int Age { get; set; } 7 8 public Person() { }//必须含有无参构造函数 9 public Person(string name, string sex, int age) 10 { 11 Name = name; 12 Sex = sex; 13 Age = age; 14 } 15 }
然后,以自定义类Person作为示例:
一、自定义类作为单个参数或返回值进行传递。webservice代码中必须添加特性 :[XmlInclude(typeof(Person))],要调用这一特性需引用System.Xml.Serialization名空间。
示例代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Xml.Serialization; [XmlInclude(typeof(Person))] [WebMethod] public Person ChangeName(Person person_input) { person_input.Name = "NewName" + person_input.Name; return person_input; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private void customClassTest_01() { ServiceReference_demo.WebService_demoSoapClient client = new ServiceReference_demo.WebService_demoSoapClient(); ServiceReference_demo.Person basePerson = new ServiceReference_demo.Person() { Name = "Naruto", Sex = "Female", Age = 38 }; ServiceReference_demo.Person newPerson = client.ChangeName(basePerson); MessageBox.Show(string.Format("Name:{0};Sex:{1};Age:{2}", newPerson.Name, newPerson.Sex, newPerson.Age)); }
二、自定义类作为集合来传递 。同样,webservice代码中必须添加特性 :[XmlInclude(typeof(Person))],集合(列表)在WebService中以类数组的方式进行传递。翠花,上代码。
示例代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Xml.Serialization; [XmlInclude(typeof(Person))] [WebMethod] public List<Person> AddPerson(List<Person> list_input) { Person newPerson = new Person("onePeace", "Male", 18); list_input.Add(newPerson); return list_input; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private void customClassTest_02() { ServiceReference_demo.WebService_demoSoapClient client = new ServiceReference_demo.WebService_demoSoapClient(); List<ServiceReference_demo.Person> old_list = new List<ServiceReference_demo.Person>() { new ServiceReference_demo.Person() { Name = "Naruto", Sex = "Female", Age = 38 } }; int old_count = old_list.Count;//初始数量 //webService中集合以数组的方式进行传递,在调用方法前要对参数进行转换。 ServiceReference_demo.Person[] inputArray = retArray(old_list);//转换参数。 ServiceReference_demo.Person[] new_list = client.AddPerson(inputArray);//返回的结果也是数组形式 int new_count = new_list.Length;//调用方法后的数量 MessageBox.Show(string.Format("old_Count:{0};new_Count:{1}", old_count, new_count)); } /// <summary> /// 将List转换为数组的方法 /// </summary> /// <param name="input"></param> /// <returns></returns> private ServiceReference_demo.Person[] retArray(List<ServiceReference_demo.Person> input) { ServiceReference_demo.Person[] array = new ServiceReference_demo.Person[input.Count]; int i = 0; foreach (ServiceReference_demo.Person item in input) { array[i] = item; i++; } return array; }
三、通过序列化、反序列化的方式进行传递。这个方式有点复杂,如果比较执着于传输效率的话可以试试(未考证)。因为Service端和Client端存在程序结构上差异的可能性,所以多数情况下,在反序列化的时候会出现找不到程序集的提示。针对这个问题,可以采用建立公共类库来引用的方式,大体的思路是:
1、 在Service端建立一个.Net类库( ClassLibrary_Person.dll),把自定义类(Person类)放入类库中,作为引用;
2、Client端引用引用该类库(ClassLibrary_Person.Dll);
用此方法实现传递要引用:using System.IO; using System.Runtime.Serialization.Formatters.Binary; 两个名空间
示例代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using ClassLibrary_Person;//引用Person类类库 using System.IO; using System.Runtime.Serialization.Formatters.Binary; [WebMethod] public byte[] bytePersons() { //初始化工作 List<ClassLibrary_Person.Person> persons_ = new List<ClassLibrary_Person.Person>(); ClassLibrary_Person.Person person = new ClassLibrary_Person.Person("Naruto", "Female", 39); BinaryFormatter formatter = new BinaryFormatter();//初始化转换器 byte[] bytes = null; MemoryStream ms = new MemoryStream(); persons_.Add(person); //转换 formatter.Serialize(ms, persons_);//序列化 bytes = ms.GetBuffer();//也可以用下边那个方法来返回Byte数组,不过这个方法效率要高些。 //bytes = ms.ToArray(); return bytes; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using ClassLibrary_Person;////引用Person类类库文件 //client端同样要引用这两个名空间 using System.IO; using System.Runtime.Serialization.Formatters.Binary; private void customClassTest_03() { ServiceReference_demo.WebService_demoSoapClient client = new ServiceReference_demo.WebService_demoSoapClient(); //初始化 byte[] bytes = client.bytePersons(); MemoryStream ms = new MemoryStream(bytes); BinaryFormatter formatter = new BinaryFormatter(); List<ClassLibrary_Person.Person> persons_ = null; //转换 object o_Result = formatter.Deserialize(ms);//反序列化 persons_ = o_Result as List<ClassLibrary_Person.Person>; MessageBox.Show(string.Format("Count:{0}", persons_.Count)); }