Blazor FAQ - Error handling

How do you fix “The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time” error in Blazor Server application?

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
How do I resolve the error “The type arguments for method ‘TypeInference.CreateListViewTemplates_4(RenderTreeBuilder, int, int, RenderFragment)’ cannot be inferred from the usage. Try specifying the type arguments explicitly”?

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
How do I resolve the error “There was an unhandled exception on the current circuit, so this circuit will be terminated. For more information, turn on detailed exceptions in ‘CircuitOptions.DetailedErrors’.”?

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
How can I handle common errors like 404 in query string parameters?

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
How can I show a custom message when a customer’s connection is lost with the server?

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
‘ChildContent’: member names cannot be the same as their enclosing type. What does this mean?

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
How do you increase server timeout to prevent elapsing without receiving a message from the server?

Scenario: Invoke JS method call from .NET.

Here is how to increase JavaScript client timeout.

hubConnection.serverTimeoutInMilliseconds = 100000; // 100 second
Permalink
How do you handle 404 pages in Blazor?

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