0

現在、ビューからボタンをクリックすると、コントローラーからかなり大きなファイルを生成して返しています。私ができるようにしたいのは、ファイルの生成中に「Generating File」というオーバーレイを表示し、完了するとオーバーレイが消えるようにすることです。どうすればこのようなことをすることができますか?

これは、私のコントローラーがどのように見えるかのサンプルです。

  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();
    }

前もって感謝します

4

2 に答える 2

1

jquery blockUIを使用してオーバーレイを表示し、divに「GeneratingFile」メッセージを表示します。この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でこれを行ったことがありませんが、同僚から聞いたところによると、これは少し調整すれば可能になるはずです。お役に立てば幸いです。

于 2009-12-31T16:18:22.813 に答える
1

UI は、ここでの問題の中で最も少ないものです。

実行に数秒かかるアクションがある場合は、ASP.NET ワーカー スレッドを拘束して、サイトのスケーラビリティを破壊しています。これが、MVC 2 にAsyncController長時間実行タスクをバックグラウンド スレッドに委譲するためのがある理由です。MVC 1 の回避策もあります。

また、アクションは に書き込むべきではありませんResponse。そうすることで、アクションのテストが不必要に難しくなり、結果オブジェクトViewResultが Response への実際の書き込みを行う標準の MVC パイプラインから逸脱します。

最後に、UI を更新する準備ができたら、通常はコールバックを使用してこれを行います。

たとえば、元のビューの「読み込みメッセージ:

<div id="report">Loading...</div>

次に、ready イベントを読み込み、"Loading..." を応答の内容に置き換えます。

$(document).ready(function() {
    $("#report").load("/path/to/action");
});
于 2009-12-31T17:35:47.400 に答える