7

I need a good example on WCF Streaming File Transfer.

I have found several and tried them but the posts are old and I am wokding on .net 4 and IIS 7 so there are some problems.

Can you gives me a good and up-to-date example on that.

2
  • What do you mean by streaming? Are you trying to use WCF for media content (I.E., videos or MP3s) or do you mean sending binary information back to a client? Commented Jul 28, 2011 at 11:55
  • basically I am trying to upload files to my server over http. Commented Jul 28, 2011 at 11:56

1 Answer 1

7

The following answers detail using a few techniques for a posting binary data to a restful service.

The following code is a sample of how you could write a RESTful WCF service and is by no means complete but does give you an indication on where you could start.

Sample Service, note that this is NOT production ready code.

[ServiceContract] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] public class FileService { private IncomingWebRequestContext m_Request; private OutgoingWebResponseContext m_Response; [WebGet(UriTemplate = "{appName}/{id}?action={action}")] public Stream GetFile(string appName, string id, string action) { var repository = new FileRepository(); var response = WebOperationContext.Current.OutgoingResponse; var result = repository.GetById(int.Parse(id)); if (action != null && action.Equals("download", StringComparison.InvariantCultureIgnoreCase)) { response.Headers.Add("Content-Disposition", string.Format("attachment; filename={0}", result.Name)); } response.Headers.Add(HttpResponseHeader.ContentType, result.ContentType); response.Headers.Add("X-Filename", result.Name); return result.Content; } [WebInvoke(UriTemplate = "{appName}", Method = "POST")] public void Save(string appName, Stream fileContent) { try { if (WebOperationContext.Current == null) throw new InvalidOperationException("WebOperationContext is null."); m_Request = WebOperationContext.Current.IncomingRequest; m_Response = WebOperationContext.Current.OutgoingResponse; var file = CreateFileResource(fileContent, appName); if (!FileIsValid(file)) throw new WebFaultException(HttpStatusCode.BadRequest); SaveFile(file); SetStatusAsCreated(file); } catch (Exception ex) { if (ex.GetType() == typeof(WebFaultException)) throw; if (ex.GetType().IsGenericType && ex.GetType().GetGenericTypeDefinition() == typeof(WebFaultException<>)) throw; throw new WebFaultException<string>("An unexpected error occurred.", HttpStatusCode.InternalServerError); } } private FileResource CreateFileResource(Stream fileContent, string appName) { var result = new FileResource(); fileContent.CopyTo(result.Content); result.ApplicationName = appName; result.Name = m_Request.Headers["X-Filename"]; result.Location = @"C:\SomeFolder\" + result.Name; result.ContentType = m_Request.Headers[HttpRequestHeader.ContentType] ?? this.GetContentType(result.Name); result.DateUploaded = DateTime.Now; return result; } private string GetContentType(string filename) { // this should be replaced with some form of logic to determine the correct file content type (I.E., use registry, extension, xml file, etc.,) return "application/octet-stream"; } private bool FileIsValid(FileResource file) { var validator = new FileResourceValidator(); var clientHash = m_Request.Headers[HttpRequestHeader.ContentMd5]; return validator.IsValid(file, clientHash); } private void SaveFile(FileResource file) { // This will persist the meta data about the file to a database (I.E., size, filename, file location, etc) new FileRepository().AddFile(file); } private void SetStatusAsCreated(FileResource file) { var location = new Uri(m_Request.UriTemplateMatch.RequestUri.AbsoluteUri + "/" + file.Id); m_Response.SetStatusAsCreated(location); } } 

Sample Client, note that this is NOT production ready code.

// ********************************* // Sample Client // ********************************* private void UploadButton_Click(object sender, EventArgs e) { var uri = "http://dev-fileservice/SampleApplication" var fullFilename = @"C:\somefile.txt"; var fileContent = File.ReadAllBytes(fullFilename); using (var webClient = new WebClient()) { try { webClient.Proxy = null; webClient.Headers.Add(HttpRequestHeader.ContentMd5, this.CalculateFileHash()); webClient.Headers.Add("X-DaysToKeep", DurationNumericUpDown.Value.ToString()); webClient.Headers.Add("X-Filename", Path.GetFileName(fullFilename)); webClient.UploadData(uri, "POST", fileContent); var fileUri = webClient.ResponseHeaders[HttpResponseHeader.Location]; Console.WriteLine("File can be downloaded at" + fileUri); } catch (Exception ex) { var exception = ex.Message; } } } private string CalculateFileHash() { var hash = MD5.Create().ComputeHash(File.ReadAllBytes(@"C:\somefile.txt")); var sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("x2")); } return sb.ToString(); } private void DownloadFile() { var uri = "http://dev-fileservice/SampleApplication/1" // this is the URL returned by the Restful file service using (var webClient = new WebClient()) { try { webClient.Proxy = null; var fileContent = webClient.DownloadData(uri); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } 
Sign up to request clarification or add additional context in comments.

2 Comments

ok, it is good for small files but how about large files? any code sample on REST example would be great
great example. thanks will give it a try soon. do you think Restful way is better that the SOAP way?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.