1

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.

Anjan Kant
  • 4,090
  • 41
  • 39

2 Answers2

0

You shouldn't use HttpContext for getting the files in WCF. you can simply create a service with stream as input. here there is simple example: Uploading an image using WCF RESTFul service full working example

UPDATE:

try byte array instead of stream and wrapping the class like this:

public class Input
{
    [DataMember]
    public string fileName { get; set; }
    [DataMember]
    public DateTime createdDate{ get; set; }
    [DataMember]
    public DateTime modifiedDate{ get; set; }
    [DataMember]
    public byte[] fileContents { get; set; }
.
.
}

then simply write the file on disk or where ever you want like this:

public string Upload(Input input)
{
    File.WriteAllBytes(input.fileName, input.fileContents);
    return "OK";
}
Community
  • 1
  • 1
Mohammad
  • 2,724
  • 6
  • 29
  • 55
  • I already mentioned that I don't need image in binary stream, I need to save image as original mode, created by, created date, modified date etc. If I use binary stream image information will be abolished. – Anjan Kant May 15 '17 at 09:55
  • in that case you can create a service and receive all other parameters. but you didn't mention it at your question. take a look at my updated answer. – Mohammad May 15 '17 at 10:47
  • I am passing [OperationContract] [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Upload")] string Upload(Input input); – Anjan Kant May 15 '17 at 11:31
  • One question arise how we can post image in class members, input file is jpg image – Anjan Kant May 15 '17 at 11:35
  • dear @AnjanKant. its completely another question. but its simple. all you need is converting image to byte array. if your image stored in disk youc use File.ReadAllBytes. – Mohammad May 15 '17 at 12:04
0

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;
        }
    }
}
Anjan Kant
  • 4,090
  • 41
  • 39