【.net 深呼吸】聊聊WCF服务返回XML或JSON格式数据

有时候,为了让数据可以“跨国经营”,尤其是HTTP Web有关的东东,会将数据内容以 XML 或 JSON 的格式返回,这样一来,不管客户端平台是四大文明古国,还是处于蒙昧时代的原始部落,都可以使用这些数据。

在WCF中实现将数据以XML或JSON格式返回有Y多种方法,不管你用什么方法,只要得到预期结果就好,米芾说了,笔可以八面出锋,当然了,人家指的是绘画。

这里,老周就挑两种方法来演示,仅供参考,没有考古价值,建议司马子长不要把本文收入《史记》。

第一种方法是用到 WebServiceHost 类,它可以自动完成一些与HTTP通信相关的配置,不过,使用该类,要以管理身份运行,不然,会无权限监听。

首先定义一个 Book 类,稍后咱们会把一个Book实例以XML或JSON数据返回。

    public sealed class Book
    {
        public string BookName { get; set; }
        public decimal Price { get; set; }

        public string BarCode { get; set; }
    }

然后,很重要一步,就是声明服务协定,它是个接口,可以对客户端公开,当然客户端也可以重新定义。

    [ServiceContract]
    interface IService
    {
        [OperationContract]
        [WebGet(UriTemplate = "getdata?f={format}")]
        Message GetXml(string format);
    }

加上ServiceContract特性表明它是服务协定,如果没有明确指定Name,则它的名字与接口的名字相同;协定接口中,希望向客户端公开的方法要加上OperationContract特性,否则不会被认为是服务操作,无法被客户端使用。

服务协定接口允许在服务器和客户端使用不同定义,只要协定的名称相同,并且方法的参数和返回值类型和数目相同即可。

WebGet特性指定URI的使用方法,地址为相对路径,假如基址是http://dog.net/,那么访问GetXml方法的路径为 http://dog.net/getdata?f=xml。本来我只想返回XML数据的,所以叫GetXml,后来一想,单返回XML格式的内容也太小气了,索性弄一个参数,来指定格式,可以传入xml或json。?f后面的{format}会自动把值传给方法的format参数,所以,UriTemplate的参数名字不要写错,如果写成 ?f={firmat},那就识别不了参数了。

然后要实现服务,实现协定接口的类型不必向客户端公开,因为它是在服务器上执行的。

    public class MyService : IService
    {
        public Message GetXml(string format)
        {
            WebOperationContext context = WebOperationContext.Current;

            Book b = new Book
            {
                BookName = "卖女孩的小火柴",
                Price = 25.2M,
                BarCode = "2811365801"
            };

            Message msgreturn = null;
            // 判断格式
            if (format.ToLower() == "xml")
            {
                msgreturn = context.CreateXmlResponse<Book>(b);
            }
            else
            {
                msgreturn = context.CreateJsonResponse<Book>(b);
            }

            return msgreturn;
        }
    }

这里通过一个很好玩的方法来完成,所以方法返回类型为Message。静态属性WebOperationContext.Current可以得到与当前调用的操作协定关联的上下文对象,即WebOperationContext实例。它公开了一堆方法,名字都是 CreateXXXResponse,其中XXX是啥取决于返回内容,要返回JSON,就调用CreateJsonResponse方法,返回XML就调用CreateXmlResponse方法。

实例化Book对象后,可以传给带泛型参数的CreateJsonResponse或CreateXmlResponse方法,把类型参数T指定为Book,就会自动把Book对象序列化,然后返回给客户端。

最后,在配置文件中给服务设定一个基址,可以在代码中写,也可以在配置文件中写,此处老周选用配置文件,好处是可以动态修改而不必重新编译应用程序。

  <system.serviceModel>
    <services>
      <service name="getXmlSample.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1888/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>

可能有初学的朋友说WCF的配置文件很难写,其实啊,是有规律的,你不妨细心研究一下,掌握规律后你会发现配置文件并不难写。

service的 name 属性的值就是服务类的Type的名字(类型名,带命名空间名称)。

在Main中实例化WebServiceHost。

        static void Main(string[] args)
        {
            WebServiceHost host = new WebServiceHost(typeof(MyService));

            host.Open();
            Console.WriteLine("服务已打开。");
            Console.Read();
            host.Close();
        }

注意,传给构造函数的Type是服务类的类型,与配置文件中service/name的值相同。

以管理员身份运行这个例子,然后打开浏览器,输入http://localhost:1888/getdata?f=xml,回车后,你会看到这样的内容:

把xml改为json,再看看。

怎么样,好玩吧。下面老周再演示另一种方法。

这种方法没使用WebServiceHost,而是使用普通的ServiceHost类来承载服务,可通过WebHttpBinding来得到HTTP交互的支持,不过,不要忘了给终结点配置WebHttpBehavior行为。

同样,先定义一个类,随后用来做测试。

    [DataContract(Namespace = "http://sample",Name = "student")]
    public sealed class Student
    {
        [DataMember(Name = "stu_id")]
        public int StuID { get; set; }

        [DataMember(Name = "stu_name")]
        public string StuName { get; set; }
    }

这一次,咱们通过将对象进行XML或JSON序列化的方式生成数据,并转为字符串返回。服务协定如下:

    [ServiceContract]
    public interface IData
    {
        [OperationContract]
        [WebGet(UriTemplate = "getdata?f={format}")]
        string GetData(string format);
    }

和前面差不多,只是返回类型改为string。

下面代码实现协定接口:

    public class MyService : IData
    {
        public string GetData(string format)
        {
            string res = null;
            Student stu = new Student
            {
                StuID = 3, StuName = "小白"
            };
            using (MemoryStream ms=new MemoryStream())
            {
                XmlObjectSerializer sz = null;
                if (format != null && format.ToLower() == "xml")
                {
                    sz = new DataContractSerializer(stu.GetType());
                }
                else
                {
                    sz = new DataContractJsonSerializer(stu.GetType());

                }
                sz.WriteObject(ms, stu);
                res = Encoding.UTF8.GetString( ms.ToArray());
            }
            return res;
        }
    }

接着,在配置文件中配置一下。

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="hb">
          <webHttp automaticFormatSelectionEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="getXmlSample2.MyService">
        <endpoint address="http://localhost:2008" binding="webHttpBinding" contract="getXmlSample2.IData" behaviorConfiguration="hb"/>
      </service>
    </services>
  </system.serviceModel>

behaviors节点下可以配置两种行为——服务行为和终结点行为。此处我们只需配置终结点的行为,需要一个webHttp元素,它映射到 WebHttpBehavior 类。记得要为behavior节点分配名字,随后在/services/service/endpoint节点下,才能通过behaviorConfiguration属性来引用前面的behavior。

实现HTTP交互,应使用webHttpBinding。

在配置webHttp行为时,应该把automaticFormatSelectionEnabled的值设置为true,这样一来,返回给调用方的内容会自动识别格式,其实主要目的是让返回的字符串中能够去掉最外层的双引号。

回到代码,实例化ServiceHost,然后打开服务。

        static void Main(string[] args)
        {
            using (ServiceHost host=new ServiceHost(typeof(MyService)))
            {
                host.Open();
                Console.WriteLine("服务已打开。");
                Console.Read();
            }
        }

运行应用程序,在浏览中输入http://localhost:2008/getdata?f=xml,得到结果如下。

然后再输入http://localhost:2008/getdata?f=json看看。

好了,就演示这两种方法吧,你愿意探索的话,方法是有很多种的。

示例源代码下载地址

时间: 2024-07-31 21:30:09

【.net 深呼吸】聊聊WCF服务返回XML或JSON格式数据的相关文章

WCF服务返回XML或JSON格式数据

第一种方式public string GetData( string format) { string res = null; Student stu = new Student { StuID = 3, StuName ="李四" }; using (MemoryStream ms = new MemoryStream()) { XmlObjectSerializer sz = null; if ( format.ToLower() == "xml") { sz

SpringBoot RestController 同时支持返回xml和json格式数据

@RestController 默认支持返回json格式数据,即使不做任何配置也能返回json数据 当接口需要支持xml或json两种格式数据时应该怎么做呢? 只要引入 Jackson xml的 maven依赖就可以了: <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-xml-provider</artifactId> &l

基于JDK6的JAX-WX为客户端提供XML与JSON格式数据服务,以及客户端采用AXIS调用案例

1:WebService服务端工程目录如下: 需要第三方jar包:gson-2.2.4.jar\javax.xml.bind.jar\commons-lang-2.5.jar 源码如下: package com.mw.dao; import com.mw.vo.Nsr; import java.util.List; /** * @author y * @date 2015-4-4 9:23:53 * @version 1.0 * @desc */ public interface NsrDao

WCF兼容WebAPI输出Json格式数据,从此WCF一举两得

问题起源: 很多时候为了业务层调用(后台代码),一些公共服务就独立成了WCF,使用起来非常方便,添加服务引用,然后简单配置就可以调用了. 如果这个时候Web站点页面需要调用怎么办呢? 复杂的XML , 使用不方便 ,而且通信成本也比较高. 这时候有人受不了了, 于是就新建了一套WebAPI , Web页面调用爽了.但是维护起来又麻烦了,一会儿WCF , 一会儿WebAPI 一段时间过后,可以想象已经相差甚远了. 某一天同事A , 在业务层需要调用一个接口 ,发现它是WebAPI方式的 ,被迫没办

WebService返回json格式数据供苹果或者安卓程序调用

1.新建一个WebService. 2. 1 /// <summary> 2 /// DemoToJson 的摘要说明 3 /// </summary> 4 [WebService(Namespace = "http://tempuri.org/",Description=("<br><p >西安xx公司</p>技术支持:王光旭"))] 5 [WebServiceBinding(ConformsTo = W

SpringMVC 统一返回JSON格式数据到前端

有时在给APP做接口功能的时候,都是返回JSON格式的数据,所以最好的只好在工程设置一个统一的数据返回方式 在SpringMVC 直接配置XML可以产生这种配置,比较简单 Spring的版本我用的是4.3.3的 <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter&qu

如何让Asp.net webAPI返回JSON格式数据

ASP.NET Web API 是新一代的 HTTP 網路服務開發框架,除了可以透過 Visual Studio 2012 快速開發外 (內建於 ASP.NET MVC 4 的 Web API 專案範本內),也非常適合用於各種跨平台的行動裝置上,如果你想開發 RESTful 應用程式,那麼使用 ASP.NET Web API 應該是挺理想的解決方案.不過 ASP.NET Web API 內建支援 JSON 與 XML 兩種輸出格式,並依據瀏覽器端送出的 Accept 標頭自動決定回應的內容格式,

java XML转JSON格式

标签: XML转Json json 2014-05-20 20:55 6568人阅读 评论(6) 收藏 举报  分类: [J2SE基础](20)  代码如下所示,从这个例子中发现了代码库的重要性,如果建立一个自己的代码库,就可以直接从自己的代码库中取出来,这样需要什么就可以随时的取出来.代码库要保证的是规范性和正确性,并且有简单的模块注释. 这是今天在网上找到的XML转json格式的代码,人家封装的很快,节省了我很多时间啊. [java] view plain copy print? impor

java将XML文档转换成json格式数据

功能 将xml文档转换成json格式数据 说明 依赖包: 1. jdom-2.0.2.jar : xml解析工具包; 2. fastjson-1.1.36.jar : 阿里巴巴研发的高性能json工具包 程序源码 package com.xxx.open.pay.util; import com.alibaba.fastjson.JSONObject; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdo