2

In my MVC 4 app, I have a view that uploads a file from the client machine with:

<snip>
@using (Html.BeginForm("Batch", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input class="full-width" type="file" name="BatchFile" id="BatchFile" 
    <input type="submit" value="Do It" />
}
<snip>

The "Batch" action in the home controller takes that file and processes it in a way that may be very lengthy.... minutes even:

<snip>
[HttpPost]
public FileResult Batch(ModelType modelInstance)
{
    // Do the batch work.
    string result = LengthyBatchProcess(modelInstance.BatchFile.InputStream)
    var encoding = new ASCIIEncoding();
    Byte[] byteArray = encoding.GetBytes(result);
    Response.AddHeader("Content-Disposition", "attachment;filename=download.csv");
    return File(byteArray, "application/csv");
}
<snip>

This all works fine, and it isn't an inherent problem that the user is locked out for the time it takes for the batch process to run. In fact they expect it. The problem is that the user may not be in a position to know whether this process will take a couple of seconds or a couple of minutes, and I would like to provide them with status information while LengthyBatchProcess is running. I have researched unobtrusive ajax, but it does not seem to have the functionality necessary for this, unless there is some way to chain unobtrusive ajax calls. Any thoughts on how to best architect this? Many thanks in advance.

4

2 回答 2

1

您想要实现的目标需要一些工作。

一种方法是打开另一个通道(ajax 调用)来获取进度报告。引自您如何衡量 Web 服务调用的进度?

在服务器上编写一个单独的方法,您可以通过传递已安排的作业的 ID 来查询该方法,该方法返回 0-100(或 0.0 和 1.0,或其他)之间的近似值,表示它的距离。

我找到了关于这个问题的一个很好的教程。

于 2013-05-11T15:57:44.943 回答
1

是的,您可以开始分块下载文件,以便用户可以看到浏览器的下载进度:

try
{
   // Do the batch work.
   string result = LengthyBatchProcess(modelInstance.BatchFile.InputStream)
   var encoding = new ASCIIEncoding();
   Byte[] byteArray = encoding.GetBytes(result);

   Response.Clear();
   Response.ClearContent();
   Response.Buffer = true;
   Response.AddHeader("Content-Disposition",
                      "attachment;filename=download.csv");
   Response.ContentType = "application/csv";
   Response.BufferOutput = false;

   for (int i = 0; i < byteArray.Length; i++)
   {
        if (i % 10000 == 0)
        {
             Response.Flush();
        }

   Response.Output.WriteLine(byteArray[i]);
   }
 }
 catch (Exception ex)
 {
 }
 finally
 {
   Response.Flush();
   Response.End();
 }           
于 2013-05-11T16:22:04.943 回答