使用流进行最简单的 RESTful WCF 服务调用
我想创建一个具有以下属性的 Web 服务:
- 它使用 WCF 和 .NET 4.0
- 它托管在 IIS7 中
- 它是 RESTful
- 可以保留收集和处理 WebFaultException 等的默认输出行为
- 它有一个调用
- 吃掉潜在巨大二进制文件的赤裸裸的 HTTP POST(最好不要保存在内存中!)
- 接受 Stream 作为输入
- 输出流
- 使用 UriTemplate 进行匹配(很快就会有更多调用)
- 希望流完全是原始的,并且不让 IIS 或 WCF 尝试通过以任何方式处理内容类型来实现智能
问题是 IIS 和/或 WCF 不断干扰 Content-Type,
415 Cannot process the message because the content type '...' was not the expected type 'text/xml; charset=utf-8'
无论如何都 坚持返回内容类型是。你能发现我在下面犯的任何错误吗?
[ServiceContract]
public interface IRenderService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/render", BodyStyle = WebMessageBodyStyle.Bare)]
Stream Render(Stream input);
}
使用 Web.config 中的以下片段:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="500000000" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding
name="FileStreamConfiguration"
transferMode="Streamed"
maxReceivedMessageSize="500000000"
maxBufferSize="500000000"
openTimeout="00:25:00"
closeTimeout="00:25:00"
sendTimeout="00:25:00"
receiveTimeout="00:25:00" />
</webHttpBinding>
</bindings>
<services>
<service name="RenderService" behaviorConfiguration="RenderServiceBehavior">
<endpoint address="" binding="webHttpBinding" contract="RenderServer.IRenderService" bindingConfiguration="FileStreamConfiguration" behaviorConfiguration="RenderEndpointBehaviour" >
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RenderServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RenderEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
我希望始终获取 HTTP POST 正文的原始内容,并在我认为必要时手动从 WebOperationContext.Current.IncomingRequest
获取标头,以及 IIS/WCF除了解析请求并将其发送到我的代码之外,应该完全忽略请求的所有方面。我将使用 WebOperationContext.Current.OutgoingResponse 来设置我认为合适的输出的各个方面,也可以手动设置。
I want to make a web service with the following properties:
- It uses WCF and .NET 4.0
- It is hosted in IIS7
- It is RESTful
- It's okay to keep the default output behaviour of collecting and handling WebFaultExceptions etc
- It has a single call that
- eats naked HTTP POST of potentially huge binary files (should preferably not be kept in memory!)
- accepts a Stream as an input
- outputs a Stream
- uses an UriTemplate for matching (there will be more calls soon)
- wants the streams to be completely raw and NOT have IIS or WCF try to be smart by handling the content type in any way
The problem is that IIS and/or WCF keep interfering regarding the Content-Type, insisting on returning
415 Cannot process the message because the content type '...' was not the expected type 'text/xml; charset=utf-8'
no matter what the content type was. Can you spot any errors I have made below?
[ServiceContract]
public interface IRenderService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/render", BodyStyle = WebMessageBodyStyle.Bare)]
Stream Render(Stream input);
}
With the following snippets from Web.config:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="500000000" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding
name="FileStreamConfiguration"
transferMode="Streamed"
maxReceivedMessageSize="500000000"
maxBufferSize="500000000"
openTimeout="00:25:00"
closeTimeout="00:25:00"
sendTimeout="00:25:00"
receiveTimeout="00:25:00" />
</webHttpBinding>
</bindings>
<services>
<service name="RenderService" behaviorConfiguration="RenderServiceBehavior">
<endpoint address="" binding="webHttpBinding" contract="RenderServer.IRenderService" bindingConfiguration="FileStreamConfiguration" behaviorConfiguration="RenderEndpointBehaviour" >
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RenderServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RenderEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I want to always get the raw contents of the HTTP POST body, and fetch headers from WebOperationContext.Current.IncomingRequest
manually if I deem that necessary, and IIS/WCF should completely ignore all aspects of the request besides parsing it and sending it to my code. I'll use WebOperationContext.Current.OutgoingResponse
to set aspects of the output as I see fit, also manually.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用新的 WCF Web API 库可以轻松实现这一点。请参阅 http://wcf.codeplex.com 我的博客上有一个示例,一旦通电我将发布该示例返回:-)
界面如下所示,
This is so easy to do with the new WCF Web API library. See http://wcf.codeplex.com I have a sample on my blog which I will post once the power comes back on :-)
The interface looks like this,