![](/img/trans.png)
[英]Unexpected end of MIME multipart stream. MIME multipart message is not complete. Web API and superagent
[英].NET Web API Blueimp multiple file upload error “Unexpected end of MIME multipart stream. MIME multipart message is not complete.”
我正在構建一個視頻管理應用程序,允許將多個視頻上傳到 Azure 存儲,然后由 Azure 媒體服務編碼。
我的問題是,如果我使用 blueimp 一次只上傳 1 個文件,一切正常。 當我在上傳中添加多個文件時,第二個文件出現錯誤。
MIME 多部分 stream 意外結束。 MIME 多部分消息不完整。
I have read that it could be to the stream missing the end of file terminator, so I added in the suggested tweak to append the line terminator (per this article ASP.NET Web API, unexpected end of MIME multi-part stream when uploading from Flex FileReference ) 沒有運氣。
如果我作為單個文件發布(通過遍歷選擇上傳的文件)並將它們作為單獨的帖子發送,它可以工作。 我的問題是我想 select 幾個文件以及添加其他元數據並點擊一個提交按鈕。 當我這樣做時,第一個文件上傳,第二個文件似乎開始上傳,但隨后我收到錯誤 500“MIME 多部分 stream 意外結束。MIME 多部分消息不完整”消息。
這是我的上傳代碼(Web API):
[HttpPost]
public async Task<HttpResponseMessage> UploadMedia()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Headers["content-type"] != null)
{
httpRequest.Headers.Remove("content-type");
}
httpRequest.Headers.Add("enctype", "multipart/form-data");
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
string assignedSectionList = string.Empty;
postedFile.SaveAs(filePath);
docfiles.Add(filePath);
string random = Helpers.Helper.RandomDigits(10).ToString();
string ext = System.IO.Path.GetExtension(filePath);
string newFileName = (random + ext).ToLower();
MediaType mediaType = MediaType.Video;
if (newFileName.Contains(".mp3"))
{
mediaType = MediaType.Audio;
}
if (httpRequest.Form["sectionList"] != null)
{
assignedSectionList = httpRequest.Form["sectionList"];
}
MediaUploadQueue mediaUploadQueueItem = new MediaUploadQueue();
mediaUploadQueueItem.OriginalFileName = postedFile.FileName;
mediaUploadQueueItem.FileName = newFileName;
mediaUploadQueueItem.UploadedDateTime = DateTime.UtcNow;
mediaUploadQueueItem.LastUpdatedDateTime = DateTime.UtcNow;
mediaUploadQueueItem.Status = "pending";
mediaUploadQueueItem.Size = postedFile.ContentLength;
mediaUploadQueueItem.Identifier = random;
mediaUploadQueueItem.MediaType = mediaType;
mediaUploadQueueItem.AssignedSectionList = assignedSectionList;
db.MediaUploadQueue.Add(mediaUploadQueueItem);
db.SaveChanges();
byte[] chunk = new byte[httpRequest.ContentLength];
httpRequest.InputStream.Read(chunk, 0, Convert.ToInt32(httpRequest.ContentLength));
var provider = new AzureStorageMultipartFormDataStreamProviderNoMod(new AzureMediaServicesHelper().container);
provider.fileNameOverride = newFileName;
await Request.Content.ReadAsMultipartAsync(provider); //this uploads it to the storage account
//AzureMediaServicesHelper amsHelper = new AzureMediaServicesHelper();
string assetId = amsHelper.CommitAsset(mediaUploadQueueItem); //begin the process of encoding the file
mediaUploadQueueItem.AssetId = assetId;
db.SaveChanges();
////start the encoding
amsHelper.EncodeAsset(assetId);
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
這是發送到 Azure Blob 存儲的上傳處理程序的代碼
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
if (parent == null) throw new ArgumentNullException(nameof(parent));
if (headers == null) throw new ArgumentNullException(nameof(headers));
if (!_supportedMimeTypes.Contains(headers.ContentType.ToString().ToLower()))
{
throw new NotSupportedException("Only jpeg and png are supported");
}
// Generate a new filename for every new blob
var fileName = Guid.NewGuid().ToString();
if (!String.IsNullOrEmpty(fileNameOverride))
fileName = fileNameOverride;
CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(fileName);
if (headers.ContentType != null)
{
// Set appropriate content type for your uploaded file
blob.Properties.ContentType = headers.ContentType.MediaType;
}
this.FileData.Add(new MultipartFileData(headers, blob.Name));
return blob.OpenWrite();
}
這是 javascript 代碼。 第一個是將文件單獨作為單獨的帖子發送,它可以工作。
$("#fileupload").fileupload({
autoUpload: false,
dataType: "json",
add: function (e, data) {
data.context = $('<p class="file">')
.append($('<a target="_blank">').text(data.files[0].name))
.appendTo(document.body);
data.submit();
},
progress: function (e, data) {
var progress = parseInt((data.loaded / data.total) * 100, 10);
data.context.css("background-position-x", 100 - progress + "%");
},
done: function (e, data) {
data.context
.addClass("done")
.find("a")
.prop("href", data.result.files[0].url);
}
});
下面的這段代碼不起作用。 它將所有文件推送到數組中,並將它們發送到一個帖子中。 這個在第二個文件上失敗了。 如果我使用此代碼只上傳一個文件,它就可以工作。
var filesList = new Array();
$(function () {
$('#fileupload').fileupload({
autoUpload: false,
dropZone: $('#dropzone'),
add: function (e, data) {
filesList.push(data.files[0]);
data.context = $('<div class="file"/>', { class: 'thumbnail pull-left' }).appendTo('#files');
var node = $('<p />').append($('<span/>').text(data.files[0].name).data(data));
node.appendTo(data.context);
},
progress: function (e, data) { //Still working on this part
//var progress = parseInt((data.loaded / data.total) * 100, 10);
//data.context.css("background-position-x", 100 - progress + "%");
},
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node.prepend('<br>').prepend(file.preview);
}
if (file.error) {
node.append('<br>').append($('<span class="text-danger"/>').text(file.error));
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
$("#uploadform").submit(function (event) {
if (filesList.length > 0) {
console.log("multi file submit");
event.preventDefault();
$('#fileupload').fileupload('send', { files: filesList })
.success(function (result, textStatus, jqXHR) { console.log('success'); })
.error(function (jqXHR, textStatus, errorThrown) { console.log('error'); })
.complete(function (result, textStatus, jqXHR) {
console.log('complete: ' + JSON.stringify(result)); //The error 500 is returned here. In fiddler, it shows and error 500. If I try to trap in Visual Studio, I can't seem to pinpoint the exception.
// window.location='back to view-page after submit?'
});
} else {
console.log("plain default form submit");
}
});
});
關於為什么會發生這種情況的任何想法? 我已經嘗試了所有我能想到的方法,但沒有運氣。 先感謝您!
我想指出,您的代碼架構可能會導致超時或錯誤。
我首先將所有內容上傳到 azure 存儲,將狀態存儲在緩存或數據庫中。
然后我會啟動一個后台作業(hangfire,azure 函數,webjobs)來處理上傳到媒體服務來做其他事情。
我建議從用戶輸入異步執行此操作。
根據 dropzone 的文檔,確保在 HTML 標簽中添加名稱
<form action="/file-upload" class="dropzone">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</form>
如果您以編程方式執行此操作:
function param() {
return "files";
}
Dropzone.options.myDropzone = {
uploadMultiple: true,
paramName: param,
}
在后端,您需要在每個 stream 之后添加 \r\n:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.