/// <summary>
        /// Process the form values that were submitted to construct a file name.
        /// Make sure all form items come before the actual file data payload.
        /// </summary>
        public override string GetLocalFileName(HttpContentHeaders headers)
        {
            // Construct a JSON object so the Serializer will get our types for us
            var jsonBuilder = new StringBuilder("{");
            var flowMetaDictionary = new Dictionary<string, string>();
            foreach (var item in this.Contents)
            {
                var param = item.Headers.ContentDisposition.Parameters.FirstOrDefault();
                string key = param.Value.Trim('\"');
                string value = item.ReadAsStringAsync().Result;

                // Possible way to parse value as JSON:
                //MyObject myObj = JsonConvert.DeserializeObject<MyObject>(value);
                
                // Instead, we'll try to put everything into a FlowMetadata object
                jsonBuilder.AppendFormat("\"{0}\":\"{1}\",",key,value);
                flowMetaDictionary[key] = value;
            }

            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);  // remove the last ',' character
            jsonBuilder.Append("}");                        // close the json

            // Allow for dynamic properties: Adding a property to the class means you don't have to remember
            // to add it to the constructor
            var dynamicMetaData = JsonConvert.DeserializeObject<FlowMetaData>(jsonBuilder.ToString());

            // Strict properties: you have to specify each property in the constructor and handle it yourself
            var strictMetaData = new FlowMetaData(flowMetaDictionary);

            // I like the dynamic method much better, much more maintainable
            MetaData = dynamicMetaData;


            return MetaData.FlowFilename;
            
            // If you wanted to save each chunk individually and stitch it together later (bad performance in my opinion):
            //var flowChunkName = String.Format("{0}.{1}", MetaData.flowFilename, MetaData.FlowChunkNumber);
            //return flowChunkName;
        }
예제 #2
0
        /// <summary>
        /// (Thread Safe) Marks a chunk as recieved.
        /// </summary>
        private static bool RegisterSuccessfulChunk(FlowMetaData chunkMeta)
        {
            FileMetaData fileMeta;
            lock (chunkCacheLock)
            {
                fileMeta = GetFileMetaData(chunkMeta.FlowIdentifier);

                if (fileMeta == null)
                {
                    fileMeta = new FileMetaData(chunkMeta);
                    uploadChunkCache.Add(chunkMeta.FlowIdentifier, fileMeta, DefaultCacheItemPolicy());
                }

                fileMeta.RegisterChunkAsReceived(chunkMeta);
                if (fileMeta.IsComplete)
                {
                    // Since we are using a cache and memory is automatically disposed,
                    // we don't need to do this, so we won't so we can keep a record of
                    // our completed uploads.
                    //uploadChunkCache.Remove(chunkMeta.FlowIdentifier);
                }
            }
            return fileMeta.IsComplete;
        }
예제 #3
0
 public bool HasChunk(FlowMetaData flowMeta)
 {
     return ChunkArray[ChunkIndex(flowMeta.FlowChunkNumber)];
 }
예제 #4
0
 public void RegisterChunkAsReceived(FlowMetaData flowMeta)
 {
     ChunkArray[ChunkIndex(flowMeta.FlowChunkNumber)] = true;
     TotalChunksReceived++;
 }
예제 #5
0
 public FileMetaData(FlowMetaData flowMeta)
 {
     FlowMeta = flowMeta;
     ChunkArray = new bool[flowMeta.FlowTotalChunks];
     TotalChunksReceived = 0;
 }
예제 #6
0
        public static bool HasRecievedChunk(FlowMetaData chunkMeta)
        {
            var fileMeta = GetFileMetaData(chunkMeta.FlowIdentifier);

            bool wasRecieved = fileMeta != null && fileMeta.HasChunk(chunkMeta);

            return wasRecieved;
        }