2011-07-28 74 views
7

我需要WCF流式文件传输的一个很好的例子。WCF流式文件传输.NET 4

我已经找到了几个,并尝试过他们,但帖子是旧的,我在网路4和IIS 7上炒作,所以有一些问题。

你能给我一个很好的最新的例子。

+0

什么是流媒体?您是否尝试将WCF用于媒体内容(I.E.,视频或MP3),还是将二进制信息发送回客户端? – Kane

+0

基本上我试图通过http上传文件到我的服务器。 – tugberk

回答

7

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

下面的代码是你如何可以写一个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<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 
// ********************************* 
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); 
     } 
    } 
} 
+0

好吧,它适合小文件,但大文件怎么样? REST示例上的任何代码示例都会很好 – tugberk

+0

添加了一个代码示例,说明如何*写入WCF服务 – Kane

+0

的一个很好的示例。谢谢你很快就会试一试。你认为Rest方式更好的是SOAP方式吗? – tugberk