【发布时间】:2009-09-29 09:10:42
【问题描述】:
我为此苦苦挣扎了几个小时,但找不到解决沟通问题的方法。 我的服务需要通过 SOAP 或纯 XML 与客户端通信
我的服务将基于 WCF 框架编写,但我的客户不是。
您能否逐步向我展示如何更改我的服务代码和配置以使其返回 SOAP 或 XML 消息?我对这两种解决方案都感兴趣。
我试图根据这个答案来实现这一目标:
REST / SOAP endpoints for a WCF service Call WCF Using SOAP call
但是这个解决方案对我来说都没有正常工作。要么是我的浏览器没有任何内容,要么是找不到资源的错误。
所以我开始了一个新的 WCF 服务项目。它在http://localhost:3151/ 下运行,代码如下:
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;
}
}
}
可能我需要创建两个端点?它们都应该包含basicHttpBinding 作为绑定参数。但是还有什么?
另外,如何生成这样的 XML(基于数据契约):
<CompositeType BoolValue = 0 StringValue = "">
而不是这样:
<CompositeType>
<BoolValue>0</BoolValue>
<StringValue></StringValue>
</CompositeType>
请注意,我需要双向通信,因此我的服务需要接收 SOAP 或 XML 并以 SOAP 或 XML 响应。
如果可能的话,我希望在浏览器中看到服务方法的描述,就像在 ASP .NET 中一样。
提前感谢您的宝贵时间。
这里有非常大的更新
我试图找到一些解决方案,这就是我迄今为止收集到的全部内容。我只关注纯 XML。
假设协议如下所示:
来自客户的消息:
<MESSAGE MessageParam1 = 0>
<AdditionalInfo>Some message info </AdditionalInfo>
</MESSAGE>
回复:
<RESPONSE ResponseParam1 = 0>
<AdditionalInfo>Some response info</AdditionalInfo>
</MESSAGE>
首先,我想查看当前服务方法的描述,并以确切的格式进行参数化,因为它们将被发送/接收。我的意思是,当我在浏览器中调用 Service(刚刚启动服务)时尝试使用 ASP .NET 2.0 WebServices 时,我得到了这样的响应:
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>
这很棒。除此之外,它具有 SOAP 信封(基础数据也不同),但重点是我可以将其展示给客户并告诉他:“您正在使用这种 XML 结构执行 HTTP POST 方法,并且您正在收到这样的答案”。我想要与 WCF 类似的结果,但更简单 - 没有 SOAP。到目前为止,当我单击 Service1.svc 时,我得到了一堆我不想要的 WSDL 代码。我知道这在某些情况下很好,但我不知道哪个平台正在使用我的客户端。如果他不使用 .NET,那么它可能不会正确导入 WSDL。
所以你知道我想要什么。
这是我在漫长的两天后所做的……:
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;
}
}
如您所见,我没有提供 Message 类,因为我不知道如何通过浏览器将它传递给方法。我只知道如何传递一个字符串。
这是实现和配置:
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;
}
}
}
配置对我来说也有点神秘。我尝试创建绑定,正如 MSDN 的主题之一所述:http://msdn.microsoft.com/en-us/library/aa395208.aspx
但是在调用一个方法后,我返回了一个类似 SOAP 的错误结构,但没有 SOAP 信封。
反正这里是配置:
<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>
当我像这样在浏览器中调用服务方法时:
http://localhost:2443/Service1.svc/rest/EchoWithGet?s=test
我在浏览器中获得了一个 XML 文件:
<Response ResponseParam1="0">
<AdditionalInfo>I've responded: test</AdditionalInfo>
</Response>
看来我走在正确的轨道上?但是,我仍然不知道如何接收有关已发送内容和已接收内容的完整信息(如 ASP .NET 2.0 中的信息)。我宁愿不使用嗅探器侦听服务端口来查看通过 HTTP 的情况。我想看看。另外,当我查看接收到的 XML 的源文件时,我看到:
<?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>
我不想在返回的 XML 中包含这些附加信息,如何删除?
另一个问题是第二种方法:
http://localhost:2443/Service1.svc/rest/EchoWithPost?s=test
这没有按预期工作。我收到“不允许使用方法”的错误消息。如何解决?
所以,让我们总结一下这个长长的问题。
我有一些半途而废的解决方案,可能是正确的方式,也可能是错误的方式。我想请您完成它,它也可以:
- 在方法中接受 XML 文件作为参数。
- 向我展示如何在 Web 浏览器中以 XML 作为参数调用该方法。是的,我不想在 .NET 中使用单独的客户端。让浏览器成为客户端。
- 告诉我如何在返回的 XML 中删除不必要的臃肿信息。
- 告诉我如何获取我的服务的类似 .NET 2.0 的描述,同时记住我不想使用 SOAP。
- 解释一下 EchoWithPost 方法有什么问题。为什么它不起作用?
如果我的例子不好,请提供一些基本的例子应该如何实现。
我只是在学习 .NET 和 WCF,我很困惑。只有设置正确的数据交换协议才能解决所有这些问题......而且我什至还没有开始编写真正的服务:|
非常感谢您的时间和任何未来的帮助。
【问题讨论】:
-
@wozdu:你完全在正确的轨道上;使用 WCF REST 服务观看有关“Plain Old XML”的截屏视频 - 它允许您做所有您想做的事情(返回完全自定义的 XML,只包含您想要的元素和属性)。
标签: xml wcf web-services soap