在 ASP.NET Core 中呈现 RDLC 报告时出现索引越界异常

Index Out of Bound exception while rendering RDLC Reports in ASP.NET Core

提问人:Dawood Jamil 提问时间:12/10/2021 最后编辑:Dawood Jamil 更新时间:12/13/2021 访问量:730

问:

我的 ASP.NET Core MVC 项目有几个报告。为了将报告呈现为 PDF,我使用了库。AspNetCore.Reporting

此库适用于单个报表,但由于某些缓存问题,它在生成另一个报表时会引发异常。我在互联网上找到的解决方案是将报告生成作为一个新流程运行,但我不知道如何实现它。

我发现建议使用 Tmds.ExecFunction 将报告生成作为单独的进程运行。但是我不知道如何将参数传递给函数。

这是我的代码:

  string ReportName = "invoiceDine";
            DataTable dt = new DataTable();
            dt = GetInvoiceItems(invoiceFromDb.Id);
            Dictionary<string, string> param = new Dictionary<string, string>();
            param.Add("bParam", $"{invoiceFromDb.Id}");
            param.Add("gParam", $"{salesOrderFromDb.Guests}");
            param.Add("tParam", $"{invoiceFromDb.Table.Table}");
            param.Add("dParam", $"{invoiceFromDb.Time}");
            param.Add("totalP", $"{invoiceFromDb.SubTotal}");
            param.Add("t1", $"{tax1}");
            param.Add("t2", $"{tax2}");
            param.Add("tA1", $"{tax1Amount}");
            param.Add("tA2", $"{tax2Amount}");
            param.Add("AT1", $"{totalAmountWithTax1}");
            param.Add("AT2", $"{totalAmountWithTax2}");
            param.Add("terminalParam", $"{terminalFromDb.Name}");
            param.Add("addressParam", $"{t.Address}");
            param.Add("serviceParam", "Service Charges of applicable on table of " + $"{personForServiceCharges}" + " & Above");
            var result = reportService.GenerateReport(ReportName, param, "dsInvoiceDine", dt);
            return File(result,"application/Pdf");


This is my version of the function:                                     
``` public byte[] GenerateReport(string ReportName, Dictionary<string,string> Parameters,string DataSetName,DataTable DataSource )
        {
            string guID = Guid.NewGuid().ToString().Replace("-", "");
            string fileDirPath = Assembly.GetExecutingAssembly().Location.Replace("POS_Website.dll", string.Empty);

            string ReportfullPath = Path.Join(fileDirPath, "\\Reports");
            string JsonfullPath = Path.Join(fileDirPath,"\\JsonFiles");

            string rdlcFilePath = string.Format("{0}\\{1}.rdlc", ReportfullPath, ReportName);
            string generatedFilePath = string.Format("{0}\\{1}.pdf", JsonfullPath, guID);
            string jsonDataFilePath = string.Format("{0}\\{1}.json", JsonfullPath, guID);
            File.WriteAllText(jsonDataFilePath, JsonConvert.SerializeObject(DataSource));

            FunctionExecutor.Run((string[] args) =>
            {
            // 0 : Data file path - jsonDataFilePath 
            // 1 : Filename - generatedFilePath 
            // 2 : RDLCPath - rdlcFilePath 
            ReportResult result;
           
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Encoding.GetEncoding("windows-1252");
            LocalReport report = new LocalReport(args[2]);
            DataTable dt = JsonConvert.DeserializeObject<DataTable>(File.ReadAllText(args[0]));
            report.AddDataSource(args[3], dt);
            result = report.Execute(RenderType.Pdf, 1,Parameters);

                using (var fs = new FileStream(args[1], FileMode.Create, FileAccess.Write))
                {
                    fs.Write(result.MainStream);
                }
            }, new string[] {jsonDataFilePath, generatedFilePath, rdlcFilePath, DataSetName });

            var memory = new MemoryStream();
            using (var stream = new FileStream(Path.Combine("", generatedFilePath), FileMode.Open))
            {
                stream.CopyTo(memory);
            }

            File.Delete(generatedFilePath);
            File.Delete(jsonDataFilePath);
            memory.Position = 0;
            return memory.ToArray();
        }
                                                                        
But it throws exception "Field marshaling is not supported by ExecFunction" on line: 
 var result = reportService.GenerateReport(ReportName, param, "dsInvoiceDine", dt);
asp.net-core asp.net-core-mvc 动态 rdlc-generation

评论

0赞 Dawood Jamil 12/10/2021
这是一个建议,但如何将参数传递给函数 [github.com/amh1979/AspNetCore.Reporting/issues/...
0赞 mcalex 12/10/2021
是哪一行导致了错误?你能包括所有代码,包括调用此方法的方法吗?此外,对问题进行编辑。评论垫是非永久性的。
0赞 Dawood Jamil 12/10/2021
@mcalex 您能否帮助我了解如何将我的报表生成逻辑移动到控制台应用程序,然后从我的 Asp.Net 核心 mvc 应用程序作为新流程运行该控制台应用程序。
0赞 Dawood Jamil 12/10/2021
在过去的两周里,我一直被这个错误所困扰。我将非常感谢任何帮助。
0赞 mcalex 12/10/2021
这些模板字符串是否在您的实际代码中?诸如:“您的 DLL 名称”、“您的 RDLC 名称”和“您获取数据的服务方法”等?

答:

0赞 Dawood Jamil 12/13/2021 #1

无需将报告生成作为单独的过程运行。只是不要将扩展名传递为 1 在:

 var result = localReport.Execute(RenderType.Pdf, 1, param);

解决方案是:

  int ext = (int)(DateTime.Now.Ticks >> 10);
  var result = localReport.Execute(RenderType.Pdf, ext, param);