VahidN/PdfReport.Core

Object refs when display formula on column

andreykhr opened this issue · 4 comments

Summary of the issue

Report generator fails on Object reference not set to an instance of an object when I add builder.DisplayFormatFormula(o =>.

So I need to translate enum Currency to string at rendering. I expected, that this method is correct for this. Am I right?

I`m don't understand why Its fails. Suppose more described exceptions will more understandable.

  1. What correct way to format column item
  2. Please do more understandable exceptions.

Environment

Rider 2018.1
OS X 10.14.2
dotnet core 2.1

Example code/Steps to reproduce:

                columns.AddColumn(column =>
                {
                    column.PropertyName<TransferPackageIN_A26SupplyActRequirement>(x => x.Currency);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(3.2f);
                    column.HeaderCell("Валюта", horizontalAlignment: HorizontalAlignment.Center);
                    column.ColumnItemsTemplate(builder =>
                    {
                        builder.DisplayFormatFormula(o =>
                        {
//                            Currency currency = (Currency) o;
//                            switch (currency)
//                            {
//                                case Currency.RUB:
//                                    return "руб.";
//                                case Currency.USD:
//                                    return "дол.";
//                                case Currency.EUR:
//                                    return "евр.";
//                                default:
//                                    return currency.ToString();
//                            }
                            return "test";
                        });
                    });
                    column.AggregateFunction(builder =>
                    {
                        builder.CustomAggregateFunction(new CurrencyAggregateFunc());
                    });
                });

Output:

Exception message:
Object reference not set to an instance of an object
Full Stack trace:
System.NullReferenceException: Object reference not set to an instance of an object.
   at PdfRpt.FluentInterface.ColumnItemsTemplateBuilder.DisplayFormatFormula(Func`2 formula)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_19(ColumnItemsTemplateBuilder builder) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 456
   at PdfRpt.FluentInterface.ColumnAttributesBuilder.ColumnItemsTemplate(Action`1 columnItemsTemplateBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_10(ColumnAttributesBuilder column) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 454
   at PdfRpt.FluentInterface.MainTableColumnsBuilder.AddColumn(Action`1 pdfColumnAttributesBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_1(MainTableColumnsBuilder columns) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 446
   at PdfRpt.FluentInterface.PdfReport.MainTableColumns(Action`1 mainTableColumnsBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.AppendMainTableColumns(PdfReport pdfReport) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 375
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.RenderPDF(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 101
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.ProcessData(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 43
fail: RosbankFactoring.Reports.Acts.ActsReportGenerator[0]
      При формировании отчета [акт уступка] с параметрами [concessionActCode: С001202; supplyCode: С001202] возникла ошибка.
System.NullReferenceException: Object reference not set to an instance of an object.
   at PdfRpt.FluentInterface.ColumnItemsTemplateBuilder.DisplayFormatFormula(Func`2 formula)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_19(ColumnItemsTemplateBuilder builder) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 456
   at PdfRpt.FluentInterface.ColumnAttributesBuilder.ColumnItemsTemplate(Action`1 columnItemsTemplateBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_10(ColumnAttributesBuilder column) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 454
   at PdfRpt.FluentInterface.MainTableColumnsBuilder.AddColumn(Action`1 pdfColumnAttributesBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_1(MainTableColumnsBuilder columns) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 446
   at PdfRpt.FluentInterface.PdfReport.MainTableColumns(Action`1 mainTableColumnsBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.AppendMainTableColumns(PdfReport pdfReport) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 375
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.RenderPDF(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 101
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.ProcessData(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 43
   at RosbankFactoring.Reports.Acts.ActsReportGenerator.Generate(Stream ms, Filter filter) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/ActsReportGenerator.cs:line 51
fail: RosbankFactoring.Api.Controllers.Reports.ActsController[0]
      Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
   at PdfRpt.FluentInterface.ColumnItemsTemplateBuilder.DisplayFormatFormula(Func`2 formula)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_19(ColumnItemsTemplateBuilder builder) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 456
   at PdfRpt.FluentInterface.ColumnAttributesBuilder.ColumnItemsTemplate(Action`1 columnItemsTemplateBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_10(ColumnAttributesBuilder column) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 454
   at PdfRpt.FluentInterface.MainTableColumnsBuilder.AddColumn(Action`1 pdfColumnAttributesBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.<>c.<AppendMainTableColumns>b__12_1(MainTableColumnsBuilder columns) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 446
   at PdfRpt.FluentInterface.PdfReport.MainTableColumns(Action`1 mainTableColumnsBuilder)
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.AppendMainTableColumns(PdfReport pdfReport) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 375
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.RenderPDF(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 101
   at RosbankFactoring.Reports.Acts.Providers.PdfProcessProvider.ProcessData(TransferPackageIN_A26 package) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/Providers/PdfProcessProvider.cs:line 43
   at RosbankFactoring.Reports.Acts.ActsReportGenerator.Generate(Stream ms, Filter filter) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/libs/RosbankFactoring.Reports/Acts/ActsReportGenerator.cs:line 51
   at RosbankFactoring.Api.Controllers.Reports.ActsController.Get(String concessionActCode, String supplyCode) in /Users/andreykhr/src/projects/rbf_versionsFix/RosbankFactoring/src/app/RosbankFactoring.Api/Controllers/Reports/ActsController.cs:line 53

If your o is null, you should check it first. right?

column.ColumnItemsTemplate(template =>
{
       template.TextBlock();
       template.DisplayFormatFormula(obj => obj == null || string.IsNullOrEmpty(obj.ToString())
                                                            ? string.Empty : string.Format("{0:n0}", obj));
});

Also just search for DisplayFormatFormula here , you can find a lot of samples about it

Okay, I figured it out!

First I test it without o, just return 'test' phrase. It fails to.

                    column.ColumnItemsTemplate(builder =>
                    {
                        builder.DisplayFormatFormula(c => "test");
                    });                   

After some research, found that I dot set template.TextBlock();. So I`d test it with this block and It worked. Thanks for your comment!

But I go deeper and found that in PdfRpt.FluentInterface.ColumnItemsTemplateBuilder method DisplayFormatFormula wave logical bug. this._columnItemsTemplate not have initialisation by default. So, if user don't init it with some TextBlock() or MonthCalendar() methods it fails on null refs exception if (this._columnItemsTemplate.BasicProperties == null) because this._columnItemsTemplate is null.

    public void DisplayFormatFormula(Func<object, string> formula)
    {
      if (this._columnItemsTemplate.BasicProperties == null)
        this._columnItemsTemplate.BasicProperties = new CellBasicProperties();
      this._columnItemsTemplate.BasicProperties.DisplayFormatFormula = formula;
    }

Fluent interface is not force user to set this property. I we have two way to fix it

  1. Create default initialisation. Something like TextBlock()
  2. Add checking for null and throw Exception to user with some help description. Something like this:
        public void DisplayFormatFormula(Func<object, string> formula)
        {
            if (this._columnItemsTemplate == null)
                throw new Exception("ColumnItemsTemplate is not initialised. Please call CustomTemplate() or one of predefined methods to init it TextBlock(), MonthCalendar(), ....");
                    
            if (this._columnItemsTemplate.BasicProperties == null)
                this._columnItemsTemplate.BasicProperties = new CellBasicProperties();
            this._columnItemsTemplate.BasicProperties.DisplayFormatFormula = formula;
        }

It will be more predictable way for library. @VahidN That do u think?

Its samples are clear. don't make it unnecessarily complicated.

lock commented

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related problems.