Could not upload Image to WCF Rest service

I am creating a WCF Rest Service to Upload Images from Mobile application. but i am getting The remote server returned an error: (400) Bad Request. can any one point me what i have done wrong. Following are my Definitions :

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/PostImage",Method ="POST")]

 PublicMessage PostImage(Upload obj);

[DataContract]
    public class Upload
    {
        [DataMember]
        public Stream File { get; set; }
    }

Service Definition :

public PublicMessage PostImage(Upload obj)
    {
        byte[] buffer = StreamToByte(obj.File);   //Function to convert the stream to byte array
     FileStream fs = new FileStream(@"D:\ShopMonkeyApp\Desert.jpg", FileMode.Create, FileAccess.ReadWrite);
        BinaryWriter bw = new BinaryWriter(fs);

        bw.Write(buffer);

        bw.Close();

        return new PublicMessage { Message = "Recieved the image on server" };
    }

Client Application :

string filePath = @"D:\ShopMonkeyApp\Desert.jpg";

        string url = "http://localhost:50268/shopmonkey.svc/PostImage/"; // Service Hosted in IIS

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        request.Accept = "text/xml";

        request.Method = "POST";

        request.ContentType = "image/jpeg";

        using (Stream fileStream = File.OpenRead(filePath))

        using (Stream requestStream = request.GetRequestStream())
        {

            int bufferSize = 1024;

            byte[] buffer = new byte[bufferSize];

            int byteCount = 0;

            while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
            {

                requestStream.Write(buffer, 0, byteCount);

            }

        }

        string result;

        using (WebResponse response = request.GetResponse())

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {

            result = reader.ReadToEnd();

        }

        Console.WriteLine(result);

Web Config :

 <system.serviceModel>
        <services>
      <service name="ShopMonkey.ShopMonkey" behaviorConfiguration="ServiceBehaviour">
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address ="" binding="webHttpBinding" contract="ShopMonkey.IShopMonkey" behaviorConfiguration="web">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.behaviorConfiguration="web"
          -->
        </endpoint>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
          <dataContractSerializer maxItemsInObjectGraph="10000000"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

Thanks

Vijay

Answers


Increasing the message queue length in web.config solves my issue.

<webHttpBinding>
        <binding name="streamWebHttpbinding" transferMode="Streamed"  maxReceivedMessageSize="1000000000000" receiveTimeout="01:00:00" sendTimeout="01:00:00" />
      </webHttpBinding>

Thanks to all


If you dont have any other properties on the Upload class then change the WCF service method to have a Stream param rather than wrapping it in a class as below:

[OperationContract]
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")]
PublicMessage PostImage(Stream obj);

Then you can use the WebClient class to upload a file directly as shown below:

var c = new System.Net.WebClient();
c.OpenWrite(string.Concat("http://localhost:50268/shopmonkey.svc", "/PostImage"), "POST");
c.Headers[HttpRequestHeader.ContentType] = "image/jpeg";            
return c.UploadFile(string.Concat(serviceBaseUrl, resourceUrl), filePath);

Also refer to this link.

UPDATE :

Please find the sample to get your code working below:

[OperationContract]
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")]
PublicMessage PostImage(Upload obj);

[DataContract]
public class Upload
{
    [DataMember]
    public MemoryStream FileContent { get; set; }
}

Now your method that implements the PostImage looks as follows:

public PublicMessage PostImage(Upload obj)
{
        byte[] buffer = new byte[obj.FileContent.Length];
        using (FileStream ms = new FileStream(@"D:\ShopMonkeyApp\Temp\Desert.jpg", FileMode.OpenOrCreate))
        {
            obj.FileContent.Position = 0;
            int read = fileInfo.Content.Read(buffer, 0, buffer.Length);
            ms.Write(buffer, 0, read);
        }

    return new PublicMessage { Message = "Recieved the image on server" };
}

Now since our server side code is complete now moving to the client side part that uploads your file to the server as below:

    private string ClientSample()
    {
            var uploadObject = new Upload();
            Image image = Image.FromFile(@"D:\ShopMonkeyApp\Desert.jpg");
            MemoryStream ms = new MemoryStream();
            uploadObject.FileContent = new MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            ms.WriteTo(uploadObject.FileContent);
            ms.Close();

        string responseMessage = null;            
        var request = WebRequest.Create(http://localhost:50268/shopmonkey.svc/PostImage) as HttpWebRequest;
        if (request != null)
        {
            request.ContentType = "application/xml";
            request.Method = method;
        }

        if(method == "POST" && requestBody != null)
        {
            byte[] requestBodyBytes;
            requestBodyBytes = ToByteArrayUsingDataContractSer<Upload>(requestBody);
            request.ContentLength = requestBodyBytes.Length;
            using (Stream postStream = request.GetRequestStream())
                postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);                    
        }

        if (request != null)
        {
            var response = request.GetResponse() as HttpWebResponse;
            if(response.StatusCode == HttpStatusCode.OK)
            {
                Stream responseStream = response.GetResponseStream();
                if (responseStream != null)
                {
                    var reader = new StreamReader(responseStream);

                    responseMessage = reader.ReadToEnd();                        
                }
            }
            else
            {   
                responseMessage = response.StatusDescription;
            }
        }
    }

    private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody)
    {
        byte[] bytes = null;
        var serializer1 = new DataContractSerializer(typeof(T));            
        var ms1 = new MemoryStream();            
        serializer1.WriteObject(ms1, requestBody);
        ms1.Position = 0;
        var reader = new StreamReader(ms1);
        bytes = ms1.ToArray();
        return bytes;            
    }

NOTE: Make sure that your Upload object both on the client and server have the same namespace and properties defined so that you avoid any deserialization issues.


Need Your Help

PHP+MYSQL: Problem with Update query

php sql mysql

I'm having problems running this query. I keep on getting the error:

Microsoft Sync Services - good solution for me?

sql-server sql-server-ce microsoft-sync-framework

We upload sales transactions from our stores to the headoffice server. At the moment, we use DTS (SQL Server Data Transformation Services), but we’re planning on replacing that with Microsoft Sync