Search code examples
c#wcfwcf-data-serviceswcf-binding.net-framework-version

HttpContext.Current.Request.Files Always Null in WCF [save image with original metadata]


I'm trying to upload images using form data using WCF. I am writing below code to get images in WCF code, but it is always sending me null value but I'm pretty able to receive image in bytes stream. My main objective is save image with original image metadata.

 HttpPostedFile file = HttpContext.Current.Request.Files["media1"];

To get done this functionality, I have already added:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1 : IService1

In Web.Config:

   <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

Note: I want to save image with metadata.


Solution

  • Finally, My issue resolved with the help of given link

    Me written below code in my implementation, I just downloaded MultipartParser.cs class from the codeplex, moreover I am pasting here complete class because Codeplex is going down after some time.

    public string Upload(Stream data)
    {
        MultipartParser parser = new MultipartParser(data);
    
        if (parser.Success)
        {
                 // Save the file
                string filename = parser.Filename;
                string contentType = parser.ContentType;
                byte[] filecontent = parser.FileContents;
                File.WriteAllBytes(@"C:\test1.jpg", filecontent);
             }
        return "OK";
    }
    

    MultipartParser.cs Class:

    using System;
    using System.IO;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    /// <summary>
    /// MultipartParser http://multipartparser.codeplex.com
    /// Reads a multipart form data stream and returns the filename, content type and contents as a stream.
    /// 2009 Anthony Super http://antscode.blogspot.com
    /// </summary>
    namespace WcfService1
    {
        public class MultipartParser
        {
            public MultipartParser(Stream stream)
            {   
                this.Parse(stream, Encoding.UTF8);
            }
    
            public MultipartParser(Stream stream, Encoding encoding)
            {
                this.Parse(stream, encoding);
            }
    
            public static async Task ParseFiles(Stream data, string contentType, Action<string, Stream> fileProcessor)
            {
                var streamContent = new StreamContent(data);
                streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
    
                var provider = await streamContent.ReadAsMultipartAsync();
    
                foreach (var httpContent in provider.Contents)
                {
                    var fileName = httpContent.Headers.ContentDisposition.FileName;
                    if (string.IsNullOrWhiteSpace(fileName))
                    {
                        continue;
                    }
    
                    using (Stream fileContents = await httpContent.ReadAsStreamAsync())
                    {
                        fileProcessor(fileName, fileContents);
                    }
                }
            }
    
            private void Parse(Stream stream, Encoding encoding)
            {
                this.Success = false;
    
                // Read the stream into a byte array
                byte[] data = ToByteArray(stream);
    
                // Copy to a string for header parsing
                string content = encoding.GetString(data);
    
                // The first line should contain the delimiter
                int delimiterEndIndex = content.IndexOf("\r\n");
    
                if (delimiterEndIndex > -1)
                {
                    string delimiter = content.Substring(0, content.IndexOf("\r\n"));
    
                    // Look for Content-Type
                    Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)");
                    Match contentTypeMatch = re.Match(content);
    
                    // Look for filename
                    re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
                    Match filenameMatch = re.Match(content);
    
                    // Did we find the required values?
                    if (contentTypeMatch.Success && filenameMatch.Success)
                    {
                        // Set properties
                        this.ContentType = contentTypeMatch.Value.Trim();
                        this.Filename = filenameMatch.Value.Trim();
    
                        // Get the start & end indexes of the file contents
                        int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length;
    
                        byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
                        int endIndex = IndexOf(data, delimiterBytes, startIndex);
    
                        int contentLength = endIndex - startIndex;
    
                        // Extract the file contents from the byte array
                        byte[] fileData = new byte[contentLength];
    
                        Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
    
                        this.FileContents = fileData;
                        this.Success = true;
                    }
                }
            }
    
            private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)
            {
                int index = 0;
                int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
    
                if (startPos != -1)
                {
                    while ((startPos + index) < searchWithin.Length)
                    {
                        if (searchWithin[startPos + index] == serachFor[index])
                        {
                            index++;
                            if (index == serachFor.Length)
                            {
                                return startPos;
                            }
                        }
                        else
                        {
                            startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
                            if (startPos == -1)
                            {
                                return -1;
                            }
                            index = 0;
                        }
                    }
                }
    
                return -1;
            }
    
            private byte[] ToByteArray(Stream stream)
            {
                byte[] buffer = new byte[32768];
                using (MemoryStream ms = new MemoryStream())
                {
                    while (true)
                    {
                        int read = stream.Read(buffer, 0, buffer.Length);
                        if (read <= 0)
                            return ms.ToArray();
                        ms.Write(buffer, 0, read);
                    }
                }
            }
    
            public bool Success
            {
                get;
                private set;
            }
    
            public string ContentType
            {
                get;
                private set;
            }
    
            public string Filename
            {
                get;
                private set;
            }
    
            public byte[] FileContents
            {
                get;
                private set;
            }
        }
    }