NullReference Exception in Blazors RenderTreeBuilder

0

So I'm working on a school project. I use blazor in the frontend and FluentValidation to validate forms.

First, the exception:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=TemperBapes
  StackTrace:
   at TemperBapes.Pages.Register.BuildRenderTree(RenderTreeBuilder __builder)

I get the exception when calling the /Register page. I already had exceptions coming from the RenderTreeBuilder when my HTML was corrupt. I could always resolve the issues pretty fast so far. But I'm stuck with this one. Thats what my .razor file looks like:

@page "/Register"

<div class="card">
    <h5 class="card-header">Register</h5>
    <div class="card-body">
        <form>
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" class="form-control" id="username" placeholder="Enter username" @bind-value="User.Username" />
                <ValidationMessage For="() => User.Username"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="displayname">Display Name</label>
                <input type="text" class="form-control" id="displayname" placeholder="Enter your display name" @bind-value="User.DisplayName" />
                <ValidationMessage For="() => User.DisplayName"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="email">Email address</label>
                <input type="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" @bind-value="User.EMail" />
                <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
                <ValidationMessage For="() => User.EMail"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="tele">Tel</label>
                <input type="tel" class="form-control" id="tele" aria-describedby="telHelp" placeholder="Enter tel" @bind-value="User.Phonenumber" />
                <small id="telHelp" class="form-text text-muted">We'll never share your tel with anyone else.</small>
                <ValidationMessage For="() => User.Phonenumber"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="passwordfield">Password</label>
                <input type="password" class="form-control" id="passwordfield" placeholder="Password" @bind-value="User.Password" />
            </div>
            <button type="submit" class="btn btn-primary" @onclick="(() => SendRegister())">Submit</button>
        </form>
    </div>
</div>

@code{
    public AddUserDto User { get; set; }

    public void SendRegister()
    {
        
    }
}

The same exception gets thrown when the FluentValidation <ValidationMessage></ValidationMessage> is commented out, already tried that. Thank you all in advance.

html
rendering
blazor
fluentvalidation

1 Answer

1

You need to initialize your User like

 public AddUserDto User { get; set; } = new AddUserDto();

Because your user is null, the bindings like @bind-value="User.Password" can't work and throws the error when used by the RenderTreeBuilder.

If you fix this issue, the page will render. However, you will run into the next issue.

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Microsoft.AspNetCore.Components.Forms.ValidationMessage`1[System.String] requires a cascading parameter of type EditContext. For example, you can use Microsoft.AspNetCore.Components.Forms.ValidationMessage`1[System.String] inside an EditForm.
System.InvalidOperationException: Microsoft.AspNetCore.Components.Forms.ValidationMessage`1[System.String] requires a cascading parameter of type EditContext. For example, you can use Microsoft.AspNetCore.Components.Forms.ValidationMessage`1[System.String] inside an EditForm.
   at Microsoft.AspNetCore.Components.Forms.ValidationMessage`1[[System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnParametersSet()
   at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

The message here is pretty straight forward. You need to add an EditContext. To do so, replace your <form> with a <EditForm> and add the Model Property.

 <EditForm Model="User">
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" class="form-control" id="username" placeholder="Enter username" @bind-value="User.Username" />
                <ValidationMessage For="() => User.Username"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="displayname">Display Name</label>
                <input type="text" class="form-control" id="displayname" placeholder="Enter your display name" @bind-value="User.DisplayName" />
                <ValidationMessage For="() => User.DisplayName"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="email">Email address</label>
                <input type="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" @bind-value="User.EMail" />
                <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
                <ValidationMessage For="() => User.EMail"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="tele">Tel</label>
                <input type="tel" class="form-control" id="tele" aria-describedby="telHelp" placeholder="Enter tel" @bind-value="User.Phonenumber" />
                <small id="telHelp" class="form-text text-muted">We'll never share your tel with anyone else.</small>
                <ValidationMessage For="() => User.Phonenumber"></ValidationMessage>
            </div>
            <div class="form-group">
                <label for="passwordfield">Password</label>
                <input type="password" class="form-control" id="passwordfield" placeholder="Password" @bind-value="User.Password" />
            </div>
            <button type="submit" class="btn btn-primary" @onclick="(() => SendRegister())">Submit</button>
 </EditForm>

To learn more about the EditForm, I recommend the following article.

https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0

answered on Stack Overflow Jan 5, 2021 by Just the benno

User contributions licensed under CC BY-SA 3.0