问题描述:

I need to make a file download that displays a loading icon during the processing of the file (because I don't know how long it is going to take), I decided to use an iframe, the code runs fine, but the problem is that the file download dialog box doesn't show up.

I've tested in IE, Firefox and Chrome and it is not working in any of them.

Here's my code:

View:

<table id="progress" style="visibility:hidden">

<tr>

<td>

<img src="~/Content/Images/ajax-loader.gif" />

</td>

<td>

<h4>please wait.</h4>

</td>

</tr>

</table>

<div class="buttons">

<input type="button" value="Ok" class="button" id="downloadButton">

</div>

<iframe id="iframe" style="visibility:hidden"></iframe>

<script>

$(document).ready(function () {

$('#downloadButton').click(function () {

$('#progress').show();

$('input:button').attr("disabled", true);

$('#iframe').src = "@Url.Action("GenerateFile", "Files", null)";

$('#iframe').load("GenerateFile", function () {

$('input:button').attr("disabled", false);

$('#progress').hide();

});

});

});

</script>

Server side Action:

[HttpGet]

public void GenerateFile(Filters viewModel)

{

var result = GetCustomers().WithName(viewModel.Name);

StringBuilder file = new StringBuilder();

foreach (var customer in result)

{

// fill up the string builder with csv format

}

System.Web.HttpContext.Current.Response.AddHeader("content-disposition","attachment; filename=Customers.csv");

System.Web.HttpContext.Current.Response.ContentType = "application/csv";

System.Web.HttpContext.Current.Response.Write(file);

System.Web.HttpContext.Current.Response.End();

}

Any help would be appreciated, thanks!

网友答案:

I think there are multiple problems with this code. Try this:

public FileResult GenerateFile(Filters viewModel)
        {
            var result = GetCustomers().WithName(viewModel.Name);
            StringBuilder file = new StringBuilder();

            foreach (var customer in result)
            {
                // fill up the string builder with csv format       
            }
            var content = Encoding.UTF8.GetBytes(file.ToString());
            return File(content, "application/csv", "Customers.csv");
        }

and I think there is no jQuery method called src, so try this also:

$('#iframe').attr('src',url);  

I assume you're using Razor syntax, so try this for your View code:

@{
    ViewBag.Title = "Test";
}

<table id="progress" style="display: none">
    <tr>
        <td>
            <img src="~/Content/Images/ajax-loader.gif" />
        </td>
        <td>
            <h4>please wait.</h4>
        </td>
    </tr>
</table>

<div class="buttons">
    <input type="button" value="Ok" class="button" id="downloadButton">
</div>

<iframe id="iframe" style="display: none"></iframe>
@section scripts{
    <script type="text/javascript">
        $(document).ready(function () {

            $('#downloadButton').click(function () {

                $('#progress').show();
                $('input:button').attr("disabled", true);

                var url = "@Url.Action("GenerateFile", "Files", null)";
$("#iframe").attr('src', url);

                $('#iframe').load("/Files/GenerateFile", function () {
                    $('input:button').attr("disabled", false);
                    $('#progress').hide();
                });
            });

        });
    </script>
}

And I also believe that you should specify an Action parameter in your jQuery load function, eg. $('#iframe').load("/Files/GenerateFile/parameter"...) because your GenerateFile action takes Filters parameter.

相关阅读:
Top