Blazor Issue with reading a URL as a string parameter in Production

Andrew Sabin 60 Reputation points
2026-08-04T03:08:25.2066667+00:00

Hello Microsoft Support Team,

With my Blazor application I am trying to create a redirect page where the URL would be:
"https://www.mywebsite.com/redirect/{*redirectedToURL}"

Where after users go to that URL they will be given a warning to let them know what the redirectedToURL URL is. I'm implementing this because my website allows for user input and people can potentially hide URLs to malicious websites within them.

When I test the implementation when the site is in Development everything works correctly (as an example the redirectedToURL is set to "https://dmc3crimson.github.io/". When the link is clicked it redirects to "https://www.mywebsite.com/redirected/https%3a%2f%2fdmc3crimson.github.io%2f):
Screenshot 2026-08-03 at 19-51-55 You Are Leaving GoMontag

However, when the site is in production it gives me this when trying to send a redirect URL (redirectedToURL is still set to "https://dmc3crimson.github.io/". When the link is clicked it redirects to "https://www.mywebsite.com/redirected/https%3a%2f%2fdmc3crimson.github.io%2f):
Missing Slash Where it takes a way one of the slashes in an "https://" part of the url.

The code for the page is as follows:

@page "/redirect/{*redirectToURL}"
@using Microsoft.Extensions.Options
@using System.Web
@inject NavigationManager navigationManager
@rendermode InteractiveServer

<PageTitle>You Are Leaving The Website</PageTitle>
@if (!isLoading)
{
    <div class="redirect-grid">
        <div class="left-column"></div>
        <div class="main-content-column">
            <div class="site-warning">
                <h3><i class="bi bi-exclamation-octagon-fill"></i> Warning! <i class="bi bi-exclamation-octagon-fill"></i></h3>
                <hr />
                <p>You are attempting to leave the site to go to:</p>
                <h4>@decodedUrl</h4>
                <p>Please take a look at your destination before clicking continue.</p>
                <p>
                    <strong>
                        If you believe that this is a suspecious link, or you know someone who is a victim of this link,
                        <a href="/contact">Contact Me</a> and I'll get back to you as soon as possible!
                    </strong>
                </p>
                <p>By clicking the button below, you agree that you trust this site shown above.</p>
                <div class="site-continue-btn">
                    <a class="btn btn-primary" target="_blank" href="@decodedUrl">Click To Continue</a>
                </div>
                
            </div>
        </div>
        <div class="right-column"></div>
    </div>
}

@code {
    [Parameter]
    public string? redirectToURL { get; set; }
    private string decodedUrl = string.Empty;
    private bool isValid;
    private bool isLoading = true;

    protected override async Task OnParametersSetAsync()
    {
        if (string.IsNullOrEmpty(redirectToURL))
        {
            navigationManager.NavigateTo("not found");
            return;
        }
        Console.WriteLine(redirectToURL);
        decodedUrl = HttpUtility.UrlDecode(redirectToURL);
        Console.WriteLine(decodedUrl);

        isLoading = false;
    }

}


I try to decode the redirectToURL URL but it gives me back the same issue. This is the first time I've come across an issue with a page working in development but not working in Production. Would you have any idea about what might be going wrong?

Thank you for your help and time,
-Andy

Azure Static Web Apps
Azure Static Web Apps

An Azure service that provides streamlined full-stack web app development.


Answer accepted by question author
Saritha Bandaru 655 Reputation points Microsoft External Staff Moderator
2026-08-06T05:43:57.1233333+00:00

Hello @Andrew Sabin

Thank you for the additional details.

On Azure App Service the request path is normalized, and Blazor’s catch-all route parameter decodes the captured segments.

“Slashes and segments of the captured path are decoded. For a route template of /catch-all/{pageRoute}, the URL /catch-all/this/is/a%2Ftest%2A yields this/is/a/test.”

https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-10.0#catch-all-route-parameters

That’s why both redirectToURL and your HttpUtility.UrlDecode call end up with https:/… in production (while it works under the local Kestrel server).

Recommended fix – use a query string

Move the destination URL out of the path and into a query string. Query-string values are not subjected to the same path decoding/normalization.

  1. Update the Blazor Page
       @page "/redirect"
       @inject NavigationManager Navigation
       @if (safeUrl is not null)
       {
           <div class="redirect-grid">
               <!-- keep your existing warning markup here -->
               <h4>@safeUrl</h4>
               <a class="btn btn-primary" target="_blank" rel="noopener noreferrer" href="@safeUrl">
                   Click To Continue
               </a>
           </div>
       }
       @code {
           [SupplyParameterFromQuery(Name = "url")]
           private string? RedirectToUrl { get; set; }
           private string? safeUrl;
           protected override void OnParametersSet()
           {
               safeUrl = null;
               // [SupplyParameterFromQuery] already URL-decodes the value — do NOT decode again
               if (Uri.TryCreate(RedirectToUrl, UriKind.Absolute, out var uri)
                   && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
               {
                   safeUrl = uri.AbsoluteUri;
               }
               else
               {
                   Navigation.NotFound();   // .NET 10 helper
               }
           }
       }
    
    1. Do not call Uri.UnescapeDataString or HttpUtility.UrlDecode again. The attribute already gives you the decoded value. A second decode will break any legitimate % sequences in the target URL.
    2. The scheme check (http / https only) is required. Without it, a javascript: or data: payload could be bound into the href.
  2. Change the place where you currently build the redirect link to:
       $"/redirect?url={Uri.EscapeDataString(originalHref)}"
    
    Do not pre-encode the value before calling EscapeDataString — that creates double-encoding and is a common follow-up problem.

https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-10.0#catch-all-route-parameters

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.supplyparameterfromqueryattribute?view=aspnetcore-10.0

This approach works consistently on Azure App Service (Linux and Windows) and locally.

Please let us know if this helps or need more assistance on this issue.

Thanks

Was this answer helpful?

1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

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