Null reference exception when click to show detail in Master-Detail component

Hello,

I'm trying out the Syncfusion components (v18.1.0.59) in a server-side Blazor project, using Visual Studio 2019 Enterprise (v16.6.3).  The data is coming from a MariaDB instance hosted on a Raspberry Pi 4.  I'm bringing that in using EF Core and the relevant package dependency (MySql.Data.EntityFrameworkCore v8.0.20).  No problem retrieving the data.

I tried to follow the guidance at https://www.syncfusion.com/blogs/post/creating-a-master-detail-view-is-easier-with-blazor-datagrid.aspx for making a component that allows the user to drill into a particular stock (aka instrument) to see the price history for that stock.  In the database, foreign keys are set up, one joining the Instruments table to the Prices table on the InstrumentID.

There were errors at first referring to a self-referencing loop.  I got round that by adorning the relationship property in the Instruments class with: [JsonIgnore] and [IgnoreDataMember].  If I keep to this approach, it will be necessary to remember to edit the class file each time the model is refreshed from the database.  I believe the problem comes from Syncfusion using Newtonsoft's JsonSerializer which, by default, processes each object by value instead of by reference.  Anyway, it would be great if Syncfusion were able to address this so that auto-generated class files don't need to be hand-edited.

Moving on, I made the Detail template per the Master-Detail page guidelines and have since been faced with a null reference exception.  That error refers to the grid columns in the Detail template but I can't see why.  I've tried a few approaches and experiments, trying to narrow things down.  One of which, so as to match the tutorial, was to comment out the relationship properties in the Instruments and Prices classes and to retrieve the data each in a separate call - this to better mimic the tutorial.  Same null reference error.  While the page renders fine, showing a grid of instruments, the error comes when I click the down-arrow to see the detail.

I don't seem to be able to paste images inline - please believe me when I say that both the instruments and prices lists are being returned bulging with data.  For the simplest troubleshooting, I've set the Query attribute to look for a hard-coded value (an InstrumentID that is definitely in the database).  When debugging, I can see that @prices is populated and that the context-based instrument has the expected ID.  The field names use the same camel-cased spelling as in the underlying classes.

@page "/datamaintenance"
@using Data
@using Microsoft.EntityFrameworkCore
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Grids
@inject DbContextOptions<FinancesContext> DbContext
@inject FinancesService service
@inject NavigationManager navManager

<h3>Data Maintenance</h3>

<SfGrid DataSource="@instruments">
    <GridTemplates>
        <DetailTemplate>
            @{
                var instrument = (context as Instruments);

                Console.WriteLine(instrument.InstrumentId);
                Console.WriteLine("Wait here to inspect");

               <SfGrid DataSource="@prices" TValue="Prices" Query="@(new Query().Where("InstrumentId", "equal", 6))" AllowPaging="true">
                   <GridPageSettings PageSize="10"></GridPageSettings>
                   <GridColumn Field=@nameof(Prices.PriceDate) HeaderText="Price Date"></GridColumn>
                   <GridColumn Field=@nameof(Prices.CurrentPriceUsd) HeaderText="Current Price ($)" Format="N"></GridColumn>
               </SfGrid>
            }
            
        </DetailTemplate>
    </GridTemplates>
    <GridColumns>
        <GridColumn Field="InstrumentId" Visible="false"></GridColumn>
        <GridColumn Field="InstrumentName" HeaderText="Instrument"></GridColumn>
    </GridColumns>
</SfGrid>

@code {
    private List<Instruments> instruments;
    private List<Prices> prices;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            instruments = await service.GetInstrumentsAsync();
            prices = await service.GetPricesAsync();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    private void RowSelectHandler(RowSelectEventArgs<Instruments> args)
    {
        Console.WriteLine(args.Data.InstrumentId);
    }

}

As a side point, it would be nice to know why some of the documentation uses syntax along the lines of Field="InstrumentId" , other parts use @nameof(Instruments.InstrumentId).  Is there a difference behind the scenes?

Any assistance getting past this will be much appreciated.  Many thanks.

3 Replies 1 reply marked as answer

VN Vignesh Natarajan Syncfusion Team July 7, 2020 06:53 AM UTC

Hi Sebastian,  
 
Greetings from Syncfusion support.  
 
Query1: “it would be great if Syncfusion were able to address this so that auto-generated class files don't need to be hand-edited. 
 
We are glad to announce that our Essential Studio 2020 Volume 2 release v18.2.0.44  is rolled out and is available for download under the following link. Kindly upgrade to latest version by installing the build from below link or by updating the Nuget package (Syncfusion.Blazor) to our latest version 18.2.0.44  
 
 
 
Please find the changes we have done and bugs included in this release from below 
 
 
We suspect that the reported issue you are facing (circular reference error) while using navigation or foreignkey properties from your database is due to serialization of datasource property in Grid. But we have fixed the reported issue in our 2020 Volume 2 release by improving the data binding in Grid. So kindly ensure the reported issue by upgrading the our Nuget package to latest version.  
 
Please get back to us if you have further queries. 
 
Query: “While the page renders fine, showing a grid of instruments, the error comes when I click the down-arrow to see the detail. 
 
We have validated the reported issue and found that you have defined the GridColumns tag wrongly in detail template Grid. Hence the reported issue has occurred. Refer the below code example (highlighted code) for the missing error.  
 
<SfGrid DataSource="@instruments"> 
        <GridTemplates> 
            <DetailTemplate> 
                @{ 
                    var instrument = (context as Instruments); 
                    Console.WriteLine(instrument.InstrumentId); 
                    Console.WriteLine("Wait here to inspect"); 
  
                    <SfGrid DataSource="@prices" TValue="Prices" Query="@(new Query().Where("InstrumentId""equal", 6))" AllowPaging="true"> 
                        <GridPageSettings PageSize="10"></GridPageSettings> 
                        <GridColumns> 
                            <GridColumn Field=@nameof(Prices.PriceDate) HeaderText="Price Date"></GridColumn> 
                            <GridColumn Field=@nameof(Prices.CurrentPriceUsd) HeaderText="Current Price ($)" Format="N"></GridColumn> 
                        </GridColumns> 
                    </SfGrid> 
                } 
            </DetailTemplate> 
        </GridTemplates> 
        <GridColumns> 
            <GridColumn Field="InstrumentId" Visible="false"></GridColumn> 
            <GridColumn Field="InstrumentName" HeaderText="Instrument"></GridColumn> 
        </GridColumns> 
    </SfGrid> 
 
 
Kindly modify your code example above to resolve the reported issue.  
 
Refer our UG documentation for your reference 
 
 
Please get back to us if you have further queries.  
 
Regards, 
Vignesh Natarajan 


Marked as answer

SC Sebastian Crewe July 7, 2020 11:15 AM UTC

I'm very impressed - your prompt and helpful response has resolved the problem.

Regarding the missing <GridColumns> tag, that was idiotic of me - not seeing the wood for the trees.  Thank you.

Meanwhile, the updated package does seem to have resolved the error regarding self-referencing loops.  Bravo.  I reinstated the relationship properties in the underlying classes and then used an Include in my service class to get the prices at the same time as the instruments.  

    return await _context.Instruments.OrderBy(s => s.InstrumentName)
                    .Include(m => m.Prices)
                    .ToListAsync()

With this as my only object in the razor component, I can get at the prices as follows (this for others trying to get this working):

<SfGrid DataSource="@instruments">
    <GridTemplates>
        <DetailTemplate>
            @{
                if (context is Instruments instrument)
                {
                    <SfGrid DataSource="@instrument.Prices" TValue="Prices" AllowPaging="true">
                        <GridPageSettings PageSize="10"></GridPageSettings>
                        <GridColumns>
                            <GridColumn Field=@nameof(Prices.PriceDate) HeaderText="Price Date"></GridColumn>
                            <GridColumn Field=@nameof(Prices.CurrentPriceUsd) HeaderText="Current Price ($)" Format="N"></GridColumn>
                            <GridColumn Field="@nameof(Prices.PreviousClosePriceUsd)" HeaderText="Previous Close ($)" Format="N"></GridColumn>
                            <GridColumn Field=@nameof(Prices.CurrentPriceGbp) HeaderText="Current Price ($)" Format="C"></GridColumn>
                            <GridColumn Field="@nameof(Prices.PreviousClosePriceGbp)" HeaderText="Previous Close (£)" Format="C"></GridColumn>
                        </GridColumns>
                    </SfGrid>
                }
            }
            
        </DetailTemplate>
    </GridTemplates>
    <GridColumns>
        <GridColumn Field="InstrumentId" Visible="false"></GridColumn>
        <GridColumn Field="InstrumentName" HeaderText="Instrument"></GridColumn>
    </GridColumns>
</SfGrid>

Since I'm referencing the context variable in the Detail template, there's no need to have the Query attribute that was used when two different data sources were 'in play'.  It's working beautifully.

Many thanks for your good assistance.


VN Vignesh Natarajan Syncfusion Team July 8, 2020 07:24 AM UTC

Hi Sebastian, 
  
Thanks for your overwhelming response.  
  
We are glad to hear that you query has been resolved by our solution.  
  
Kindly get back to us if you have further queries.   
  
Regards, 
Vignesh Natarajan 


Loader.
Up arrow icon