从控制器生成/返回文件时显示叠加层

时间:2009-12-31 16:14:41

标签: jquery asp.net-mvc overlay

我正在从视图中点击一个按钮,从控制器生成并返回一个相当大的文件。 我希望能够做的是在生成文件时显示“生成文件”的叠加层,一旦完成,叠加层就会消失。 我将如何做这样的事情?

以下是我的控制器的示例。

  public ActionResult Generate(FormViewModel fvm)
  {
        var isValid = AreInputsValid(fvm);
        if (!isValid)
        {
            TryUpdateModel(fvm);
            return View("Index", );
        }
        RenderReport(new Report(fvm));
        return View();
    }

    private void RenderReport(Models.Report report)
    {
        var localReport = new LocalReport { ReportPath = report.ReportPath };

        var reportDataSource = new ReportDataSource(report.DataSourceName, report.Model);
        localReport.DataSources.Add(reportDataSource);

        var reportType = "PDF";
        string mimeType;
        string encoding;
        string fileNameExtension;

        //The DeviceInfo settings should be changed based on the reportType
        //http://msdn2.microsoft.com/en-us/library/ms155397.aspx
        var deviceInfo =
            string.Format("<DeviceInfo><OutputFormat>{0}</OutputFormat><PageWidth>11in</PageWidth><PageHeight>8.5in</PageHeight><MarginTop>0.5in</MarginTop><MarginLeft>0.25in</MarginLeft><MarginRight>0.25in</MarginRight><MarginBottom>0.5in</MarginBottom></DeviceInfo>", reportType);

        Warning[] warnings;
        string[] streams;

        //Render the report
        var renderedBytes = localReport.Render(
            reportType,
            deviceInfo,
            out mimeType,
            out encoding,
            out fileNameExtension,
            out streams,
            out warnings);

        //Clear the response stream and write the bytes to the outputstream
        //Set content-disposition to "attachment" so that user is prompted to take an action
        //on the file (open or save)
        Response.Clear();
        Response.ContentType = mimeType;
        Response.AddHeader("content-disposition", "attachment; filename=" + report.ReportName + "." + fileNameExtension);
        Response.BinaryWrite(renderedBytes);
        Response.End();
    }

提前致谢

2 个答案:

答案 0 :(得分:1)

我会使用jquery blockUI来显示叠加层,并在div中显示“生成文件”消息。你可以在onClientClick上弹出它,它会一直存在,直到你从服务器返回

我总是将这段代码放在我使用blockUI的页面上 当出于某种原因你必须从服务器返回并显示模态时,它会很有用,否则它将隐藏以前可见的模态。

function pageLoad(event, args)
{
    var hdf = $('[id$=hdf_DisplayModal]').val();

    if(hdf != "")
        showPopup(hdf);
    else
        $.unblockUI();
}

然后我有一个附加的外部jasvascript文件,其中包含以下内容:

function showPopup(modal)
{
    showPopup(modal, null);
}

function showPopup(modal, fadeInTime)
{
    if(fadeInTime == null)
        fadeInTime = 500;

    modal = $('[id$=' + modal + ']');
    $.blockUI({ message: modal,
        fadeIn : fadeInTime,
        css: {
            top:  ($(window).height() - modal.height())/2  + 'px', 
            left: ($(window).width() - modal.width()) /2 + 'px', 
            width: modal.width() + 'px'
        }
    });
}

function closePopup(modal)
{
    closePopup(modal, null);
}

function closePopup(modal, fadeOutTime)
{
    $('[id$=hdf_DisplayModal]').attr("value", "");
    modal = $('[id$=' + modal + ']')
    $.unblockUI({ message: modal,
        fadeOut: fadeOutTime
    });
}

现在我从来没有在MVC中做过这些,但是根据我从同事那里听到的内容,经过一些调整之后,这一切都应该是可能的。我希望它有所帮助。

答案 1 :(得分:1)

用户界面是您遇到的问题中最少的。

如果您有一个需要几秒钟才能执行的操作,那么您将破坏ASP.NET工作线程以破坏站点的可伸缩性。这就是MVC 2 has AsyncControllers for delegating long-running tasks to a background thread的原因。还有a workaround for MVC 1

此外,您的操作不应写入Response。这样做会使操作不必要地难以测试,并偏离标准MVC管道,其中像ViewResult这样的结果对象实际写入响应。

最后,当您准备好更新UI​​时,通常会通过回调来执行此操作。

,例如,在“原始视图中加载消息:

”开头
<div id="report">Loading...</div>

然后加载就绪事件,并将“Loading ...”替换为响应内容:

$(document).ready(function() {
    $("#report").load("/path/to/action");
});