WCF Rest Webservice with Stream

I am reading the following post with interest, as this is an exact copy of the problem I am experiencing (and driving me crazy) "For the request in the UploadFile operation to be a stream, the operation must have one parameter, the type of which is Stream". - http://social.msdn.microsoft.com/Forums/en/wcf/thread/80cd26eb-b7a6-4db6-9e6e-ba65b3095267

I followed quite a lot of all the codes / examples I found and still cannot get around this error - http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model- receiving-arbitrary-data.aspx

All I would like to achieve is to send an image (jpeg / png) from an Android device using standard file / stream name parameters. Most likely, this is something simple that I misconfigured, misunderstood or forgot, but I need to have a solution to prove the concept.

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

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

Using vs2010 and IIS Express. If I comment on the method described above, all other methods work and return data, as well as the wsdl request

Hello and thanks in advance kern

+8
rest stream wcf
source share
2 answers

You mention WSDL, which makes me think that you are getting an error when trying to view the metadata endpoint for a service. So, firstly, WSDL and REST do not go together, so you should not use it at all for the REST interface. Forget the concept of service metadata, even existing in the REST world.

Further So far, it is true that REST webHttpBinding supports parameters before the body Stream parameter, other bindings do not and there must be either one Stream parameter or a contract with headers and body of the stream.

So, in the end, the problem is not that REST has webHttpBinding in general, I'm sure everything works fine. If this is not so, I would be absolutely shocked, because you are not doing anything that should not work in this department. The problem is that you expect the metadata endpoint to generate WSDL for the service contract that you defined and which is simply not supported.

+13
source share

I do it this way and it works.

Add factory class to web service

My interface:

 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); } 

My method:

 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); } } 

my 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(); } } } 

I added the EndpointBehaviors class for which it finds the UploadFile operation and removes its DataContractSerializerOperationBehavior , and then it works!

 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)."); } } } 
0
source share

All Articles