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

ZDNet软件频道 时间:2008-07-05 作者: | 中国IT实验室 我要评论()
本文关键词:自定义 WebService xml 软件
所谓自定义类,不知道我有没有表达清楚,这里指的就是petshop中的Model层实体类了。
所谓自定义类,不知道我有没有表达清楚,这里指的就是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>(sxmltypeof(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代码。

自定义

WebService

xml

软件


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134