2014-09-23 40 views
12

我花了好幾天的時間研究和研究上傳/下載byte []的解決方案。我很接近,但有一個似乎在AngularJS代碼塊中的問題。使用AngularJS和ASP.NET Web API上傳/下載字節數組

在SO上有類似的問題,但它沒有任何迴應。請參閱https://stackoverflow.com/questions/23849665/web-api-accept-and-post-byte-array

這裏是一些背景信息,在我陳述我的問題之前設置上下文。

  1. 我正在嘗試創建一個通用客戶端/服務器接口來上傳和下載byte [],這些接口用作專有服務器數據庫的一部分。
  2. 我在客戶端上使用TypeScript,AngularJS,JavaScript和Bootstrap CSS來創建單頁面應用程序(SPA)。
  3. 我在服務器上使用ASP.NET Web API/C#。

SPA正在開發中,以取代在Silverlight中開發的現有產品,因此它受限於現有的系統要求。 SPA還需要針對各種設備(移動到桌面)和主要操作系統。

在幾個在線資源(下面列出)的幫助下,我得到了大部分代碼的工作。我在下面的Byte Rot鏈接中使用了一個異步多媒體格式化程序來處理byte []。

http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html

Returning binary file from controller in ASP.NET Web API

  1. 我使用的是JPEG轉換成Uint8Array作爲客戶端在我的測試案例。
  2. 實際系統字節數組將包含壓縮到預定義數據包中的混合內容。但是,我需要能夠處理任何有效的字節數組,因此圖像是有效的測試用例。
  3. 使用下面顯示的客戶端和服務器代碼和Byte Rot Formatter(未顯示,但可在其網站上獲得)將數據正確傳輸到服務器。
  4. 我已經驗證了jpeg在服務器上作爲字節[]與字符串參數元數據一起正確接收。
  5. 我已經使用Fiddler來驗證是否將正確的響應發送回客戶端。
    • 尺寸正確
    • 圖片在Fiddler中可以看到。
  6. 我的問題是,下面顯示的Angular客戶端代碼中的服務器響應不正確。

    • 由不正確的,我指的是錯誤的大小(〜10K與〜27.5K),這是不確認爲UintArray構造有效值。當我將光標放在下面客戶端代碼中顯示的返回「響應」上時,Visual Studio顯示JFIF,但沒有其他可見的內容指示器。

/**********************服務器代碼**************** ********/ 添加缺失的項目後[FromBody]字節[]

public class ItemUploadController : ApiController{ 
[AcceptVerbs("Post")] 
    public HttpResponseMessage Upload(string var1, string var2, [FromBody]byte[] item){ 
     HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     var stream = new MemoryStream(item); 
     result.Content = new StreamContent(stream); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     return result; 
    } 
} 

/*****************示例代碼客戶端代碼********************/

我從代碼中省略的唯一東西就是實際的變量參數。

$http({ 
url: 'api/ItemUpload/Upload', 
    method: 'POST', 
    headers: { 'Content-Type': 'application/octet-stream' },// Added per Byte Rot blog... 
    params: { 
     // Other params here, including string metadata about uploads 
     var1: var1, 
     var2: var2 
    }, 
data: new Uint8Array(item), 
// arrybuffer must be lowecase. Once changed, it fixed my problem. 
responseType: 'arraybuffer',// Added per http://www.html5rocks.com/en/tutorials/file/xhr2/ 
transformRequest: [], 
}) 
.success((response, status) => { 
    if (status === 200) { 
     // The response variable length is about 10K, whereas the correct Fiddler size is ~27.5K. 
     // The error that I receive here is that the constructor argument in invalid. 
     // My guess is that I am doing something incorrectly with the AngularJS code, but I 
     // have implemented everything that I have read about. Any thoughts??? 
     var unsigned8Int = new Uint8Array(response); 
     // For the test case, I want to convert the byte array back to a base64 encoded string 
     // before verifying with the original source that was used to generate the byte[] upload. 
     var b64Encoded = btoa(String.fromCharCode.apply(null, unsigned8Int)); 
     callback(b64Encoded); 
    } 
}) 
.error((data, status) => { 
    console.log('[ERROR] Status Code:' + status); 
}); 

/************************************** **********************/

任何幫助或建議將不勝感激。

謝謝...

被修改以包括更多的診斷數據

首先,我使用的angular.isArray函數來確定響應值不是數組,我認爲它應該是。

其次,我使用下面的代碼來詢問響應,這看起來是一個看不見的字符串。前導字符似乎不對應圖像字節數組代碼中的任何有效序列。

var buffer = new ArrayBuffer(response.length); 
var data = new Uint8Array(buffer); 
var len = data.length, i; 
for (i = 0; i < len; i++) { 
    data[i] = response[i].charCodeAt(0); 
} 

實驗結果

我跑通過從0創建字節數組的值的實驗 - 255服務器,該服務器我下載上。 AngularJS客戶端正確地收到了前128個字節(即,0,1,...,126,127),但其餘值在Internet Explorer 11中爲65535,在Chrome和Firefox中爲65533。 Fiddler顯示通過網絡發送了256個值,但在AngularJS客戶端代碼中僅接收到217個字符。如果我只使用0-127作爲服務器值,一切似乎都有效。我不知道什麼會導致這種情況,但客戶端的響應似乎更符合帶符號的字節,我認爲這是不可能的。

來自服務器的Fiddler十六進制數據顯示256個字節,值範圍從00,01,...,EF,FF,這是正確的。正如我前面提到的,我可以返回一個圖像並在Fiddler中正確地查看它,所以Web API服務器接口對於POST和GET都適用。

我想香草XMLHttpRequest看到我可以得到在AngularJS環境以外的工作。

XMLHttpRequest的測試更新

我已經能夠證實,香草XMLHttpRequest的工作原理與服務器的GET和能夠返回正確的字節代碼和測試圖像。

好消息是我可以繞過AngularJS來讓我的系統工作,但壞消息是我不喜歡這樣做。我寧願與Angular保持所有客戶端服務器通信。

我打算在Stack Overflow上單獨討論一個問題,它只處理我在AngularJS中遇到的GET byte []問題。如果我能得到解決方案,我會用解決方案更新這個問題,以便用於歷史目的以幫助他人。

更新

埃裏克Eslinger在谷歌網上論壇給我發了一個小的代碼段突出顯示的responseType應該是「arraybuffer」,全部小寫。我更新了上面的代碼塊以顯示小寫值並添加了一個註釋。

謝謝...

+0

你能在類似的問題,建議我有[問題] [1] [1]:http://stackoverflow.com/questions/31612259/sending-byte-collections-with-form- form-data-to-api-using-angularjs – 2015-07-25 09:53:33

回答

11

我終於收到了從埃裏克Eslinger在谷歌集團的響應。他指出他使用

$http.get('http://example.com/bindata.jpg', {responseType: 'arraybuffer'}). 

他提到camelcase可能是重要的,這是。改變了一個角色,現在整個流程都在工作。

所有榮譽都歸埃裏克埃斯林格所有。

+0

我使用自定義get,但是這個responseType:'arraybuffer'救了我,謝謝分享! – SomeRandomName 2014-12-04 15:13:29

+0

我收到一個TypedArray構造函數參數是無效的錯誤,這只是因爲我有'arrayBuffer'。將它更改爲'arraybuffer',並且嘿presto錯誤消失了!向Eric表示敬意。 – 2016-06-03 14:32:30

相關問題