/// <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; }
/// <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; }
public bool HasChunk(FlowMetaData flowMeta) { return ChunkArray[ChunkIndex(flowMeta.FlowChunkNumber)]; }
public void RegisterChunkAsReceived(FlowMetaData flowMeta) { ChunkArray[ChunkIndex(flowMeta.FlowChunkNumber)] = true; TotalChunksReceived++; }
public FileMetaData(FlowMetaData flowMeta) { FlowMeta = flowMeta; ChunkArray = new bool[flowMeta.FlowTotalChunks]; TotalChunksReceived = 0; }
public static bool HasRecievedChunk(FlowMetaData chunkMeta) { var fileMeta = GetFileMetaData(chunkMeta.FlowIdentifier); bool wasRecieved = fileMeta != null && fileMeta.HasChunk(chunkMeta); return wasRecieved; }