2011-07-28 12 views
7

WCFストリーミングファイル転送の良い例が必要です。WCFストリーミングファイル転送ON .NET 4

私はいくつかを見つけて試しましたが、投稿は古く、私はネット4とIIS 7で動揺していますので、いくつかの問題があります。

あなたは私にそれに関する良い最新の例を教えてもらえますか?

+0

ストリーミングとはどういう意味ですか?メディアコンテンツ(I.E.、ビデオ、またはMP3)にWCFを使用しようとしているのですか、バイナリ情報をクライアントに送り返すことを意味していますか? – Kane

+0

私はhttpを介して自分のサーバーにファイルをアップロードしようとしています。 – tugberk

答えて

7

以下は、安価なサービスへのバイナリデータの投稿にいくつかのテクニックを使用して詳細を示しています。

次のコードでは、RESTfulなWCFサービスを作成することができる方法の例ですと、決して完全ではなく、あなたに指示を与えるんあなたは始めることができます。

サンプルサービス、これはNOT生産準備完了コードです。

[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

という素晴らしい例で追加しました。すぐに試してみると感謝します。あなたは落ち着いたやり方がSOAPの方が良いと思いますか? – tugberk

関連する問題