两天来,我一直在用这个问题撞墙,希望有人能帮我一把。我拥有的是一个使用 WCF 编写的 RESTful Web 服务;没什么,实际上只是两个接受单个字符串参数并返回字符串的方法。参数和返回值都是纯 XML。
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "/method1/{data}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
string Method1(string data);
[OperationContract]
[WebGet(UriTemplate = "/method2/{data}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
string Method2(string data);
}
为了论证,假设这两种方法的实现如下所示:
public string Method1(string data)
{
return string.Format("You entered: {0}", data);
}
如果我转到 http://myuri.com/service.svc/method1/foo,将向浏览器写入以下内容:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You
entered: foo</string>
这很好用,但如果我将 url 更改为:http://myuri.com/service.svc/method1/
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="All">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\Traces.svclog" />
</listeners>
</source>
</sources>
如您所见,我正在使用开关值“All”来捕获在执行此服务期间发生的每个事件。我使用 URL 格式跑了几次,以验证跟踪器是否正常工作。然后我转到包含 XML 标记 foo 的 URL,并按预期收到 400 错误,但是当我返回日志文件时,它的末尾没有附加信息。这使我相信在调用 WCF 服务之前会显示 400 错误。
最后,我将方法从“GET”方法切换为“POST”方法,使用 WebRequest/WebResponse 编写了一些代码,结果相同。现在我已经阅读了一些关于在客户端使用 XmlSerializer 将数据发送到服务的帖子,但这违背了该服务的目的。当我使用 .NET 编写服务时,很可能 PHP 或经典 ASP 脚本将连接到该服务,而且它们显然无法访问 XmlSerializer。
所以我的百万美元问题是:是否可以将“原始”XML 请求发送到在 WCF 中开发的 RESTful web 服务,如果可以,如何发送?
附言 进入和离开服务的 XML 不基于任何有形对象,它只是我创建的用于此服务的结构。传入的 XML 通过 XPath 进行解析,将值放入更大的 XML 字符串中,并传递给外部 API。来自该 API 的结果经过处理,然后由我的 RESTful 服务返回。
任何帮助将不胜感激!!
最佳答案
Brett,感谢您提供的代码。不幸的是我在这个线程中找到了它:WCF Rest parameters involving complex types并在发帖之前尝试过。
无论如何,我已经解决了这个问题。现在我很想说我有一个完整的“ Eureka ”时刻,一切都刚刚好,但事实是我刚开始在谷歌上扔首字母缩略词,其中一个 SERP 将我带到了这个链接:http://blogs.msdn.com/pedram/archive/2008/04/21/how-to-consume-rest-services-with-wcf.aspx
链接本身并没有直接解决手头的问题,但它让我对如何将我的 URI 模板放在一起有了不同的想法。我读过这篇 MSDN 文章 http://msdn.microsoft.com/en-us/library/dd203052.aspx关于如何组合 RESTful 服务。在示例中,作者提供了几种不同的模板,其中一些使用典型的查询字符串参数式模板,而另一些则不使用。无论出于何种原因,我选择了没有典型查询字符串参数的模板,如我原来的帖子中所示。所以我稍微修改了我的代码并想出了这个:
[OperationContract]
[WebGet(UriTemplate = "/method1/?xml={data}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
string Method2(string data);
请注意,URI 模板是唯一发生变化的东西;从“/method1/{data}”更改为“/method1/?xml={data}。然后我导航到 http://myuri.com/service.svc/method1/?xml= 和 viola,一切都很顺利!
这也是 POST 的问题。无论出于何种原因,在内容主体中传递 XML,即使作为键/值对,也会导致 400 错误。使用上面显示的完全相同的 URI 模板,我打开了 Fiddler,执行了一个 POST,结果是 200 OK。
感谢大家的帮助。
关于c# - RESTful WCF 服务在发送 "raw"XML 时返回 400 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2016544/