Problem when binding to a property of a child object, or to a variable

Two classes : 

public partial class MfgInwardsReceiptHeader : BaseEntity, IMfgInwardsReceiptHeader
{
    ILookupSuppliers IMfgInwardsReceiptHeader.LookupSupplier { get => LookupSupplier; set => LookupSupplier = (LookupSuppliers)value; }
    public LookupSuppliers LookupSupplier
    {
        get { return GetValue (); }
        set { SetValue(value); }
    }
    
    [Key]
    public String ReceiptID
    {
        get { return GetValue (); }
        set { SetValue(value); }
    } 
}
 public partial class LookupSuppliers : BaseEntity, ILookupSuppliers { [Key] public Int32 SupplierID { get { return GetValue (); } set { SetValue(value); } } public String? SupplierName { get { return GetValue (); } set { SetValue(value); } } }

 IRHeader is the parent class, with a child navigation property to LookupSupplier. 

var IRHeader = new(MfgInwardsReceiptHeader); 
var supplierName = IRHeader.LookupSupplier?.SupplierName ?? "";

This produces an error when the page is rendered : 
2024-02-15 18:07:00.504 +13:00 [ERR] Unhandled exception in circuit 'AtcPa1oh6EHdUA2PQeRRgWdPHolgAB8f0insQGspjao'. System.NullReferenceException: Object reference not set to an instance of an object. at Syncfusion.Blazor.DataForm.FormItems.b__49_3(RenderTreeBuilder __builder5) at Microsoft.AspNetCore.Components.CascadingValue`1.Render(RenderTreeBuilder builder) at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

 None of the objects or properties are null. 
Instead of binding the second FormItem to IRHeader.LookupSupplier.SupplierName I tried binding it to the supplierName variable, but got the same error. 
If I comment out the second FormItem then the form does not produce an error. 

(I am using the Breeze framework to fetch data and populate the models; this also manages state, saving etc. I can get the form to work with a complex POCO not linked to any data source (using the example here : https://blazor.syncfusion.com/documentation/data-form/validation#complex-model-validation), but not when binding to a complex property on the Breeze object).
(FYI, I remember having trouble when editing a Breeze object in the SfGrid too - I had to stop the grid from cloning the object to make things work).

Please advise what I need to do to bind to a complex property that actually backs into an ORM like Entity Framework or Breeze, or to bind to a variable.

 Thanks

13 Replies

PA Paul February 15, 2024 11:58 PM UTC

Forgot the razor :


<SfDataForm

        Model="@IRHeader" ColumnCount="6" ColumnSpacing="20px">


    <FormValidator>

        <ObjectGraphDataAnnotationsValidator></ObjectGraphDataAnnotationsValidator>

    </FormValidator>


    <FormItems>

        <FormItem Field="@nameof(IRHeader.SupplierID)" LabelText="Supplier" ColumnSpan="2"></FormItem>

        <FormItem Field="IRHeader.LookupSupplier.SupplierName" LabelText="Supplier Name" ColumnSpan="2"></FormItem>

    </FormItems>

</SfDataForm>



YS Yohapuja Selvakumaran Syncfusion Team February 16, 2024 10:40 AM UTC

Hi Paul,


Thank you for sharing the details of your issue. We understand that you're encountering difficulties when binding to a property of a child object or a variable in your Blazor application.


Based on the provided classes and the code snippet for the SfDataForm component, We’ve reviewed your requirement and created a sample using a base class and a child class. You can find the sample at the following link:


Sample: https://blazorplayground.syncfusion.com/VZrpNLidqweeZNzo 


For further reference and details on complex model validation in Blazor using Syncfusion's SfDataForm component, please refer to the documentation provided at the following link:


Documentation:  https://blazor.syncfusion.com/documentation/data-form/validation#complex-model-validation



If you continue to encounter the same issue, We recommend modifying the shared sample to replicate the reported problem at our end. Please provide specific steps or details on how to reproduce the issue within the sample. Additionally, if possible, could you please provide a video illustration demonstrating the problem? This will help us better understand the issue and provide an accurate solution. Thank you for your cooperation.



Regards,

Yohapuja S



PA Paul February 19, 2024 04:09 AM UTC

I have modified your sample code and have two questions :

  1. why does "xyz" not show in the  CreateClient.ClientAddress.Street Formitem ?
  2. the commented FormItem is my attempt to bind to a variable - it does not work.  How do you bind to a variable?  Do you have to make a template and Sftextbox for example?


@using Syncfusion.Blazor.DataForm
@using System.ComponentModel.DataAnnotations
@using Syncfusion.Blazor.TreeGrid.Internal


<SfDataForm ID="MyForm" Model="CreateClient" OnValidSubmit="ValidSubmithanlder">
    <FormValidator>
        <ObjectGraphDataAnnotationsValidator></ObjectGraphDataAnnotationsValidator>
    </FormValidator>
    <FormItems>
        <FormGroup ColumnCount="6" ColumnSpacing="10px">
            <FormItem Field="@nameof(CreateClient.FirstName)" ColumnSpan="6"></FormItem>
            <FormItem Field="@nameof(CreateClient.LastName)" ColumnSpan="3"></FormItem>
            <FormItem Field="@nameof(CreateClient.Email)" ColumnSpan="3"></FormItem>
        </FormGroup>
        <FormGroup ColumnCount="2" ColumnSpacing="10px">
            <FormItem Field="@nameof(CreateClient.ClientAddress.Street)" ColumnSpan="1" Placeholder="Address"></FormItem>
            @*<FormItem Field="@myValue" ColumnSpan="1" Placeholder="Address"></FormItem>*@
            <FormItem Field="@nameof(CreateClient.ClientAddress.City)" ColumnSpan="1" Placeholder="City"></FormItem>
            <FormItem Field="@nameof(CreateClient.ClientAddress.State)" ColumnSpan="2" Placeholder="State"></FormItem>
            <FormItem Field="@nameof(CreateClient.ClientAddress.ZipCode)" ColumnSpan="2" Placeholder="ZipCode"></FormItem>
        </FormGroup>
    </FormItems>
    <FormButtons>
        <Syncfusion.Blazor.Buttons.SfButton>Submit</Syncfusion.Blazor.Buttons.SfButton>
    </FormButtons>
</SfDataForm>

@code{

    private EventRegistration CreateClient;
    private string myValue = "";

protected override async Task OnParametersSetAsync()
{
    CreateClient = new EventRegistration();
    CreateClient.ClientAddress = new();
    CreateClient.ClientAddress.Street = "xyz";
    //CreateClient = await Task<EventRegistration>.Run(() => {
    //    var aa = new EventRegistration();
    //    aa.ClientAddress = new();
    //    aa.ClientAddress.Street = "abc";  
    //   return aa; });
    myValue = CreateClient.ClientAddress.Street;
}

    public abstract class BaseAddress
    {
        [Required(ErrorMessage = "Street is required")]
        [Display(Name = "Street")]
        public string Street { get; set; }

        [Required(ErrorMessage = "City is required")]
        [Display(Name = "City")]
        public string City { get; set; }

        [Required(ErrorMessage = "State is required")]
        [Display(Name = "State")]
        public string State { get; set; }

        [Required(ErrorMessage = "Zip Code is required")]
        [Display(Name = "Zip Code")]
        [MinLength(5, ErrorMessage = "Zip Code must be at least 5 characters")]
        [MaxLength(10, ErrorMessage = "Zip Code cannot be more than 10 characters")]
        public string ZipCode { get; set; }
    }

    public class DefaultAddress : BaseAddress
    {
    }

    public class EventRegistration: BaseAddress
    {
        [Required(ErrorMessage = "Please enter your First Name.")]
        [Display(Name = "First Name")]
        public string FirstName { get; set; } = "Jack";

        [Required(ErrorMessage = "Please enter your last name.")]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "Please enter your email-ID.")]
        [Display(Name = "Email ID")]
        public string Email { get; set; }

        [ValidateComplexType]
        public DefaultAddress? ClientAddress { get; set; } = null;
    }

    private void ValidSubmithanlder()
    {
        // Handle form submission logic
    }
}


PA Paul February 20, 2024 10:09 PM UTC

Also, what is your recommended approach to binding to a nullable navigation property?

For example :

<FormItem Field="CreateClient.ClientAddress.Street" ColumnSpan="1" Placeholder="Address"></FormItem>

What if ClientAddress is null?


I suppose the same question could be asked of SfTextBox and other UI components too - what do you recommend when binding to a nullable navigation entity/property?



YS Yohapuja Selvakumaran Syncfusion Team February 23, 2024 04:52 PM UTC

Hi Paul,


We have considered the reported issue Console error occurs, when assigning value to the fields of the Dataform in the ParameterSetAsyncas a bug from our end and the fix for the issue will be included with our upcoming weekly release on March 6th, 2024.



Now you can track the status of the reported issue through the feedback below,

Feedback Link: https://www.syncfusion.com/feedback/51217/console-error-occurs-when-assigning-value-to-the-fields-of-the-dataform-in-the


Disclaimer: “Inclusion of this solution in the weekly release may change due to other factors including but not limited to QA checks and works reprioritization.


Regards,

Yohapuja S





JR Joe Robe March 26, 2024 03:01 PM UTC

The example makes no sense. Why is EventRegistration inheriting from address ? 

If I remove the inheritance, the script crashes. The data in the example does NOT bind to the Navigation Property !


See simple example:

https://blazorplayground.syncfusion.com/LZBpZqVRIKpTVMcj


This is what is happening on my form. Navigations seem not to work ( i am on latest 

25.1.35 version)



PA Paul April 8, 2024 05:04 AM UTC

I gave up on Syncfusion's response.

To make navigation properties work I have to use a template and check for null.

For example :


<FormItem Field="@nameof(IRHeader.SupplierID)" ID="suppliername" ColumnSpan="6">

    <Template>

        @if (IRHeader.LookupSupplier is null)

        {

            <SfTextBox Readonly="true"></SfTextBox>

        }

        else

        {

            <SfTextBox @bind-Value="@IRHeader.LookupSupplier.SupplierName" Readonly="true"></SfTextBox>

        }

    </Template>



YS Yohapuja Selvakumaran Syncfusion Team April 10, 2024 02:05 PM UTC

Hi Paul,

We would like to inform you that we have resolved the reported issue Console error occurs, when assigning value to the fields of the Dataform in the ParameterSetAsync" in our latest version “25.1.35”. Therefore, we recommend upgrading to our latest version to resolve the current issue.


Rootcause:

The conflicts arise due to the complex model structure and inheritance hierarchy, where both child and parent classes inherit properties from a single base class. These conflicts occur when manipulating property values directly and indirectly through nested objects using setvalue and getvalue methods. Introducing constant and property expressions exacerbates these conflicts, requiring precise object references. Resolving these conflicts entails a thorough review and refinement of object referencing and property manipulation mechanisms


Release Notes: https://blazor.syncfusion.com/documentation/release-notes/25.1.35?type=all#data-form



Regards,

Yohapuja S




DI Diego July 22, 2024 08:31 PM UTC

Hi Paul,


Have you managed to find a workaround for this problem?

I am using version 26.1.40 but I keep getting the following error:


Error: System.NullReferenceException: Object reference not set to an instance of an object.

   at Syncfusion.Blazor.DataForm.SfDataForm.GetNestedConstantExpression(Object model, String nestedPropertyName)

   at Syncfusion.Blazor.DataForm.SfDataForm.<>c__DisplayClass80_0.<RenderComponent>b__0(RenderTreeBuilder builder)

   at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)

   at Syncfusion.Blazor.DataForm.FormItems.<BuildRenderTree>b__39_3(RenderTreeBuilder __builder5)

   at Microsoft.AspNetCore.Components.CascadingValue`1.Render(RenderTreeBuilder builder)

   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)



YS Yohapuja Selvakumaran Syncfusion Team July 29, 2024 05:22 AM UTC

Hi Paul,

We apologize for the delay in our response. We have reviewed the issue you've reported and thoroughly tested it based on the provided code snippet. In our tests, we did not encounter any console errors, and the component rendered correctly. Please check the attached sample for reference.


A screenshot of a computer

Description automatically generated


To help us better understand and address the issue, we kindly request that you modify the shared sample to replicate the problem on our end. This will enable us to replicate the issue accurately and provide you with the most appropriate solution.


Thank you for your patience and cooperation. We're committed to assisting you and resolving this issue promptly.



Regards,

Yohapuja S



Attachment: Dataform_error_ceb562ef.zip


EG Etienne Gunslay replied to Yohapuja Selvakumaran August 6, 2024 09:23 AM UTC

The bug is not fix, i got the same problem when i try to put a complex object in my dataform model without inheritance 


@using Syncfusion.Blazor.DataForm

@using System.ComponentModel.DataAnnotations


<SfDataForm ID="MyForm" Model="CreateClient" OnValidSubmit="ValidSubmithanlder">

    <FormValidator>

        <ObjectGraphDataAnnotationsValidator></ObjectGraphDataAnnotationsValidator>

    </FormValidator>

    <FormItems>

        <FormGroup ColumnCount="6" ColumnSpacing="10px">

            <FormItem Field="@nameof(CreateClient.FirstName)" ColumnSpan="6"></FormItem>

            <FormItem Field="@nameof(CreateClient.LastName)" ColumnSpan="3"></FormItem>

            <FormItem Field="@nameof(CreateClient.Email)" ColumnSpan="3"></FormItem>

        </FormGroup>

        <FormGroup ColumnCount="2" ColumnSpacing="10px">

            <FormItem Field="@nameof(CreateClient.ClientAddress.Street)" ColumnSpan="1" Placeholder="Address"></FormItem>

            <FormItem Field="@nameof(CreateClient.ClientAddress.City)" ColumnSpan="1" Placeholder="City"></FormItem>

            <FormItem Field="@nameof(CreateClient.ClientAddress.State)" ColumnSpan="2" Placeholder="State"></FormItem>

            <FormItem Field="@nameof(CreateClient.ClientAddress.ZipCode)" ColumnSpan="2" Placeholder="ZipCode"></FormItem>

        </FormGroup>

    </FormItems>

    <FormButtons>

        <Syncfusion.Blazor.Buttons.SfButton>Submit</Syncfusion.Blazor.Buttons.SfButton>

    </FormButtons>

</SfDataForm>


@code {


    private EventRegistration CreateClient;

    private string myValue = "adress";


    protected override async Task OnParametersSetAsync()

    {

        // Call base method if needed

        await base.OnParametersSetAsync();


        // Assuming you have an instance of EventRegistration named CreateClient

        if (CreateClient == null)

        {

            CreateClient = new EventRegistration();

        }


        // Set the value of the Street field

        CreateClient.ClientAddress.Street = "123 Main St";

        StateHasChanged();

    }


    public class BaseAddress

    {

        [Required(ErrorMessage = "Street is required")]

        [Display(Name = "Street")]

        public string Street { get; set; }


        [Required(ErrorMessage = "City is required")]

        [Display(Name = "City")]

        public string City { get; set; }


        [Required(ErrorMessage = "State is required")]

        [Display(Name = "State")]

        public string State { get; set; }


        [Required(ErrorMessage = "Zip Code is required")]

        [Display(Name = "Zip Code")]

        [MinLength(5, ErrorMessage = "Zip Code must be at least 5 characters")]

        [MaxLength(10, ErrorMessage = "Zip Code cannot be more than 10 characters")]

        public string ZipCode { get; set; }

    }


    public class EventRegistration

    {

        [Required(ErrorMessage = "Please enter your First Name.")]

        [Display(Name = "First Name")]

        public string FirstName { get; set; } = "Jack";


        [Required(ErrorMessage = "Please enter your last name.")]

        [Display(Name = "Last Name")]

        public string LastName { get; set; }


        [Required(ErrorMessage = "Please enter your email-ID.")]

        [Display(Name = "Email ID")]

        public string Email { get; set; }


        [ValidateComplexType]

        public BaseAddress ClientAddress { get; set; } = new BaseAddress();

    }


    private void ValidSubmithanlder()

    {

        // Handle form submission logic

    }

}



EG Etienne Gunslay replied to Etienne Gunslay August 6, 2024 09:25 AM UTC

ArgumentNullException: Value cannot be null. (Parameter 'element')

  • System.ArgumentNullException.Throw(string paramName)

  • System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, bool inherit)

  • System.Attribute.GetCustomAttribute(MemberInfo element, Type attributeType, bool inherit)

  • System.Reflection.CustomAttributeExtensions.GetCustomAttribute<T>(MemberInfo element)

  • Syncfusion.Blazor.DataForm.FormItems.<BuildRenderTree>b__39_3(RenderTreeBuilder __builder5)

  • Microsoft.AspNetCore.Components.CascadingValue<TValue>.Render(RenderTreeBuilder builder)

  • Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, out Exception renderFragmentException



YS Yohapuja Selvakumaran Syncfusion Team August 23, 2024 01:05 PM UTC

Hi Etienne,



We sincerely apologize for the delay in getting back to you. We greatly appreciate your patience.


After thoroughly validating the reported issue using our latest package and the code snippet you provided, we were unable to reproduce any console errors. The validation appears to be working as expected on our end. To assist you further, we’ve attached a sample for your reference, which you can review to ensure everything aligns with your setup


A screenshot of a computer

Description automatically generated


To help us better understand and replicate the issue, we kindly ask if you could modify the attached sample to demonstrate the problem you're encountering. This will allow us to investigate more effectively and provide a more accurate solution.


Thank you for your cooperation and understanding. We're here to support you, so please don’t hesitate to reach out with any further details or questions.



Regards,

Yohapuja S




Attachment: Dataform_error_ceb562ef_(2)_c98d0cb0.zip

Loader.
Up arrow icon