DataForm is showing the wrong property with complex objects

I have the following class hierarchy in my Blazor control.

class GrandChild

{

    public string Description { get; set; } = "Grandchild Description";

}


class Child

{

    public string Description { get; set; } = "Child Description";

    public GrandChild GrandChild { get; set; } = new();

}


class Parent

{

    public string Description { get; set; } = "Parent Description";

    public Child Child { get; set; } = new();

};


partial class Index

 {


    Parent? Parent { get; set; } = new();


    protected override void OnInitialized()

    {


    }



}
And my razor view looks like so:

<PageTitle>Index</PageTitle>


<h1>Hello, world!</h1>


Welcome to your new app.




<SfDataForm Model="@Parent">

    <FormItems>

        <FormItem Field="@nameof(Parent.Description)" LabelText="Parent Description" IsEnabled="false"> </FormItem>

        <FormItem Field="@nameof(Parent.Child.Description)" LabelText="Child Description" IsEnabled="false"> </FormItem>

        <FormItem Field="@nameof(Parent.Child.GrandChild.Description)" LabelText="Grandchild Description" IsEnabled="false"> </FormItem>

    </FormItems>

</SfDataForm>

In the output it is showing only the Parent control description 3 times over instead of child and grandchild description


Attachment: Screenshot_20241107_121533_5a2b1fa3.zip

2 Replies

CG Chris Gilliam November 7, 2024 10:30 AM UTC

Update: If I change the code as follows:

class GrandChild

{

    public string Description2 { get; set; } = "Grandchild Description";

}


class Child

{

    public string Description1 { get; set; } = "Child Description";

    public GrandChild GrandChild { get; set; } = new();

}


class Parent

{

    public string Description { get; set; } = "Parent Description";

    public Child Child { get; set; } = new();

};


And update Razor :

<SfDataForm Model="@Parent">

    <FormGroup LabelText="Parent Information" ID="parent-information-group">

        <FormItems>

            <FormItem Field="@nameof(Parent.Description)" LabelText="Parent Description"> </FormItem>

            <FormItem Field="@nameof(Parent.Child.Description1)" LabelText="Child Description"> </FormItem>

            <FormItem Field="@nameof(Parent.Child.GrandChild.Description2)" LabelText="Grandchild Description"> </FormItem>

        </FormItems>

    </FormGroup>

</SfDataForm>

I now get an Exception:

  • 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.Rendering.RenderTreeBuilder.AddContent(int sequence, RenderFragment fragment)

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

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

    • Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.HandleException(Exception exception)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.HandleExceptionViaErrorBoundary(Exception error, ComponentState errorSourceOrNull)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

    • Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.HandleException(Exception exception)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender()

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(int componentId, RenderFragment renderFragment)

    • Microsoft.AspNetCore.Components.RenderHandle.Render(RenderFragment renderFragment)

    • Microsoft.AspNetCore.Components.Endpoints.SSRRenderModeBoundary.SetParametersAsync(ParameterView parameters)

    • Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)

    • Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.HandleException(Exception exception)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.HandleExceptionViaErrorBoundary(Exception error, ComponentState errorSourceOrNull)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToPendingTasksWithErrorHandling(Task task, ComponentState owningComponentState)

    • Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)

    • Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)

    • Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(int componentId, ParameterView initialParameters)

    • Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(IComponent component, ParameterView initialParameters)

    • Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer+<>c__DisplayClass35_0.<PrerenderComponentAsync>b__0()

    • Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<InvokeAsync>g__Execute|9_0<TResult>(ValueTuple<AsyncTaskMethodBuilder<TResult>, Func<TResult>, RendererSynchronizationContext> state)

    • Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.PrerenderComponentAsync(HttpContext httpContext, Type componentType, IComponentRenderMode prerenderMode, ParameterView parameters, bool waitForQuiescence)

    • System.Threading.Tasks.ValueTask<TResult>.get_Result()

    • Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)

    • Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)

    • SyncFusionComboDemo.Pages.Pages__Host.<ExecuteAsync>b__14_1()

    • Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()

    • SyncFusionComboDemo.Pages.Pages__Host.ExecuteAsync()

    • Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)

    • Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)

    • Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)

    • Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)

    • Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)

    • Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)

    • Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

    • Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)



YS Yohapuja Selvakumaran Syncfusion Team December 3, 2024 06:29 AM UTC

Hi Chris Gilliam,

Thank you for reaching out to us.


We would like to inform you that to handle common properties efficiently across multiple classes, you can introduce a base class that encapsulates these shared properties. The other classes can then inherit from this base class, ensuring consistency and reusability in your application design.


To assist you, we have created a sample demonstrating this approach. You can explore it using the link below:


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


For more details on implementing validation and handling complex models, you can refer to our documentation:


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


If you need further assistance or clarification, please feel free to get back to us. We are happy to help you with any additional queries!




Regards,

Yohapuja S



Loader.
Up arrow icon