none
download an image POSTed By multipart form-data RRS feed

  • Question

  • Hi,

    I need to download an image in my WCF Service. I am getting an image from another “aspx” page by client POSTing the page using multipart form-data.

     

    Posting aspx page

     

    <form id="form2" action="http://localhost:8080/services/cardservices/card/image" method="post" enctype="multipart/form-data">

            <input type="file" id="Text1" />

            <!-- <input type="text" id="Text2" name="shippingaddress.lastname" />

            <input type="submit" />

          </form>

     

     

    I think I supposed to get the image as a stream.

    Below is my C# code

     

    [OperationContract]

            [WebInvoke(Method = "POST", UriTemplate = "/card/image")]

            Activation TestImage(Stream stream);

     

     

    public Activation TestImage(Stream stream)

            {

                MemoryStream ms = (MemoryStream)stream;

     

                System.Drawing.Bitmap b = (System.Drawing.Bitmap)Image.FromStream(ms);

                b.Save(@"c:\two.bmp");

            }

     

    In my app config the base uri is http://localhost:8080/services/cardservices

     

     

     

     

    Do I need to set any configuration setting to achieve this functionality?

     

    Please help me to figure out.

     

     

    Thanks in advance

     

    Regards

    Umeshnath

     

     

     

    Tuesday, August 11, 2009 5:26 PM

Answers

  • Stream is the right way to go for this scenario. You still need, however, to decode the multipart/form-data encoded request to extract the file - the file that was uploaded is only part of the request (more information about the format at http://www.ietf.org/rfc/rfc2045.txt and http://www.ietf.org/rfc/rfc2046.txt). The code below shows a simple way to decode it, you'll need to update it to your needs.

        //sending image via HTML
        public class Post_7a387bc1_fb7a_4c7b_a17f_19fc167f9621
        {
            [ServiceContract(Namespace = "")]
            public interface ITest
            {
                [OperationContract]
                [WebInvoke(Method = "POST", UriTemplate = "/card/image")]
                Stream TestImage(Stream stream);
            }
    
            [ServiceBehavior(IncludeExceptionDetailInFaults = true, Namespace = "")]
            public class Service : ITest
            {
                public Stream TestImage(Stream stream)
                {
                    StringBuilder sb = new StringBuilder();
                    try
                    {
                        string contentType = WebOperationContext.Current.IncomingRequest.ContentType;
                        if (!contentType.StartsWith("multipart/form-data; boundary="))
                        {
                            throw new ArgumentException("Error, invalid Content-Type: " + contentType);
                        }
                        MemoryStream ms = new MemoryStream();
                        byte[] buffer = new byte[1000];
                        int bytesRead = 0;
                        do
                        {
                            bytesRead = stream.Read(buffer, 0, buffer.Length);
                            ms.Write(buffer, 0, bytesRead);
                        } while (bytesRead > 0);
                        sb.AppendLine("Request size: " + ms.Position);
                        string boundary = contentType.Substring("multipart/form-data; boundary=".Length);
                        byte[] boundaryBytes = Encoding.ASCII.GetBytes(boundary);
                        byte[] requestBytes = ms.ToArray();
                        int index = 0;
                        Debug.Assert(requestBytes[0] == (byte)'-', "First char is '-'");
                        Debug.Assert(requestBytes[1] == (byte)'-', "Second char is '-'");
                        index = 2;
                        string boundaryLine = ReadLine(requestBytes, ref index);
                        Debug.Assert(boundaryLine == boundary, "First line is boundary");
                        string contentDispositionLine = ReadLine(requestBytes, ref index);
                        Debug.Assert(contentDispositionLine.StartsWith("Content-Disposition"), "First line of part is Content-Disposition");
                        sb.AppendLine(contentDispositionLine);
                        string contentTypeLine = ReadLine(requestBytes, ref index);
                        Debug.Assert(contentTypeLine.StartsWith("Content-Type"), "Second line of part is Content-Type");
                        sb.AppendLine(contentTypeLine);
                        string emptyLine = ReadLine(requestBytes, ref index);
                        Debug.Assert(emptyLine == "", "Third line is empty");
                        byte[] file = new byte[requestBytes.Length - index - "\r\n--".Length - boundaryBytes.Length - "--\r\n".Length];
                        Array.Copy(requestBytes, index, file, 0, file.Length);
                        File.WriteAllBytes(@"C:\temp\a.txt", file);
                        sb.AppendLine("File saved to a.txt, len = " + file.Length);
                    }
                    catch (Exception e)
                    {
                        sb.AppendFormat("{0}: {1}", e.GetType().FullName, e.Message);
                        sb.AppendLine();
                    }
                    WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
                    return new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString()));
                }
                string ReadLine(byte[] buffer, ref int index)
                {
                    StringBuilder sb = new StringBuilder();
                    while (index < buffer.Length - 1 && buffer[index] != 0x0D && buffer[index] != 0x0A)
                    {
                        sb.Append((char)buffer[index]);
                        index++;
                    }
                    index += 2;
                    return sb.ToString();
                }
            }
        }
    
    Wednesday, August 12, 2009 4:21 AM