2013-07-05 28 views
1

使用VS 2012,ASP.NET Web API 4.0,4.0版的Web API客戶端庫。
我創建了一個「hello world」控制器,並且獲得了簡單的get/post工作。但是,我無法發佈文件。無法從HttpClient發佈文件到ASP.NET Web API

我正在通過HttpClient客戶端訪問服務,但無法使用簡單的HTML頁面來工作(發佈文件),無論我嘗試了什麼。但是,這有它自己的問題(並且內容總是碰到了IsMimeMultipartContent,而我的HttpClient沒有);我只想得到一個HttpClient現在的工作。客戶端流在文件中的罰款(我可以看到長度是好的),但在服務器上,ReadAsStreamAsync中的流的長度爲0.此外,HttpContext.Current.Request.Files計數爲0(即使當從HTML文件發佈)。

這裏的控制器:

public class ImportController : ApiController 
{ 

    public HttpResponseMessage Post() 
    { 
     WriteFile(HttpContext.Current.Server.MapPath("~/killme.xml")); 
     return new HttpResponseMessage(HttpStatusCode.Accepted); 
    } 

    private void WriteFile(string filePath) 
    { 
     Request.Content.ReadAsStreamAsync().ContinueWith(task => 
     { 
      try 
      { 
       var requestStream = task.Result; 
       var fileStream = File.Create(filePath); 
       requestStream.CopyTo(fileStream); 
       fileStream.Close(); 
       requestStream.Close(); 
      } 
      catch 
      { 
       ; // TBD 
      } 
     }); 
    } 

} 

下面是客戶端:

var client = new HttpClient(); 
client.PostAsync("http://localhost:52800/api/Import", ReadFile()).ContinueWith((task) => 
{ 
    Console.WriteLine(task.Result.StatusCode.ToString()); 
    client.Dispose(); 
}); 

private static StreamContent ReadFile() 
{ 
    var fileBytes = File.ReadAllBytes(@"C:\temp\killme.xml"); 
    var ms = new MemoryStream(fileBytes.Length); 
    ms.Write(fileBytes, 0, fileBytes.Length); 
    // Can't put this in using; don't know how to dispose 
    return new StreamContent(ms); 
} 

回答

1

我認爲你唯一的錯誤是忘記將它傳遞給StreamContent之前重置內存流的位置。但是,我更願意創建一個專門用於處理髮送文件的派生HttpContent類。

有了這個類代碼會是什麼樣子,

var client = new HttpClient(); 
var content = new FileContent(@"C:\temp\killme.xml"); 
client.PostAsync("http://localhost:52800/api/Import", content).ContinueWith((task) => 
{ 
    Console.WriteLine(task.Result.StatusCode.ToString()); 
    client.Dispose(); 
}); 

例如

public class FileContent : HttpContent 
    { 
     private const int DefaultBufferSize = 1024 * 64; 
     private readonly string _fileName; 
     private readonly FileInfo _fileInfo; 

     public FileContent(string fileName) 
     { 
      if (string.IsNullOrWhiteSpace(fileName)) 
      { 
       throw new ArgumentNullException("fileName"); 
      } 
      _fileInfo = new FileInfo(fileName); 
      if (!_fileInfo.Exists) 
      { 
       throw new FileNotFoundException(string.Empty, fileName); 
      } 

      _fileName = fileName; 

     } 

     protected override bool TryComputeLength(out long length) 
     { 
      length = _fileInfo.Length; 
      return true; 
     } 

     private FileStream _FileStream; 
     protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
     { 
      _FileStream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 
             DefaultBufferSize, 
             FileOptions.Asynchronous | FileOptions.SequentialScan); 

      _FileStream.CopyTo(stream); 
      var tcs = new TaskCompletionSource<object>(); 
      tcs.SetResult(null); 
      return tcs.Task; 

     } 

     protected override void Dispose(bool disposing) 
     { 
      if (_FileStream != null) 
      { 
       _FileStream.Dispose(); 
       _FileStream = null; 
      } 
      base.Dispose(disposing); 
     } 
    } 
} 
+0

將我的數據流重置爲0不起作用,但您的代碼確實有效;小記:結尾有額外的捲曲。 – dudeNumber4

+0

重置我的流確實可行,我很困惑,我無法多次運行任何一種方法(除非我重新啓動IIS Express)。在你的代碼中沒有任何東西是沒有處理的;不知道是什麼讓第二次運行時請求流長度爲0 – dudeNumber4

相關問題