Blazor FAQ - Error handling

Find answers for the most frequently asked questions
Expand All Collapse All

In a Blazor Server application, if you want to use both AllowCredentials() and AllowAnyOrigin() with respect to CORS settings, then add SetIsOriginAllowed(Func<string,bool> predicate) under ConfigureServices in the Startup.cs file instead of using AllowAnyOrigin(). See the following code snippet. 

[Startup.cs] 

public void ConfigureServices(IServiceCollection services) 

{ 

        …… 

        …… 

        services.AddCors(options => 

        { 

        options.AddPolicy("Open", builder => 

        builder.SetIsOriginAllowed(_ => true). 

        AllowAnyMethod(). 

        AllowAnyHeader(). 

        AllowCredentials()); 

    }); 

} 

Refer to this link for more information. 

Permalink

This error would occur when the generic Blazor component is unable to infer the type argument from the parameters. So, the compiler does not know which type of argument is intended. To resolve this, provide the intended type parameter explicitly.

Refer to this link for more details.

Permalink

To resolve and get more information about the error, enable the ‘CircuitOptions.DetailedErrors’ configuration in the ConfigureServices method in Startup.cs file.

[Startup.cs]

public void ConfigureServices(IServiceCollection services)
{
   // . . .
   services.AddServerSideBlazor().AddCircuitOptions(option => { option.DetailedErrors = true; });
}

For the debug and development environment, initialize the IWebHostEnvironment and provide the web hosting environment information to the Startup constructor. Finally, add the AddCircuitOption configuration to the ConfigureServices method in the Startup.cs file.

[Startup.cs]

public class Startup
{
   // . . .
   public IWebHostEnvironment _env { get; }
   public Startup(IConfiguration configuration, IWebHostEnvironment env)
   {
       Configuration = configuration;
       _env = env;
   }

   public void ConfigureServices(IServiceCollection services)
   {
       // . . .
       services.AddServerSideBlazor().AddCircuitOptions(option =>
       {
           if (_env.IsDevelopment()) //Only add details when debugging.
           {
               option.DetailedErrors = true;
           }
       });
   }
}
Permalink

We can handle the 404 error for query string parameters by checking whether the query is available in the parameter. If the parameter is not found, we can handle the error. We can also log an exception in Visual Studio by using the service ILogger in the application.

[Product.razor]
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger

@if (details != null)
{
<h1>@details.ProductId</h1>
 <p>@details.Products</p>
}
else if (loadFailed)
{
    <h1>Product ID:@ProductId not found. Sorry, we could not load this product due to an error. Click <a href="/product-details/1001">here</a> to go back to first product page</h1>
    
}
else
{
  <h1>Loading...</h1>
}

@code {
    [Parameter] public int ProductId { get; set; }

    ProductDetails details;
    bool loadFailed;

    public List<ProductDetails> Data { get; set; }
    static ProductDetails Product_Details = new ProductDetails();

    protected override async Task OnParametersSetAsync()
    {
        try
        {
            loadFailed = false;
            details = await Product_Details.GetProductId(ProductId);
        }
        catch (Exception ex)
        {
            loadFailed = true;
            Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
        }
    }
    public class ProductDetails
    {
        public int ProductId { get; set; }
        public int In_Stock { get; set; }
        public int Sold { get; set; }
        public double Amount { get; set; }
        public string Country { get; set; }
        public string Product_Categories { get; set; }
        public string Products { get; set; }
        public string Order_Source { get; set; }
        public string Year { get; set; }
        public string Quarter { get; set; }

        public async Task<ProductDetails> GetProductId(int id)
        {
            List<ProductDetails> Product_Data = new List<ProductDetails>();
            Product_Data.Add(new ProductDetails { ProductId = 1001, In_Stock = 34, Sold = 51, Amount = 383, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Retail Outlets", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1002, In_Stock = 4, Sold = 423, Amount = 3595.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Sales Person", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1004, In_Stock = 38, Sold = 234, Amount = 1813.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Teleshopping", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1005, In_Stock = 42, Sold = 127, Amount = 952.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "App Store", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1005, In_Stock = 36, Sold = 89, Amount = 668, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Retail Outlets", Year = "FY 2015", Quarter = "Q2" });
            if (id == Product_Data[0].ProductId)
            {

                return Product_Data[0];
            }
            else if (id == Product_Data[1].ProductId)
            {

                return Product_Data[1];
            }
            else if (id == Product_Data[2].ProductId)
            {

                return Product_Data[2];
            }
            else if (id == Product_Data[3].ProductId)
            {

                return Product_Data[3];
            }
            else if (id == Product_Data[4].ProductId)
            {

                return Product_Data[4];
            }
            else if(id == Product_Data[5].ProductId)
            {
                return Product_Data[5];
            }

            return null;
        }
    }
}

You can download the reference sample here

Permalink

Blazor will check for an HTML ID on initializing the HTML element. If such an ID does not exist on the page, then it will use the default handler to display messages. To display custom messages  on connection loss, we can define a div element with the ID components-reconnect-modal in the body of _Host.cshtml to manipulate the overlay that shows up in the case of a connection loss. If this element exists, this element’s class will be :

components-reconnect-show: A lost connection. The client is attempting to reconnect. Show the modal. Then, you can apply your custom styling to the screen overlay with CSS. If you want to remove them all, you can just choose not to display them at all.

components-reconnect-hide: An active connection is re-established to the server. Hide the modal.

components-reconnect-failed: Reconnection failed, probably due to a network failure. To attempt reconnection, call window.Blazor.reconnect().

components-reconnect-rejected: Reconnection rejected. The server was reached but refused the connection, and the user’s state on the server is lost. To reload the app, call location.reload().

Refer to this link for more details: https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-model-configuration?view=aspnetcore-3.1#reflect-the-connection-state-in-the-ui

[_Host.cshmtl]

<body>
……

<div id="components-reconnect-modal" class="my-reconnect-modal components-reconnect-hide">
<div class="show">
    <p>
        // Message when attempting to connect to server
    </p>
</div>
<div class="failed">
    <p>
        // Message when failing to connect
    </p>
</div>
<div class="rejected">
    <p>
        // Message when refused
    </p>
</div>
</div>

……
<app>
    @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>

</body>
[site.css]

    .my-reconnect-modal > div {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1000;
        overflow: hidden;
        background-color: #fff;
        opacity: 0.8;
        text-align: center;
        font-weight: bold;
    }

    .components-reconnect-hide > div {
        display: none;
    }

    .components-reconnect-show > div {
        display: none;
    }

    .components-reconnect-show > .show {
        display: block;
    }

    .components-reconnect-failed > div {
        display: none;
    }

    .components-reconnect-failed > .failed {
        display: block;
    }

    .components-reconnect-refused > div {
        display: none;
    }

    .components-reconnect-refused > .refused {
        display: block;
    }

You can download the reference sample here

Permalink

The parameter name and component (file) name should not be the same. They must be unique. For example, in the below code snippet the component name is ChildComponent so we cannot have a parameter with the same name it will not compile

[ChildComponent.razor]

<h2>Parent Title is: @Title</h2>
<button @onclick="UpdateParentsTitle">Update Title</button>
@code {
    //the parameter name cannot be ChildComponent since component name is ChildComponent
    [Parameter] public string Title { get; set; }

    [Parameter] public EventCallback<string> TitleChanged { get; set; }

    private async Task UpdateParentsTitle()
    {
        Title = "Hello, From Child Component!";
        await TitleChanged.InvokeAsync(Title);
    }
}

Permalink

The NotFound template section in the App.razor can be used to handling 404 pages. The router shows this content if it hits a route that is not available, which is a 404 page.

<Router AppAssembly="@typeof(Program).Assembly"> 
    <Found Context="routeData"> 
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> 
    </Found> 

    <NotFound> 
        <LayoutView Layout="@typeof(MainLayout)"> 
            <p>Handled 404 page</p> 
        </LayoutView> 
    </NotFound> 
</Router> 

Create a component Page/Error.razor to display the 404 contents. For more information, read about Blazor routing. 

Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.