RESTful WCF 服务在发送“原始"代码时返回 400 代码XML [英] RESTful WCF Service returns a 400 code when sending "raw" XML

查看:34
本文介绍了RESTful WCF 服务在发送“原始"代码时返回 400 代码XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两天我一直在敲我的头,希望有人能帮我一把.我拥有的是使用 WCF 编写的 RESTful Web 服务;没有什么真正只是两个接受单个字符串参数并返回一个字符串的方法.参数和返回值都是纯 XML.

I have been banging my head of the wall for two days with this so, hopefully, someone can give me a hand. What I have is a RESTful Web Service that I wrote using WCF; nothing to it really just two methods that accept a single string parameter and also return a string. Both the parameter and return value are straight 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);

}

为了论证,我们假设这两种方法的实现如下所示:

For the sake of argument lets say that the implementation of both of these methods looks like this:

public string Method1(string data)
{
    return string.Format("You entered: {0}", data);
}

如果我转到 http://myuri.com/service.svc/method1/foo,以下内容将写入浏览器:

If I goto http: //myuri.com/service.svc/method1/foo the following is wrote to the browser:

  <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You 
    entered: foo</string> 

这很好用,但如果我将 url 更改为:http://myuri.com/service.svc/method1/<foo >我得到 400(错误的请求).所以我使用以下代码启用了一些跟踪器来查看发生了什么:

This works great but if I change the url to: http: //myuri.com/service.svc/method1/<foo > I get a 400 (Bad Request). So I enabled some tracers to see what was going using the following code:

<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 错误.

As you can see I am using the switch value 'All' to capture every event that happens during the execution of this service. I ran back through a few times using the URL format that works to verify that the tracers were working and they were. I then went to the URL that contained the XML tag foo and recieved the 400 error as expected but when I went back to the log file there had been no additional information appened to the end of it. This leads me to believe that the 400 error is being displayed before the WCF service is ever invoked.

最后,我将方法从GET"方法切换到POST"方法,使用 WebRequest/WebResponse 编写了一些代码,结果相同.现在我已经阅读了一些关于在客户端使用 XmlSerializer 将数据发送到服务的帖子,但这违背了该服务的目的.当我使用 .NET 编写服务时,PHP 或经典 ASP 脚本很可能会连接到此服务,而且它们显然无法访问 XmlSerializer.

Lastly, I switched the the methods from 'GET' methods to 'POST' methods, wrote a bit of code using WebRequest / WebResponse with the same result. Now I have read some posts talking about using the XmlSerializer on the client side to send the data to the service but that defeats the purpose of this service. While I am using .NET to write the service it is likely that PHP or classic ASP scripts will be connecting to this service and they, obviously, do not have access to the XmlSerializer.

所以我的百万美元问题是:是否可以将原始"XML 请求发送到在 WCF 中开发的 RESTful Web 服务,如果可以,如何发送?

So my million dollar question is this: Is it possible to send a 'raw' XML request to a RESTful webservice developed in WCF and, if so, how?

附言进出服务的 XML 不基于任何有形对象,它只是我创建的用于此服务的结构.传入的 XML 通过 XPath 进行解析,将值放入更大的 XML 字符串中,然后传递给外部 API.该 API 的结果经过处理,然后由我的 RESTful 服务返回.

P.S. The XML coming into and going out of the service is not based on any tangible object it is simply the structure I created to use with this service. The XML coming in is parsed via XPath, the values are placed into a larger XML string, and passed along to an external API. The results from that API are processed and then returned by my RESTful service.

任何帮助将不胜感激!

推荐答案

Brett,感谢您提供的代码.不幸的是,我在这个线程中找到了它:涉及复杂类型的 WCF Rest 参数 并且有在此发布之前尝试过.

Brett, thanks for the bit of code. Unfortunately I found it in this thread: WCF Rest parameters involving complex types and had attempted it prior to this posting.

无论如何,我已经解决了这个问题.现在我想说我有一个完整的尤里卡"时刻,一切都刚刚好,但事实是我刚刚开始在谷歌上扔首字母缩略词,其中一个 SERP 将我带到了这个链接:http://blogs.msdn.com/pedram/archive/2008/04/21/how-to-consume-rest-services-with-wcf.aspx

In any event, I have solved this problem. Now I would love to say that I had a complete 'Eureka' moment and everything just came together but the fact of the matter is I just started throwing acronymns at Google and one of the SERPs led me to this link: 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 服务.在示例中,作者提供了几种不同的模板,其中一些使用典型的查询字符串参数式模板,而另一些则不使用.无论出于何种原因,我都选择了没有典型查询字符串参数的模板,如我的原始帖子中所示.所以我稍微修改了我的代码并想出了这个:

The link itself doesn't directly address the question at hand but it made me think differently about how I was putting together my URI templates. I had read this MSDN article http://msdn.microsoft.com/en-us/library/dd203052.aspx on how to put together a RESTful service. In the example the author provides several different templatesL some which utilize a typical querystring parameter-esque template and some that don't. For whatever reason I choose the template that was void of a typical querystring parameter as can be seen in my original post. So I modified my code a bit and came up with this:

[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= 和中提琴,一切都很顺利!

Notice that the URI template is the only thing that changed; changing from "/method1/{data}" to "/method1/?xml={data}. I then navigated to http://myuri.com/service.svc/method1/?xml= and viola, everything worked beautifully!

这也是 POST 的问题.无论出于何种原因,在内容正文中传递 XML,即使作为键/值对,也会导致 400 错误.使用上面显示的完全相同的 URI 模板,我打开了 Fiddler,执行了一个 POST,结果是 200 OK.

This also was the problem with POST. For whatever reason passing the XML along in the content body, even as a key/value pair, was causing the the 400 error. Using the exact same URI template shown above I opened Fiddler, executed a POST, and the result was 200 OK.

感谢大家的帮助.

这篇关于RESTful WCF 服务在发送“原始"代码时返回 400 代码XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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