WCF 服务,SOAP 或纯 XML 响应,如何? [英] WCF service, response in SOAP or plain XML, how?

查看:28
本文介绍了WCF 服务,SOAP 或纯 XML 响应,如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为此苦苦挣扎了几个小时,但找不到通信问题的解决方案.我的服务需要通过 SOAP 或纯 XML 与客户端通信

我的服务将基于 WCF 框架编写,但我的客户不是.

您能否逐步向我展示如何以返回 SOAP 或 XML 消息的方式更改我的服务代码和配置?我对这两种解决方案都感兴趣.

我试图根据以下答案实现这一目标:

WCF 服务的 REST/SOAP 端点使用 SOAP 调用调用 WCF

但是没有一个解决方案适合我.要么我的浏览器中没有任何内容,要么出现找不到资源的错误.

所以我开始了一个新的 WCF 服务项目.它在 http://localhost:3151/ 下运行,代码如下:

使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Runtime.Serialization;使用 System.ServiceModel;使用 System.Text;命名空间 WcfService1{//注意:如果您在此处更改类名Service1",您还必须在 Web.config 和关联的 .svc 文件中更新对Service1"的引用.公共类 Service1 : IService1{公共字符串 GetData(int 值){return string.Format("您输入的是:{0}", value);}public CompositeType GetDataUsingDataContract(CompositeType Composite){if (composite.BoolValue){Composite.StringValue += "后缀";}返回组合;}}}

可能我需要创建两个端点?它们都应该包含 basicHttpBinding 作为绑定参数.但还有什么?

另外,如何生成这样的 XML(基于数据契约):

而不是这个:

<BoolValue>0</BoolValue><StringValue></StringValue></复合类型>

请注意,我需要进行双向通信,因此我的服务需要接收 SOAP 或 XML 以及 SOAP 或 XML 中的响应.

此外,如果可能的话,我希望在我的浏览器中看到服务方法的描述,就像在 ASP .NET 中一样.

提前感谢您的时间.

这里有很大的更新

我试图找到一些解决方案,这就是我目前收集到的所有内容.我只关注纯 XML.

假设协议如下所示:

来自客户的消息:

<AdditionalInfo>一些消息信息</AdditionalInfo></MESSAGE>

回复:

<AdditionalInfo>一些响应信息</AdditionalInfo></MESSAGE>

首先,我想查看当前服务方法的描述,以及它们将被发送/接收时的确切格式.我的意思是,当我在浏览器中调用 Service(刚刚启动服务)时,当我尝试使用 ASP .NET 2.0 WebServices 时,我得到了这样的响应:

POST/Service1.asmx HTTP/1.1主机:本地主机内容类型:文本/xml;字符集=utf-8内容长度:长度SOAPAction:http://tempuri.org/ShowUser"<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><肥皂:身体><ShowUser xmlns="http://tempuri.org/"><我的登录><用户>字符串</用户><密码>字符串</密码><数据库>字符串</数据库></我的登录></ShowUser></soap:Body></soap:Envelope>HTTP/1.1 200 正常内容类型:文本/xml;字符集=utf-8内容长度:长度<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><肥皂:身体><ShowUserResponse xmlns="http://tempuri.org/"><ShowUserResult>字符串</ShowUserResult></ShowUserResponse></soap:Body></soap:Envelope>

这太棒了.除此之外,它具有 SOAP 信封(基础数据也不同),但重点是我可以将其展示给客户端并告诉他:您正在使用这种 XML 结构执行 HTTP POST 方法,并且您正在收到这样的答案".我想要与 WCF 类似的结果,但更简单 - 没有 SOAP.到目前为止,当我单击 Service1.svc 时,我得到了一堆我不想要的 WSDL 代码.我知道这在某些情况下非常有用,但我不知道我的客户端正在使用什么平台.如果他不使用 .NET,那么它可能无法正确导入 WSDL.

所以你知道我想要什么.

这就是我在漫长的两天后所做的...:

命名空间 RESTService{//注意:如果在此处更改接口名称IService1",则还必须更新 Web.config 中对IService1"的引用.[服务合约][XmlSerializerFormat]公共接口 IService{【经营合同】[网络获取]响应 EchoWithGet(string s);【经营合同】[网络调用]响应 EchoWithPost(string s);}公开课回应{[Xml 属性]公共 int ResponseParam1;[XmlElement]公共字符串附加信息;}}

如您所见,我没有提供 Message 类,因为我不知道如何通过浏览器将其传递给该方法.我只知道如何传递一个字符串.

这是实现和配置:

命名空间 RESTService{//注意:如果您在此处更改类名Service1",您还必须在 Web.config 和关联的 .svc 文件中更新对Service1"的引用.公共类 Service1 : IService{公共响应 EchoWithGet(string s){响应事务;交易 = 新响应();Transaction.AdditionalInfo = "我已回复:" + s;返回交易;}公共响应 EchoWithPost(string s){响应事务;交易 = 新响应();Transaction.AdditionalInfo = "我已回复:" + s;返回交易;}}}

配置对我来说也有点神秘.我尝试创建绑定,因为它在 MSDN 的主题之一中有所描述:http://msdn.microsoft.com/en-us/library/aa395208.aspx

但是在调用一个方法之后,我返回了一个类似 SOAP 的错误结构,但没有 SOAP 信封.

无论如何这里是配置:

<服务><服务名称="RESTService.Service1"><主机></host><端点地址=休息"行为配置=网络行为"bindingConfiguration="" binding="webHttpBinding"合同=RESTService.IService"/></服务></服务><行为><端点行为><行为名称=网络行为"><webHttp/></行为></endpointBehaviors></行为></system.serviceModel>

当我像这样在浏览器中调用服务方法时:

http://localhost:2443/Service1.svc/rest/EchoWithGet?s=测试

我在浏览器中得到了一个 XML 文件:

<AdditionalInfo>我已经回复:test</AdditionalInfo></响应>

所以看起来我是在正确的轨道上?但是,我仍然不知道如何接收有关已发送内容和已接收内容的完整信息(如 ASP .NET 2.0 中的信息).我宁愿不使用嗅探器侦听服务端口来查看通过 HTTP 进行的操作.我想看看.另外,当我查看收到的 XML 的源文件时,我看到了:

<?xml version="1.0" encoding="utf-8"?><Response ResponseParam1="0" xmlns:xsi="http://www.w3.org/2001/XMLSchema 实例" <br/>xmlns:xsd="http://www.w3.org/2001/XMLSchema"><br/><AdditionalInfo>我已经回复了:test</AdditionalInfo></Response>

我不想在返回的 XML 中包含此附加信息,如何删除?

另一个问题是第二种方法:

http://localhost:2443/Service1.svc/rest/EchoWithPost?s=测试

这不符合预期.我收到不允许使用方法"的错误消息.如何解决这个问题?

那么,让我们总结一下这个长问题.

我有一些半途而废的解决方案,这可能是正确的方法,也可能是错误的方法.我想请你要么完成它,它也可以:

  1. 在方法中接受一个 XML 文件作为参数.
  2. 演示如何使用 XML 作为参数在 Web 浏览器中调用该方法.是的,我不想在 .NET 中使用单独的客户端.让浏览器成为客户端.
  3. 告诉我如何在返回的 XML 中删除不必要的臃肿信息.
  4. 告诉我如何获取类似 .NET 2.0 的服务描述,同时记住我不想要 SOAP.
  5. 解释一下 EchoWithPost 方法有什么问题.为什么它不起作用?

如果我的例子不好,请给我一些基本的例子,它应该如何实现.

我只是在学习 .NET 和 WCF,我很困惑.只有设置正确的数据交换协议才能解决所有这些问题......我什至还没有开始编写真正的服务:|

非常感谢您的时间和任何未来的帮助.

解决方案

您在此处拥有的服务返回一条 SOAP 消息 - 其中将包含CompositeType"作为其有效负载".

WCF 默认使用 SOAP - 任何基本的HttpBinding、wsHttpBinding、netTcpBinding 等都以 SOAP 作为它们的基础.

如果您想直接返回 XML,您需要查看 WCF 的 REST 功能 - 这适用于 webHttpBinding(并且仅适用于该绑定).

<块引用><块引用>

另外,如何生成这样的 XML(基于数据契约):

<块引用><块引用>

而不是这个:

<BoolValue>0</BoolValue><StringValue></StringValue></复合类型>

这是 WCF DataContract 序列化程序的限制.出于性能原因,它不支持属性,例如您无法创建您想要的第一个 XML 片段.

如果您绝对必须拥有第一个 XML,则需要改用 XmlSerializer(它有其自身的一组限制/问题).

马克

更新:如果您只想返回给定的 XML,那么使用 REST 方法可能会更好.

查看 Pluralsight 网站,获取关于使用 REST 的出色系列截屏视频特别是关于如何创建 的一个截屏视频普通的 XML (POX) REST 服务.

I am struggling few hours with this and can't find a solution to the communication problem. My service need to communicate with clients via SOAP or plain XML

My service will be written based on WCF framework, however my clients not.

Could you show me step by step how to change my service code and configuration in a way that it will return SOAP or XML message? I am interested in both solutions.

I've tried to achieve this basing on this answers:

REST / SOAP endpoints for a WCF service Call WCF Using SOAP call

But none of this solution worked properly for me. Either I got nothing in my browser or error that resource could not be found.

So I've started a new WCF Service Project. It runs under http://localhost:3151/ and have code like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfService1
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}

Probably I'will need to create two endpoints? Both of them should contain basicHttpBinding as a binding parameter. But what else?

Also, how to produce an XML like this (based on data contract):

<CompositeType BoolValue = 0 StringValue = "">

rather than this:

<CompositeType>
  <BoolValue>0</BoolValue>
  <StringValue></StringValue>
</CompositeType>

Please note that I need to as a two way communication so my service need to receive SOAP or XML and response in SOAP or XML.

Also if this is possible I would like to see description of the service methods in my browser just like it was in ASP .NET.

Thanks in advance for your time.

Very big update down here

I've tried to find some solution and here it is all what I gathered so far. I've focused only on plain XML.

Lets say that the protocol looks like this:

Message from a client:

<MESSAGE MessageParam1 = 0>
  <AdditionalInfo>Some message info </AdditionalInfo>
</MESSAGE>

Response:

<RESPONSE ResponseParam1 = 0>
  <AdditionalInfo>Some response info</AdditionalInfo>
</MESSAGE>

First of all, I would like to see description of current service methods and it params in the exact format as they will be send / received. What I mean is that when I was experimented with ASP .NET 2.0 WebServices when I invoked Service in my browser (just started the service) I've got such response:

POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/ShowUser"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ShowUser xmlns="http://tempuri.org/">
      <MyLogin>
        <User>string</User>
        <Password>string</Password>
        <Database>string</Database>
      </MyLogin>
    </ShowUser>
  </soap:Body>
</soap:Envelope>

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ShowUserResponse xmlns="http://tempuri.org/">
      <ShowUserResult>string</ShowUserResult>
    </ShowUserResponse>
  </soap:Body>
</soap:Envelope>

And this is GREAT. Apart from that this has SOAP envelope (underlying data is also different) but the point is that I can show it to the client and tell him: "you are doing HTTP POST method with such XML structure and you are receiving such answer". I want similar result with WCF but even simpler - without SOAP. So far, when I click on the Service1.svc I am getting a bunch of WSDL code which I don't want to. I know that this is great for some cases but I don't know what platform is using my client. And if he won't be using .NET than it will probably not import correctly the WSDL.

So you know what I would like to get.

This is what I did so far after two long days...:

namespace RESTService
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.

    [ServiceContract]
    [XmlSerializerFormat]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        Response EchoWithGet(string s);

        [OperationContract]
        [WebInvoke]
        Response EchoWithPost(string s);
    }

    public class Response
    {
        [XmlAttribute]
        public int ResponseParam1;
        [XmlElement]
        public string AdditionalInfo;
    }
}

As you see I did not provide Message class because I don't know how to pass it to the method via browser. I only know how to pass a string.

And here is the implementation and config:

namespace RESTService
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class Service1 : IService
    {
        public Response EchoWithGet(string s)
        {
            Response Transaction;
            Transaction = new Response();
            Transaction.AdditionalInfo = "I've responded: " + s;
            return Transaction;
        }
        public Response EchoWithPost(string s)
        {
            Response Transaction;
            Transaction = new Response();
            Transaction.AdditionalInfo = "I've responded: " + s;
            return Transaction;
        }
    }
}

The config is also a bit of mystery for me. I've tried to create binding as it was described in one of the topics from MSDN: http://msdn.microsoft.com/en-us/library/aa395208.aspx

but then after invoking a method I had returned a SOAP-like fault structure but without SOAP envelope.

Anyway here is the config:

<system.serviceModel>
      <services>
         <service name="RESTService.Service1">
           <host>
           </host>
           <endpoint 
               address="rest" behaviorConfiguration="webBehavior"
               bindingConfiguration="" binding="webHttpBinding" 
               contract="RESTService.IService"/>
         </service>
       </services>
       <behaviors>
         <endpointBehaviors>
            <behavior name="webBehavior">
               <webHttp />
            </behavior>
         </endpointBehaviors>
       </behaviors>
</system.serviceModel>

When I invoke a service method in my browser like this:

http://localhost:2443/Service1.svc/rest/EchoWithGet?s=test

I got in my browser an XML file:

<Response ResponseParam1="0">
<AdditionalInfo>I've responded: test</AdditionalInfo>
</Response>

So it looks like I am on the right track? However still I don't know how to receive a full information (like the one in ASP .NET 2.0 ) about what has been send and what has been received. I would like to rather not listen the service port with sniffer to look what is going through HTTP. I would like to see it. Also, when I look at the source file of the received XML I see this:

<?xml version="1.0" encoding="utf-8"?><Response ResponseParam1="0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <br/>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><br/>
<AdditionalInfo>I've responded: test</AdditionalInfo></Response>

I don't want to have this additional info in the returned XML, how to cut this?

Another problem is with the second method:

http://localhost:2443/Service1.svc/rest/EchoWithPost?s=test

This doesn't work as expected. I get the error message that "method is not allowed". How to resolve this?

So, lets sum up this long question.

I have some half-working solution which might be the correct way or is the wrong way. I would like to ask you to either finish it that it also could:

  1. Accept in method an XML file as a parameter.
  2. Show me how to call the method in web browser with XML as a parameter. Yes, I don't want to a separate client in .NET. Let the browser will be the client.
  3. Show me how to cut unnecessary bloated info in returned XML.
  4. Show me how to obtain .NET 2.0-like description of my service with bearing on mind that I don't want to have SOAP.
  5. Explain me what is wrong with EchoWithPost method. Why it doesn't work?

If my example is bad, please provide me some basic example how it should be achieved.

I am just learning .NET and WCF and I am very confused. All that problems only with setting up correct data exchange protocol... and I even haven't statred to write a real service :|

Thanks a lot for your time and any future help.

解决方案

The service you have here will return a SOAP message - which will contain the "CompositeType" as its "payload".

WCF by default uses SOAP - any of the basicHttpBinding, wsHttpBinding, netTcpBinding etc. all work with SOAP as their basis.

If you want to return straight XML, you need to check out the REST capabilities of WCF - this works with the webHttpBinding (and only that binding).

Also, how to produce an XML like this (based on data contract):

<CompositeType BoolValue = 0 StringValue = "">

rather than this:

<CompositeType>
  <BoolValue>0</BoolValue>
  <StringValue></StringValue>
</CompositeType>

This is a limitation of the WCF DataContract serializer. For performance reasons, it does not support attributes, e.g. you cannot create the first fragment of XML that you want.

If you absolutely must have the first XML, you'll need to use the XmlSerializer instead (which has its own set of limitations / problems).

Marc

UPDATE: if you just want to return a given XML, then you're probably better off with the REST approach.

Check out the Pluralsight website for an excellent series of screencasts on using REST and in particular, one screencast on how to create a plain-old XML (POX) REST service.

这篇关于WCF 服务,SOAP 或纯 XML 响应,如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆