Wednesday, 25 December 2013

how to upload large file in chunks in MVC Api

Note : if IOs app want to use it,they need to do code to upload chunk of file.logic for that is as below:
and in c# you can use it to test by yourself by creating function in api controller with the below logic.

        [HttpPost]
        [ActionName("UploadVideo1")] (when local testing is needed)
        public string UploadVideo1(Pro_VideoMaster_Api1 video)
        {
            //Dictionary<string, dynamic> dicto;
            string FilePath=video.File;
            int Offset = 0; // starting offset.
            int ChunkSize = 65536;

            byte[] Buffer = new byte[ChunkSize];
            //opening the file for read.
            FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
            //creating the ServiceSoapClient which will allow to connect to the service.
            //WSservice.ServiceSoapClient soap_client = new WSservice.ServiceSoapClient();
            try
            {
                long FileSize = new FileInfo(FilePath).Length; // File size of file being uploaded.
                // reading the file.
                fs.Position = Offset;
                int BytesRead = 0;

                while (Offset != FileSize) // continue uploading the file chunks until offset = file size.
                {
                    BytesRead = fs.Read(Buffer, 0, ChunkSize); // read the next chunk
                    // (if it exists) into the buffer.
                    // the while loop will terminate if there is nothing left to read
                    // check if this is the last chunk and resize the buffer as needed
                    // to avoid sending a mostly empty buffer
                    // (could be 10Mb of 000000000000s in a large chunk)
                    if (BytesRead != Buffer.Length)
                    {
                        ChunkSize = BytesRead;
                        byte[] TrimmedBuffer = new byte[BytesRead];
                        Array.Copy(Buffer, TrimmedBuffer, BytesRead);
                        Buffer = TrimmedBuffer; // the trimmed buffer should become the new 'buffer'
                    }
                    // send this chunk to the server. it is sent as a byte[] parameter,
                    // but the client and server have been configured to encode byte[] using MTOM.
                    bool ChunkAppened = new VideoRepository().UploadFile(Path.GetFileName(FilePath), Buffer, Offset);
                    if (!ChunkAppened)
                    {
                        break;
                    }

                    // Offset is only updated AFTER a successful send of the bytes.
                    Offset += BytesRead; // save the offset position for resume
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                fs.Close();
            }

            return "Success";

        }


Function in Api Controller : (when consumed by IOS app)

        [HttpPost]
        [ActionName("UploadVideo")]
        public dynamic UploadVideo(Pro_VideoMaster_Api video)
        {
            Dictionary<string, dynamic> dicto;
           // byte[] b = Encoding.ASCII.GetBytes(video.buffer);
            long offset =  Convert.ToInt64(video.Offset);
            var IsSuccess = new VideoRepository().UploadFile(video.FileName, video.buffer, offset);

            dicto = new Dictionary<string, dynamic>();
            dicto.Add("Result", IsSuccess);
            dicto.Add("Message", (IsSuccess == true ? "Success" : "Failure"));

            return dicto;

        }

Function in Repository :

public bool UploadFile(string FileName, byte[] buffer, long Offset)
        {
            bool retVal = false;
            try
            {
                // setting the file location to be saved in the server.
                // reading from the web.config file
                string FilePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["upload_path"]);
                FilePath = Path.Combine(FilePath, FileName);

                if (Offset == 0) // new file, create an empty file
                {
                    //if(File.Exists(FilePath )){
                    File.Create(FilePath).Close();
                }
                // open a file stream and write the buffer.
                // Don't open with FileMode.Append because the transfer may wish to
                // start a different point
                using (FileStream fs = new FileStream(FilePath, FileMode.Open,FileAccess.ReadWrite, FileShare.Read))
                {
                    fs.Seek(Offset, SeekOrigin.Begin);
                    fs.Write(buffer, 0, buffer.Length);
                }
                retVal = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            { objDBHelper = null; }

            return retVal;
        }

No comments:

Post a Comment