最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - asp.net How Do I Change a Cursor From Wait Back to Normal After a Server Process Has Executed With No Postback? - S

programmeradmin3浏览0评论

I have a website that, after the user clicks an Imagebutton, calls server side code to create an Excel file and downloads it. This process can take about 20 seconds to finish so I'm wanting to change the cursor to wait mode until it finishes. I've followed the guidelines in this post, but it fails to say how I can reset the cursor back to normal once the download is complete.

Below is the last part of my server side code that actually creates the download, is there something I can possibly do to check the HTTPContext to see if it's finished?

//*****************************************
//* Workbook Download & Cleanup
//*****************************************
using (var stream = new MemoryStream())
{
    Response.Clear();
    wb.Write(stream);
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "Student Experiences.xlsx"));
    Response.BinaryWrite(stream.ToArray());
    Response.Flush();
    Response.End();
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}

I have a website that, after the user clicks an Imagebutton, calls server side code to create an Excel file and downloads it. This process can take about 20 seconds to finish so I'm wanting to change the cursor to wait mode until it finishes. I've followed the guidelines in this post, but it fails to say how I can reset the cursor back to normal once the download is complete.

Below is the last part of my server side code that actually creates the download, is there something I can possibly do to check the HTTPContext to see if it's finished?

//*****************************************
//* Workbook Download & Cleanup
//*****************************************
using (var stream = new MemoryStream())
{
    Response.Clear();
    wb.Write(stream);
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "Student Experiences.xlsx"));
    Response.BinaryWrite(stream.ToArray());
    Response.Flush();
    Response.End();
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}
Share Improve this question asked Mar 31 at 20:55 JimmyGJimmyG 6277 silver badges25 bronze badges 11
  • Well, actually, the problem is you are downloading a file, and that is a server response, and as such, then you can ONLY return a web page, or ONLY return a file. There's thus not really a provision for any event to run. You don't show how the above server code is being triggered, but regardless, you can't return "both" a server (page) response, and a file at the same time - you can only do one, or the other. In effect, you question is how can I run some client side JavaScript code after downloading a file - that's not a easy task at all. – Albert D. Kallal Commented Apr 1 at 1:10
  • Thanks, for clarity the trigger is an asp ImageButton: <asp:ImageButton ID="expExcel" runat="server" AlternateText="Excel" ImageUrl="/DMC/Images/excelDownload2.png" CssClass="excel-img" OnClick="exportExcel" OnClientClick="hourglass(); return true;"/> – JimmyG Commented Apr 1 at 3:38
  • Also, I know I can make this work using cookies -- I've done that before: in javascript 1) set the cursor status; look for the existence of a cookie; when cookie is found reset cursor status; and then on the server side once the file has finished downloading create the cookie the js is looking for. But I'm trying to get away from using cookies. – JimmyG Commented Apr 1 at 3:40
  • 1 How you going to create cookies after the file download? You may well be able to include a cookie in the response headers before you send the file, but that means the cookie created at start/before the file starts to flow.... – Albert D. Kallal Commented Apr 1 at 4:27
  • What kind of website? You only revealed some backend code, which is ASP.NET based, but what's the technology you use to build the front end? Mature frameworks like Angular/React/Blazor all have existing solutions for such scenarios. – Lex Li Commented Apr 1 at 7:31
 |  Show 6 more comments

1 Answer 1

Reset to default 1

Sorry my question didn't contain more detail, I'll try to include all the relevant information in my answer below. I decided to go back to using a cookie. I knew this method works but I was trying to do away with cookies. This is for an old asp webform written with a c# base.

The process starts when somebody clicks on the Excel image:

<img src='/DMC/Images/excelDownload2.png' class="excel-img" onclick="beginDownload('excel');" />

This calls a javascript function that starts looking for a not-yet-created cookie:

function beginDownload(dt) {
    $('#progressModal').modal('show');

    var downloadFrame = document.createElement("IFRAME");
    if (downloadFrame != null) {
        downloadFrame.setAttribute("src", 'aolStudentExperiences_Academy.aspx?exportType=' + dt);
        downloadFrame.style.width = "0px";
        downloadFrame.style.height = "0px";
        document.body.appendChild(downloadFrame);
    }

    var myDownload = setInterval(function () {
        if (Cookies.get('studentExperiencesByAcademy') == null) {
        }
        else {
            Cookies.remove('studentExperiencesByAcademy');
            $('#progressModal').modal('hide');
            clearInterval(myDownload);
        }
    }, 1000);
}

The modal being called displays a 'please wait' image until the cookie is found:

<!-- Modal -->
<div class="modal fade" id="progressModal" tabindex="-1" role="dialog"
    aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="progress" style="height: 25px">
                <div class="progress-bar progress-bar-striped progress-bar-animated bg-warning"
                    role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"
                    style="width: 75%; color: black">
                    ...Building File (about 20-25 seconds)
                </div>
            </div>
        </div>
    </div>
</div>

The javascript function also builds an iframe and recalls this page with an exportType attribute appended onto the address. When the iframe gets loaded the server side code kicks in:

using DMC.Classes;
using DMC.AOL.WebServices;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;

namespace DMC.AOL
{
    public partial class aolStudentExperiences_Academy : System.Web.UI.Page
    {
        int pageID = 134;
        export dmc = new export();

        string exportType { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //Check to see if this is an excel download 
                exportType = Request.QueryString["exportType"];

                if (exportType == "excel")
                {
                    //Create the cookie to let main page know download is complete
                    HttpCookie myCookie = dmc.createDownloadCookie("studentExperiencesByAcademy");
                    //Add the cookie
                    Response.Cookies.Add(myCookie);

                    exportExcel();
                }
            }
        }

        protected void exportExcel()
        {
            //Steps to build the Excel file 

            //*****************************************
            //* Workbook Download & Cleanup
            //*****************************************
            using (var stream = new MemoryStream())
            {
                //Create the cookie to let main page know download is complete
                HttpCookie myCookie = dmc.createDownloadCookie("studentExperiencesbyAcademy");
                //Add the cookie
                Response.Cookies.Add(myCookie);

                Response.Clear();
                wb.Write(stream);
                Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "Student Experiences.xlsx"));
                Response.BinaryWrite(stream.ToArray());
                Response.Flush();
                Response.End();
                HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
        }
    }
}

The createDownloadCookie function is a class:

public HttpCookie createDownloadCookie(string cookieName)
{
    //Create a cookie to let the main page know the download has completed
    HttpCookie myCookie = new HttpCookie(cookieName);
    DateTime now = DateTime.Now;

    //Set the cookie value
    myCookie.Value = now.ToString();

    //Set the cookie expiration date
    myCookie.Expires = now.AddMinutes(1);

    return myCookie;
}

Once the javascript functino sees the cookie has been created it immediately removes it and hides the modal, and the file is ready to view!

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论