How to resolve file corruption after upload through WCF Service.

Recently I Implemented a WCF  Service to upload files. Implementation was fine and even file save to given location successfully, but  when I try to open these files I got error messages saying that the file is not encoded properly or file is too large to open. After searching I got a sample code to overcome that issue.
You can check original Implementation in here http://multipartparser.codeplex.com/. Thanks Anthony for awesome code implementation.  



1. Multipart Parser Code


   /// <summary>  
   /// This class will validation binary stream and remove unwanted characters  
   /// </summary>  
   public class MultipartParser  
   {  
     #region Properties  
     /// <summary>  
     /// Get Status of the Parser  
     /// </summary>  
     public bool Success  
     {  
       get;  
       private set;  
     }  
     /// <summary>  
     /// Content Type  
     /// </summary>  
     public string ContentType  
     {  
       get;  
       private set;  
     }  
     /// <summary>  
     /// File Name of Binary stream  
     /// </summary>  
     public string Filename  
     {  
       get;  
       private set;  
     }  
     /// <summary>  
     /// Original file content of the stream  
     /// </summary>  
     public byte[] FileContents  
     {  
       get;  
       private set;  
     }  
     #endregion  
     #region Constructor Declaration  
     /// <summary>  
     /// Constructor which pass stream UTF8 encoding  
     /// </summary>  
     /// <param name="stream"></param>  
     public MultipartParser(Stream stream)  
     {  
       this.Parse(stream, Encoding.UTF8);  
     }  
     /// <summary>  
     /// Constructor which stream and encoding  
     /// </summary>  
     /// <param name="stream"></param>  
     /// <param name="encoding"></param>  
     public MultipartParser(Stream stream, Encoding encoding)  
     {  
       this.Parse(stream, encoding);  
     }  
     #endregion  
     #region Private Methods  
     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);  
         }  
       }  
     }  
     #endregion  
   }  

2. How to use Parser in code  


 public string Upload(Stream stream)  
 {  
   MultipartParser parser = new MultipartParser(stream);  
   if(parser.Success)  
   {  
     // Save the file  
     SaveFile(parser.Filename, parser.ContentType, parser.FileContents);  
   }  
   else  
   {  
     throw new WebException(System.Net.HttpStatusCode.UnsupportedMediaType, "The posted file was not recognised.");  
   }  
 }  

Comments

Popular posts from this blog

Deep dive into OpenXML Part 1

Deep dive into OpenXML Part 2

Convert XML data to dynamic (ExpandoObject) Object