3

I am trying to save an image in a database through a WCF. This is my code.

public void saveImage(Stream stream, string size)
    {
        //int intsize = Convert.ToInt32(size);
        byte[] buffer = new byte[10000];
        int bytesRead, totalBytesRead = 0;
        string encodedData = "";

        do
        {
            bytesRead = stream.Read(buffer, 0, buffer.Length);
            encodedData = encodedData + Convert.ToBase64String(buffer,
                                       Base64FormattingOptions.InsertLineBreaks);
            totalBytesRead += bytesRead;
        } while (bytesRead > 0);

And this is the contract.

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "SaveImage/{size}")]
    void saveImage(Stream stream, string size);

And finally this is part of my config file

<system.serviceModel>
<services>
  <service behaviorConfiguration="RestServiceBehavior" name="ABBStreamService.ABBConnectStreamWCF">
    <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="webHttpBinding" contract="ABBStreamService.IABBConnectStreamWCF" />
  </service>
</services>
<bindings>
  <webHttpBinding>
    <binding name="webHttpBinding" transferMode="Streamed" maxReceivedMessageSize="2147483647" maxBufferSize="10485760" closeTimeout="00:01:00" openTimeout="00:01:00"
             receiveTimeout="00:10:00" sendTimeout="00:01:00">
      <readerQuotas maxStringContentLength="2147483647" maxArrayLength="1000000" />
    </binding>
  </webHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="RestServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="web">
      <webHttp />
    </behavior>
  </endpointBehaviors>
</behaviors>
<protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>    
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

When i try to run the service with only the Stream as parameter, it works. But when i try to add another parameter it fails.

user1860935
  • 83
  • 1
  • 2
  • 6
  • Fails how? what is the error, what is the parameter? – crthompson Jan 05 '14 at 18:17
  • Sorry maybe my description was incomplete. My service is working when the saveImage method has only the Stream as a parameter. I get this error "The server was unable to process the request due to an internal error." – user1860935 Jan 05 '14 at 18:30
  • That error is given to the client to hide the real error that could be a security risk. If you debug the service (with logging or debugging) you should find the actual error. Look at InnerException's as well – crthompson Jan 05 '14 at 18:33
  • You can't have multiple parameters in a streamed operation. "Operations that occur across a streamed transport can have a contract with at most one input or output parameter." (http://msdn.microsoft.com/en-us/library/ms731913%28v=vs.110%29.aspx) – Tim Jan 05 '14 at 18:35
  • This article should help you: http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP – Dmitry Razumikhin Jan 05 '14 at 18:38

2 Answers2

0

You could add a header to the request then read that in the service.

 //Javascript to set the header
 var xhr = new XMLHttpRequest();
 var image = document.getElementById("yourFileInput").files[0];
 xhr.setRequestHeader('size', image.size);

 //C# in your service method to read the size header
 IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
 var headers = request.Headers;
 string size = headers["size"];
Dan Leksell
  • 510
  • 5
  • 6
0

I know i am late but this will be useful for searchers. Send your file in body and rest of parameters in header of request.

following sample code is tested in Post man and working like a charm.

your Interface

[WebInvoke(
        Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "PostImage")]
        void PostImage(Stream stream);

.svc Method:

public void PostImage(Stream stream)  
        {
            // get image from stream and implement your logic

            var headers = OperationContext.Current.IncomingMessageProperties["httpRequest"];
            // other parameters will be accessible here e.g image name etc
            var imgname = ((HttpRequestMessageProperty)headers).Headers["imgname"];


        }

for reference please see this link

Waqas
  • 847
  • 4
  • 14
  • 36