c# - RESTful WCF 服务在发送 "raw"XML 时返回 400 代码

标签 c# rest wcf

两天来,我一直在用这个问题撞墙,希望有人能帮我一把。我拥有的是一个使用 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/ 我会收到 400(错误请求)。因此,我使用以下代码启用了一些跟踪器来查看发生了什么:

<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/

相关文章:

具有 CORS 和基本身份验证支持的 WCF 自托管数据服务

asp.net - 反序列化操作请求消息正文时出现 WCF 错误

c# - 多线程同时阻塞主线程

php - Laravel 5.4 级联无法创建 REST API(也无法实现一对多关系)

.net - WCF 最小客户端 app.config 设置

java - 为什么 REST Controller 返回 404 状态代码?

java - 带有 Spring : WARNING: javax. ws.rs.NotFoundException 的最新 CXF

c# - 使用查询字符串 MVC 将数组传递给 View

c# - 我可以使用 Xamarin 为 Windows 7 编写应用程序吗?

c# - Devexpress GridView 如何获取选定行的字段值?