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

828 Views Asked by At

My ASP.NET Core MVC project has several reports. To render the reports as PDF, I'm using AspNetCore.Reporting library.

This library works fine for a single report but due to some cache issues it throws an exception while generating another report. The solution I found on the internet was to run report generation as a new process but I don't know how to implement that.

I found the suggestion to use Tmds.ExecFunction to run report generation as a seperate process. But I dont know how to pass parameters to the function.

Here is my code:

  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);
1

There are 1 best solutions below

0
Dawood Jamil On

No Need to run report generation as a seperate process. Just Dont Pass extension as 1 in:

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

The Solution is:

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