在 ASP.NET Core 中呈现 RDLC 报告时出现索引超出范围异常

Posted

技术标签:

【中文标题】在 ASP.NET Core 中呈现 RDLC 报告时出现索引超出范围异常【英文标题】:Index Out of Bound exception while rendering RDLC Reports in ASP.NET Core 【发布时间】:2022-01-14 20:58:48 【问题描述】:

我的 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);

【问题讨论】:

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

【讨论】:

以上是关于在 ASP.NET Core 中呈现 RDLC 报告时出现索引超出范围异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 的自定义 TagHelper 中呈现 Razor 模板?

ASP.NET Core MVC:无法在表单标签内呈现字段

csharp 在ASP.NET中流式传输和下载RDLC报告

asp.net core 注入后仍然报错?

ASP.NET Core 6框架揭秘实例演示[32]:错误页面的N种呈现方式

ef在asp.net中删除报值不能为空的原因