WCF流式文件传输在.NET 4上

我需要一个关于WCF流式文件传输的好例子。

我找到了几个并尝试了它们,但post很旧,我在.net 4和IIS 7上玩耍,所以有一些问题。

你能给我一个很好的,最新的例子吗?

以下答案详细介绍了使用一些技术将二进制数据发布到一个宁静的服务。

  • 将二进制数据发布到RESTful应用程序
  • 将二进制数据传输到HTTP REST API服务的好方法是什么?
  • 使用Web服务传输大型负载的坏主意?

以下代码是您如何编写RESTful WCF服务的示例,并不是完整的,但它会告诉您可以从哪里开始。

示例服务 ,请注意,这不是生产就绪代码。

[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("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 (IE, 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 (IE, 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 // ********************************* 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); } } }