Asp.net轻松修改Web Service返回格式

作者:翅膀的初衷 来源:本站原创 发布时间:2015-07-02 查看数:11702

Web Service是目前使用非常普及的一种跨平台的基于WEB的数据交互技术 ,深受广大开发者的喜欢,但是因为Web Service基于XML格式,有时返回的结果中带有较多的额外的数据格式信息,或者基于一些特殊的应用场景,希望对返回的XML格式进行一些自定义,那么,我们怎么办呢?

首先,看一个例子:

下面的数据是某web service返回的一个字符串数组:

<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://WebXml.com.cn/">
<string>湖南</string>
<string>长沙</string>
<string>57679</string>
<string>57679.jpg</string>
<string>2015-7-2 20:20:02</string>
<string>23℃/31℃</string>
<string>7月2日 多云</string>
<string>东北风微风</string>
<string>1.gif</string>
<string>1.gif</string>
<string>今日天气实况:气温:29℃;风向/风力:西北风 1级;湿度:71%;空气质量:暂无;紫外线强度:中等</string>
<string>
太阳镜指数:必要。建议佩戴透射比为1级的浅色太阳镜。 穿衣指数:热。适合穿T恤、短薄外套等夏季服装。 旅游指数:适宜。微风,虽天气稍热,但不会影响心情。 运动指数:较适宜。户外运动请注意防晒。 洗车指数:不宜。有雨,雨水和泥水会弄脏爱车。 化妆指数:去油。请选用露质面霜打底,水质无油粉底霜。 感冒指数:少发。感冒机率较低,避免长期处于空调屋中。 空气污染指数:暂无。 紫外线指数:中等。涂擦SPF大于15、PA+防晒护肤品。 舒适度指数:较不舒适。晴,有些热。
</string>
<string>25℃/31℃</string>
<string>7月3日 多云</string>
<string>东北风微风</string>
<string>1.gif</string>
<string>1.gif</string>
<string>23℃/27℃</string>
<string>7月4日 阵雨转小雨</string>
<string>东北风转西北风微风</string>
<string>3.gif</string>
<string>7.gif</string>
</ArrayOfString>

看起来还算比较正常,但是如果是object数组,下面的子点节的名字就会五花八门,变成如下格式:

湖南 长沙 57679 57679.jpg 2015-7-2 20:20:02

看起来非常不整齐,而且读取起来也不方便。幸好.NET中我们可以通过为对象实现IXmlSerializable接口来自定义格式,比如:

    public class MyObjectList : List<Object>, IXmlSerializable
    {

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;

        }

        public void ReadXml(System.Xml.XmlReader reader)
        {

        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteStartElement("List");
            for (var i = 0; i < this.Count; i++)
            {
                writer.WriteStartElement("Item");
                writer.WriteString(this[i].ToString());
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

        }
    }

那么,该类型的web service返回的结果就是

<MyObjectList xmlns="http://tempuri.org/">
<List>
<Item>sss</Item>
<Item>aaa</Item>
<Item>1111</Item>
</List>
</MyObjectList>

好了,要是我返回有很多格式,比如字典啊,INT数组啊,DataTable啊,及其它泛型数组与各式自定义对象,那我不是每个类型都要先重新定义一个并实现一下IXmlSerializable接口?那不是多麻烦?

理论上确实是这样,不过,我们可以灵活变通一下,不必要这么麻烦。我们只要定义一个类并实现IXmlSerializable就行了,然后在WriteXml中判断下类型即可,代码如下(仅供参考原理):

public class ResultData : IXmlSerializable
    {
        #region IXmlSerializable 成员


        private object _data;
        public object Data
        {
            get { return _data; }
            set { _data = value; }
        }


        public ResultData(object data)
        {
            this._data = data;
        }


        public ResultData()
            : this(null)
        {
        }

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }


        public void ReadXml(System.Xml.XmlReader reader)
        {


        }


        public void WriteXml(System.Xml.XmlWriter writer)
        {
            Type t = this._data.GetType();
            if(this._data is IEnumerable) //是否是可枚举对象
            {
                IEnumerable data1 = (IEnumerable)this._data;
                IEnumerator data2 = data1.GetEnumerator();
                writer.WriteStartElement("List");
                while (data2.MoveNext())
                {
                    writer.WriteStartElement("Item");
                    writer.WriteString(data2.Current.ToString());
                    writer.WriteEndElement();
                }
                 writer.WriteEndElement()
            }
            else if (t.IsClass)
            {
                PropertyInfo[] pi = this._data.GetType().GetProperties();
                for (int i = 0; i < pi.Length; i++)
                {
                    writer.WriteStartElement("Item");
                    writer.WriteStartElement(pi[i].Name.ToLower());
                    writer.WriteString(pi[i].GetValue(this._data, null).ToString());
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                }
            }
            //更多略...
            //此处只做了简单判断,实际应用中应该要处理注意处理和复杂情况
        }
    }

我们在web service中返回其它类型时,只要 return new ResultData(你的对象) 就行了。如果是可枚举对象,返回的格式为

<ResultData xmlns="http://tempuri.org/">
<List>
<Item>你的数据</Item>
<Item>你的数据</Item>

</List>
</ResultDatat>

如果是类,则为

<ResultData xmlns="http://tempuri.org/">
<Item>
<属性1>你的数据</属性1>
<属性2>你的数据</属性2>

</Item>
</ResultDatat>

当然,你也可以根据自己的需要自行定义成任何格式。(注:以上演示代码仅供演示,类型的判断不完善,实际应用中请注意完善相关代码)

原创文章,转载请注明作者与出处:http://www.jiniannet.com