2017-04-24 73 views
1

我有一個存儲圖像的Azure blob容器。我還有一套ASP.NET Web API方法用於在此容器中添加/刪除/列出blob。如果我將圖像作爲文件上傳,這一切都有效。但是我現在想要將圖像作爲流上傳,並且出現錯誤。使用ASP.NET Web API將映像添加到Azure blob存儲器

public async Task<HttpResponseMessage> AddImageStream(Stream filestream, string filename) 
    { 
     try 
     { 
      if (string.IsNullOrEmpty(filename)) 
      { 
       throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); 
      } 

      BlobStorageService service = new BlobStorageService(); 
      await service.UploadFileStream(filestream, filename, "image/png"); 
      var response = Request.CreateResponse(HttpStatusCode.OK); 
      return response; 
     } 
     catch (Exception ex) 
     { 
      base.LogException(ex); 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); 
     } 

用於將新圖像作爲流添加到blob容器的代碼如下所示。

public async Task UploadFileStream(Stream filestream, string filename, string contentType) 
    { 
     CloudBlockBlob blockBlobImage = this._container.GetBlockBlobReference(filename); 
     blockBlobImage.Properties.ContentType = contentType; 
     blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString()); 
     blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString()); 
     await blockBlobImage.UploadFromStreamAsync(filestream); 
    } 

最後,這是我的單元測試失敗。

[TestMethod] 
    public async Task DeployedImageStreamTests() 
    { 
     string blobname = Guid.NewGuid().ToString(); 

     //Arrange 
     MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes($"This is a blob called {blobname}.")) 
     { 
      Position = 0 
     }; 

     string url = $"http://mywebapi/api/imagesstream?filestream={stream}&filename={blobname}"; 
     Console.WriteLine($"DeployedImagesTests URL {url}"); 
     HttpContent content = new StringContent(blobname, Encoding.UTF8, "application/json"); 
     var response = await ImagesControllerPostDeploymentTests.PostData(url, content); 

     //Assert 
     Assert.IsNotNull(response); 
     Assert.IsTrue(response.IsSuccessStatusCode); //fails here!! 
     Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); 
    } 

我得到的錯誤是值不能爲空。 參數名稱:源

這是使用Web API將圖像流上傳到Azure blob存儲的正確方法嗎?我使用圖像文件時沒有問題,現在只是在嘗試使用流上傳時遇到此問題。

+0

什麼是你得到的是錯誤的堆棧跟蹤(即,哪一行代碼引發錯誤)? – jadarnel27

回答

3

這是使用Web API將圖像流上傳到Azure blob存儲的正確方法嗎?我使用圖像文件時沒有問題,現在只是在嘗試使用流上傳時遇到此問題。

根據你的描述和錯誤消息,我發現你發送你的流數據在你的網址到web api。

根據這篇文章:

的Web API使用以下規則綁定參數:

如果參數是一個「簡單」的類型,網頁API嘗試從URI中的價值。簡單類型包括.NET原始類型(int,bool,double等),加上TimeSpan,DateTime,Guid,decimal和string,以及任何類型的轉換器都可以從字符串轉換。 (稍後關於類型轉換器的更多信息。)

對於複雜類型,Web API嘗試使用媒體類型格式化程序從消息正文讀取值。

在我看來,流是一個複雜的類型,所以我建議你可以將它作爲body發佈到web api上。

此外,我建議你可以創建一個文件類並使用Newtonsoft.Json將其轉換爲json作爲消息的內容。

更多細節,你可以參考下面的代碼。 文件類:

public class file 
    { 
     //Since JsonConvert.SerializeObject couldn't serialize the stream object I used byte[] instead 
     public byte[] str { get; set; } 
     public string filename { get; set; } 

     public string contentType { get; set; } 
    } 

的Web API:

[Route("api/serious/updtTM")] 
    [HttpPost] 
    public void updtTM([FromBody]file imagefile) 
    { 
      CloudStorageAccount storageAccount = CloudStorageAccount.Parse("aaaaa"); 
      var client = storageAccount.CreateCloudBlobClient(); 
      var container = client.GetContainerReference("images"); 

      CloudBlockBlob blockBlobImage = container.GetBlockBlobReference(imagefile.filename); 
      blockBlobImage.Properties.ContentType = imagefile.contentType; 
      blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString()); 
      blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString()); 

      MemoryStream stream = new MemoryStream(imagefile.str) 
      { 
       Position=0 
      }; 
      blockBlobImage.UploadFromStreamAsync(stream); 
     } 

測試控制檯:

using (var client = new HttpClient()) 
      { 
       string URI = string.Format("http://localhost:14456/api/serious/updtTM"); 
       file f1 = new file(); 

       byte[] aa = File.ReadAllBytes(@"D:\Capture2.PNG"); 

       f1.str = aa; 
       f1.filename = "Capture2"; 
       f1.contentType = "PNG"; 
       var serializedProduct = JsonConvert.SerializeObject(f1); 
       var content = new StringContent(serializedProduct, Encoding.UTF8, "application/json"); 
       var result = client.PostAsync(URI, content).Result; 
      } 
+0

這很有道理。我會試一試,看看它是否能解決問題。謝謝(你的)信息。 – DomBurf

+0

我在將流轉換爲JSON時遇到了問題,但我設法解決了這個問題。此解決方案現在可以工作,因此我將其標記爲接受的答案。 – DomBurf

相關問題