ASP.NET不向客户端发送上传进度

时间:2015-12-03 16:22:46

标签: asp.net-mvc xmlhttprequest

我正在进行这样的图片上传:

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function (e) {
    // THIS DOESN'T UPDATE UNTIL THE END. EVEN WITH A 10MB IMAGE
}, false);
xhr.open('POST', 'https://www.coolsite.com/api/upload', true);
reader.onload = function (evt) {
    var blob = new Blob([evt.target.result]);
    var formData = new FormData();
    formData.append('image', blob);
    xhr.send(formData);
};
reader.readAsArrayBuffer(file);

然后在服务器上我这样读了:

public class VideoController : CORSController
{
    ImageSaver imageSaver = new ImageSaver();
    public HttpResponseMessage Post()
    {
        Stream imageStream = HttpContext.Current.Request.Files[0].InputStream;
        imageSaver.save(imageStream);
        return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
}

public class CORSController : ApiController
{
    public HttpResponseMessage Options()
    {
        return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
}

但事实是,即使我使用巨大的图像文件,客户端也只能在文件上传后获取进度事件。我已经找到了答案,并尝试了各种配置来附加进度事件,但没有任何作用。我想我在服务器上做错了什么。

注意 - 这是一个CORS上传,所以可能与它有关。

4 个答案:

答案 0 :(得分:2)

如果您在浏览器控制台中无错误返回状态,则问题与服务器或其配置无关。虽然,我认为显示上传进度,主要是客户端问题。所以我叮嘱你使用一个更干净的有组织的客户端代码,就像我为你写的那样:

var bar = $('#uploadprogress');//like a <div> which will show the progress
var current = $('#preview');

$('#sendform').ajaxForm({
    beforeSend: function () {
        $('#progressbar').show();
        var percentVal = '0%';
        bar.width(percentVal)
        bar.html(percentVal);
    },
    uploadProgress: function (event, position, total, percentComplete) {
        var percentVal = percentComplete + '%';
        bar.width(percentVal)
        bar.html(percentVal);
    },
    success: function () {
        var percentVal = '100%';
        bar.width(percentVal)
        bar.html(percentVal);
    },
    complete: function (xhr) {
        current.html(xhr.responseText);
    }
});

控制器只是这样:

public ActionResult Upload(HttpPostedFileBase file)
{
     if (file != null)
     {
          string extension = Path.GetExtension(file.FileName).ToLower();
          if (extension == ".jpg" || extension == ".png")
          {
               file.SaveAs(Server.MapPath(_directory + file.FileName));
               return PartialView("_view");
          }
          else throw new Exception("Not Supported File");
     }
     throw new Exception("Empty File");
}

答案 1 :(得分:2)

尝试添加这些行。我通常将它们添加到_layout视图中加载的.js文件中,这样我就可以在任何地方获得“加载效果”,否则只需在文件上传的页面中添加它们。

$(document).on({
    ajaxStart: function () { $body.addClass("loading"); },
    ajaxStop: function () { $body.removeClass("loading"); }
});

然后添加以下css类

/* Start by setting display:none to make this hidden.
   Then we position it in relation to the viewport window
   with position:fixed. Width, height, top and left speak
   for themselves. Background we set to 80% white with
   our animation centered, and no-repeating */
.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background: rgba( 255, 255, 255, .8 ) url('../Images/Loader.gif') 50% 50% no-repeat;
}
/* When the body has the loading class, we turn the scrollbar off with overflow:hidden */
body.loading {
    overflow: hidden;   
}

/* Anytime the body has the loading class, our modal element will be visible */
body.loading .modal {
    display: block;
}

最后选择一个加载器gif(例如从这里http://www.ajaxload.info/

答案 2 :(得分:2)

我尝试过如下。它对我有用。

xhr.upload.addEventListener("progress", function (e) {
       console.log((e.loaded / e.total * 100).toFixed(2) + '%');
}, false);

答案 3 :(得分:2)