为什么将数据导出到Excel会导致刷新会话问题?

I develop a web API with ASP.NET C# and angular 8.

我尝试将一些数据从Oracle导出到服务器端的Excel文件中,然后在客户端下载。 我以前做过,而且能用,但是现在我遇到一个异常,它说:

“会话状态创建了一个会话ID,但无法保存它,因为   响应已被应用程序刷新。未处理   当前Web请求的执行期间发生异常。   请查看堆栈跟踪以获取有关该错误的更多信息,以及   它起源于代码的位置。”

When I debug the program I can see that the api request called twice (I don't know why), on the first call the file is generated successfully but the response doesn't returned to the client.

在第二次通话中,它根本不起作用。

这是我的代码: HTML:

       <button
            class="col-sm-2 button-style button-text"
            style="color: white; background-color: #19D893;height: 100%;"
            (click)="exportPriceList()">
        Export
        </button>

打字稿:

public exportPriceList():  void {

    console.log('start export to excel');
   

    const fileName = 'PriceList_' + this.auth.authDetails.getValue().bank + '_' + Date.now.toString() + '.xlsx'; 
    const fileType = 'application/vnd.ms-excel';
    let url;
    if (this.auth.authDetails.getValue().isBoi)
    {
     url = this.apiService.baseUrl + 'api/PriceList/Export?token='  + this.token + 
    '&priceListType=' + this.selectedPriceListType.Key +   '&bank=' + this.selectedBank.Key  ;
    }
    else
    {
      url = this.apiService.baseUrl + 'api/PriceList/Export?token='  + this.token + 
      '&priceListType=' + this.selectedPriceListType.Key;
    }

   const promise = new Promise((resolve, reject) => {                                 
      this.http.post(url,   '' ,
         {
            headers: new HttpHeaders({
            'Content-Type':  'application/json'
           }), responseType: 'blob'
         }).subscribe(success => {
           console.log('start success');

          const blob = new Blob ([success], {type: fileType});
          

          console.log('window.navigator ', window.navigator  );
          console.log('window.navigator.msSaveOrOpenBlob ', window.navigator.msSaveOrOpenBlob  );
    
          if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            
    
            window.navigator.msSaveOrOpenBlob(blob, );
          }
           else {
              const a = document.createElement('a');
              a.href = URL.createObjectURL(blob);
              a.download = fileName ;
              document.body.appendChild(a);
              a.click();
              document.body.removeChild(a);
          }
      },
      err => {
          alert(err);
      });
     
   });

     promise.then((res) => {
       console.log('promise!!!! ', res );
    });
    promise.catch((err) => {
    });

      }
    
  }
}

API控制器:

[HttpPost]
    [Route("api/PriceList/Export")]
    public HttpResponseMessage Export([FromUri]string token, [FromUri]int priceListType, [FromUri]int? bank=null)
    {
        try
        {

            var stream = dal.ExportPriceListServer(priceListType, bank);

            var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);

            response.Content = new StreamContent(stream);
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "PriceList_" + bank + "_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
            //response.Content.Headers.ContentLength = stream.Length;
            response.StatusCode = System.Net.HttpStatusCode.OK;

            return response;
        }
        catch (Exception ex)
        {
            exc.throwException(EventLogEntryType.Error, ex.ToString());
            throw;
        }
    }

创建Excel:

 public MemoryStream CreateExcel(DataTable dt)
    {

        try
        {

            XSSFWorkbook workbook = new XSSFWorkbook();

            //FileStream fStream = new FileStream(Path.GetTempPath()+"test.xlsx", FileMode.OpenOrCreate, FileAccess.ReadWrite);

            MemoryStream ms = new MemoryStream();

            XSSFSheet sheet = (XSSFSheet)(workbook.CreateSheet("a1"));
            sheet.RightToLeft = true;


            //Sheet's title design
            XSSFRow title = (XSSFRow)(sheet.CreateRow(0));

            XSSFCell tc = (XSSFCell)title.CreateCell(0, CellType.String);
            tc.SetCellValue("a1");

            XSSFFont tf = (XSSFFont)workbook.CreateFont();
            tf.Color = IndexedColors.LightBlue.Index;
            tf.IsBold = true;

            tf.FontHeightInPoints = 16;


            XSSFCellStyle tstl = (XSSFCellStyle)workbook.CreateCellStyle();
            tstl.SetFont(tf);
            tstl.FillForegroundColor = IndexedColors.White.Index;
            tstl.FillPattern = FillPattern.NoFill;
            tstl.Alignment = HorizontalAlignment.Center;

            tc.CellStyle = tstl;

            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));

            //Header design
            XSSFRow headerRow = (XSSFRow)(sheet.CreateRow(1));

            XSSFFont hf = (XSSFFont)workbook.CreateFont();
            hf.Color = IndexedColors.White.Index;
            hf.IsBold = true;
            hf.FontHeightInPoints = 14;


            XSSFCellStyle hstl = (XSSFCellStyle)workbook.CreateCellStyle();
            hstl.SetFont(hf);
            hstl.FillForegroundColor = IndexedColors.Grey80Percent.Index;
            hstl.FillPattern = FillPattern.SolidForeground;

            XSSFCellStyle numCellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
            numCellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0");

            //// handling header.                
            foreach (DataColumn column in dt.Columns)
            {
                XSSFCell hc = (XSSFCell)headerRow.CreateCell(column.Ordinal);
                //hc.SetCellValue(column.ColumnName);

                //ColumnTitle columnTitle = (ColumnTitle)Enum.Parse(typeof(ColumnTitle), column.ColumnName);
                hc.SetCellValue(GetColumnTitle(column.ColumnName));
                hc.CellStyle = hstl;
            }

            // handling value.
            int rowIndex = 2;

            foreach (DataRow row in dt.Rows)
            {
                XSSFRow dataRow = (XSSFRow)(sheet.CreateRow(rowIndex));

                foreach (DataColumn column in dt.Columns)
                {
                    XSSFCell c = (XSSFCell)dataRow.CreateCell(column.Ordinal);
                    string val = row[column].ToString();

                    int x;
                    if (Int32.TryParse(val, out x) && (!String.IsNullOrEmpty(val)))//column.IsNumeric()
                    {
                        c.SetCellValue(Int64.Parse(val));
                        c.SetCellType(CellType.Numeric);
                    }
                    else
                    {
                        c.SetCellValue(row[column].ToString());
                    }

                    // no need to auto size all the time, after 100 is ok... (it costs a lot)
                    if (rowIndex == 100)
                    {
                        sheet.AutoSizeColumn(column.Ordinal);
                    }

                }

                rowIndex++;
            }
            //fStream.Flush();
            //workbook.Write(fStream);
            //return fStream;

            workbook.Write(ms);
            return ms;

        }
        catch (System.Exception ex)
        {
            Console.Write(ex);
            Environment.Exit(-1);
            return null;
        }


    }

I have tried this solution: What's causing “Session state has created a session id, but cannot save it because the response was already flushed by the application.”

void Session_Start(object sender, EventArgs e) 
{
    // Code that runs when a new session is started
    string sessionId = Session.SessionID;
}

但这并没有解决问题。 提前致谢, 珊瑚