Blazor 8.0 NavigateTo throws an exception

Kuler Master 386 Reputation points
2024-12-19T08:59:18.7133333+00:00

Hello,

I have a language selector that calls the following code and it works like a charm.

On other hand, I want to change the language from within the MainLayout on Initialized event (async) but then the very same code throws an exception of type NavigationException. No further explanation.

var cultureEscaped = languageFromURL == "en" ? "en-US" : "de-DE"; 
_navigationManager.NavigateTo($"Culture/Set?culture={cultureEscaped}&redirectUri=/");

The Culture is Controller and Set is an action.

The idea is to change the language if the language in the URL differs from the CultureInfo language. Maybe I should use another component instead of MainLayout? Please advice.

Thank you!

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,731 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,645 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,185 questions
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 69,121 Reputation points
    2024-12-23T17:19:00.79+00:00

    as you are calling NavigateTo during render it has to throw an error to stop processing (much like aborting a task). don't catch the error, or use OnAfterRender()

    also can not update the cookie, as httpcontext is readonly in a blazor app. the request created the signal/r connection and there is no response available. you should handle this logic before the blazor app starts with middleware.


1 additional answer

Sort by: Most helpful
  1. Kuler Master 386 Reputation points
    2024-12-23T07:53:13.7166667+00:00

    This is the code that I have at the moment and which throws that exception explained previously.

    protected override async Task OnParametersSetAsync()
    {
    
        var languageFromURL = string.Empty;
        var languageFromCulture = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
        var parts = _navigationManager.ToBaseRelativePath(_navigationManager.Uri.ToString()).Split('/');
    
        if (parts.Count() > 1)
        {
            languageFromURL = parts[0];
    
            PageName = parts[1];
        }
    
    
        try
        {
            // ensure that language is two letters
            if (languageFromCulture.Length == 2 && languageFromURL.Length == 2)
            {
                if (languageFromURL != languageFromCulture)
                {
                    //-- LANGUAGE IN THE URL DIFFERS FROM THE CURRENTLY SELECTED LANGUAGE
    
                    var isPastedRouteFound = false;
                    var newLanguage = string.Empty;
                    var newRoute = string.Empty;
    
                    using (Microsoft.Data.SqlClient.SqlConnection connection = DatabaseHelpers.NewConnection())
                    {
                        connection.Open();
                        using (Microsoft.Data.SqlClient.SqlCommand command = connection.CreateCommand())
                        {
                            command.CommandType = System.Data.CommandType.StoredProcedure;
                            command.CommandText = "blazor_CheckRoute";
                            command.Parameters.AddWithValue("@LanguageFromCulture", languageFromCulture); // language from the culture info
                            command.Parameters.AddWithValue("@LanguageFromURL", languageFromURL); // language from the route/URL
                            command.Parameters.AddWithValue("@PageName", PageName);
                            command.Parameters.Add("@IsRouteFound", System.Data.SqlDbType.Int, 4).Direction = System.Data.ParameterDirection.Output;
                            command.ExecuteNonQuery();
                            if (command.Parameters["@IsRouteFound"].Value != null)
                            {
                                isPastedRouteFound = Convert.ToBoolean(command.Parameters["@IsRouteFound"].Value);
                            }
                        }
                    }
    
                    if (isPastedRouteFound == true)
                    {
                        var culture = string.Empty;
                        switch (languageFromURL)
                        {
                            case "en":
                                culture = Uri.EscapeDataString("en-US");
                                break;
                            case "de":
                                culture = Uri.EscapeDataString("de-DE");
                                break;
                            case "es":
                                culture = Uri.EscapeDataString("es-ES");
                                break;
                        }
    
    
                        _httpContextAccessor.HttpContext.Response.Cookies.Append(
                            CookieRequestCultureProvider.DefaultCookieName,
                            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture, culture)));
    
                        //-- EXCEPTION IS THROWN WHEN THE LINE BELOW GETS EXECUTED
                        //_navigationManager.NavigateTo(_navigationManager.Uri, true);
    
                    }
    
                }
            }
    
        }
        catch (Exception ex)
        {
            Logging.LogError(ex, remark: "");
        }
    
        await Task.CompletedTask;
    }
    
    

    Database Table (Pages)

    Language Route

    en contact

    de kontakt

    es contacto

    etc. etc.

    Possible scenario: let's say you are currently visiting website.com/es/contacto. Then you paste the following URL to the address bar and hit enter: website.com/en/contact. It redirects you to the new route but the page remains in Spanish. Then if you navigate to another page the language gets changed to EN.

    I am certain that I miss something obvious though I am not quite sure what. Thank you!

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.