带有流的WCF Rest Webservice

问题描述 投票:8回答:2

我很感兴趣地阅读了以下帖子,因为它是我所遇到问题的精确复制(并让我发疯了)“要使操作UploadFile中的请求成为流,该操作必须具有一个类型为Stream的单个参数。” -http://social.msdn.microsoft.com/Forums/en/wcf/thread/80cd26eb-b7a6-4db6-9e6e-ba65b3095267

我几乎遵循了我找到的所有代码/示例,但仍然无法解决此错误-http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx

[我想实现的是使用标准文件名/流参数从android设备发布图像(jpeg / png)。很可能是我配置错误,误解或遗漏了一些简单的事情,但是我需要有一个概念验证的解决方案。

 public interface IConXServer
    {
    [OperationContract]
    [WebInvoke(UriTemplate = "UploadImage({fileName})", Method="POST")]
    void UploadImage(string fileName, Stream imageStream);
    }

 public class ConXWCFServer : IConXServer
    {
    public void UploadImage(string fileName, Stream imageStream)
       {
       //implement image save
       }
    }

web.config设置->

<standardEndpoints>
   <webHttpEndpoint>
       <standardEndpoint name="webHttpEndpoint" helpEnabled="false"/>
   </webHttpEndpoint>
</standardEndpoints>

<bindings>
    <webHttpBinding>
        <binding name="webHttpBinding" transferMode="Streamed"/>
    </webHttpBinding>
</bindings>

<behaviors>
    <endpointBehaviors>
        <behavior name="webHttpBehavior">
            <webHttp/>
        </behavior>
    </endpointBehaviors> 
    <serviceBehaviors>
        <behavior>
            <serviceMetadata httpGetEnabled="false"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
            <serviceThrottling maxConcurrentCalls="2147483647"  maxConcurrentSessions="2147483647"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

使用vs2010和IIS Express。如果我注释掉上面的方法,其他所有方法都可以工作并返回数据以及wsdl查询

感谢和事先感谢内核

wcf rest stream
2个回答
13
投票
[您提到WSDL,这使我相信您在尝试浏览服务的元数据端点时遇到错误。因此,首先,WSDL和REST不能一起使用,因此您不应该期望它完全用于REST接口。忘记服务元数据的概念甚至存在于REST世界中。

下一个REST的webHttpBinding确实支持Stream主体参数前面的参数,而其他绑定则不支持,并且必须有单个Stream参数或带有标头和流主体的消息协定。

因此,最后,问题根本就没有REST webHttpBinding,我敢打赌它工作得很好。如果不是这样,我绝对会感到震惊,因为您没有做任何该部门不应该做的事情。问题是您期望元数据终结点为您定义的服务协定生成WSDL,而只是不支持。


0
投票
我这样做是可行的。

将工厂类添加到Web服务(WcfService2.ServiceFactory)

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService2.Service1" CodeBehind="Service1.svc.cs" Factory="WcfService2.ServiceFactory" %>

我的界面:

public interface IService1 { [OperationContract] [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UploadFile/{fileName}")] void UploadFile(string fileName, Stream fileContent); }

我的方法:

public void UploadFile(string fileName, Stream fileContent) { var pathfile = "\\\\SERVER\\TravelsRequestFiles"; using (var fileStream = new FileStream(string.Concat(pathfile, "\\", fileName), FileMode.Create, FileAccess.Write)) { fileContent.CopyTo(fileStream); } }

我的FactoryClass:

public class ServiceFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { return new MyServiceHost(serviceType, baseAddresses); } class MyServiceHost : ServiceHost { public MyServiceHost(Type serviceType, Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void InitializeRuntime() { ServiceEndpoint endpoint = this.Description.Endpoints[0]; endpoint.Behaviors.Add(new EndpointBehaviors()); base.InitializeRuntime(); } } }

我添加了一个EndpointBehaviors类,在找到操作UploadFile并删除其DataContractSerializerOperationBehavior之后,

然后可以正常工作!

public class EndpointBehaviors: IEndpointBehavior { public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { ContractDescription cd = endpoint.Contract; foreach (DispatchOperation objDispatchOperation in endpointDispatcher.DispatchRuntime.Operations) { if (objDispatchOperation.Name.Equals("UploadFile")) { OperationDescription myOperationDescription = cd.Operations.Find("UploadFile"); DataContractSerializerOperationBehavior serializerBehavior = myOperationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>(); myOperationDescription.Behaviors.Remove(serializerBehavior); } } } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void Validate(ServiceEndpoint endpoint) { BindingElementCollection elements = endpoint.Binding.CreateBindingElements(); WebMessageEncodingBindingElement webEncoder = elements.Find<WebMessageEncodingBindingElement>(); if (webEncoder == null) { throw new InvalidOperationException("This behavior must be used in an endpoint with the WebHttpBinding (or a custom binding with the WebMessageEncodingBindingElement)."); } } }
© www.soinside.com 2019 - 2024. All rights reserved.