Blazor server page with parameters throwing "404 not found " on manual refreshes
Asked Answered
A

1

8

I have a Blazor Server app with a page that takes in parameters in the uri. When I click on an anchor tag that has the route setup to hit that page with params (like below) the link works fine, and the page loads.

<a href="/MyPage/{@Param1}/{@Param2}"> <!--link content in here--> </a>

However, if one tries to access the page from that url directly, or manually refreshes in the browser, then the page doesn't reinitialize or hit any breakpoints on the parameters. Instead, it throws a 404 not found.

So two things here:

  • Firstly, I'm confused about why it works fine from within the anchor tag, but dies any other way. Especially when pages without params in the @page directive work fine with refreshes/direct-urls.
  • Second, is this an intended behavior for Blazor Server or am I missing something here that's breaking the page refreshes/hitting-url-directly? Doesn't seem like a feature, but maybe I'm misunderstanding Blazor's routing.

Razor and Razor.cs for page in question:

@page "/MyPage/{Param1}/{Param2}"

<h1>MyPage</h1>

<Metrics Param1="@Param1" />

<Details Param1="@Param1" Param2="@Param2" />

<InProgress Param1="@Param1" Param2="@Param2" />

<InQueue Param1="@Param1" />

<br />
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using MyApp.Data.Models.ApiResponse;

namespace MyApp.Pages
{
    public partial class MyPage
    {
        [Parameter]
        public string Param1 { get; set; }

        [Parameter]
        public string Param2{ get; set; }

        public TaskList Tasks { get; set; }

        protected override Task OnInitializedAsync()
        {
            // work in progress, intend to do more here later on
            var test = "";
            return base.OnInitializedAsync();
        }
    }
}

Edit(s) -- per comment suggestions

UseEndpoints section of Configure method in Startup.cs:

 app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });

After further digging I noticed that the @param2 will occaionally have a . char in it. Blazor does have a need for configuring routes that have params with dots in them. The below fall back doesn't work:

endpoints.MapFallbackToPage("/MyPage/{Param1}/{Param2}", "/MyPage");

It throws an: InvalidOperationException: Cannot find the fallback endpoint specified by route values: { page: /MyPage, area: }.

I'm guessing that the area: being empty is a problem but I'm not finding how or where to properly set that. The example from the link shows just the Page's name in the fallback. Could someone please point out what's wrong with this fall back and how one can properly correct it?

Aholah answered 22/2, 2021 at 20:57 Comment(9)
Following the links doesn't refresh the page. Refreshing the page explicitly means that it's loading everything from the new URI. This is usually accomplished with the default template with the following line in your Startup.cs: endpoints.MapFallbackToFile("index.html"); Start by checking for that.Selfaggrandizement
@KirkWoll that is in the Startup.cs file, do I need to do something else/extra then? Also I'm not saying they are the same thing, just that the behavior is identical between page refreshes and directly hitting the url/uri.Aholah
I just meant make sure that line is there, as it sounds like it's not successfully falling back to index.html. Also, it might be helpful if you include the entire section starting with app.UseEndpoints (where the fallback stuff should be defined)Selfaggrandizement
Also, I was speaking to your comment, "Firstly, I'm confused about why it works fine from within the anchor tag" -- it works fine with the anchor tag because in that scenario the page is not refreshed from the server.Selfaggrandizement
That all looks good to me. Is this a .NET 5 project? Is it using the latest project templates? When you create a brand new server-side project from scratch, does that work when you type in arbitrary URLs? (it should show a blazor page saying "Sorry, there's nothing at this address" -- but not a literal 404)Selfaggrandizement
@KirkWoll It's a Blazor Server .NET 5 project with latest everything (afaik) I think I found the issue though, I noticed that @param2 occasionally has periods in it. However, the fallback doesn't seem to be working -- will update question in a minute to reflect this.Aholah
Ohhh, I think you're on to something. When I add a period in the URL I repro'd your behavior.Selfaggrandizement
Adding a trailing slash also fixes the issue, so maybe that would be a viable approach. Anyway, if you arrive at a solution you're happy with, I encourage you to self-answer with your solution. 👍Selfaggrandizement
@KirkWoll that trailing slash didn't seem to do anything, but specifying the _Host instead of the page did the trick. Thanks for the help!Aholah
A
9

My problem was with a dot character being in the parameter's value. When the routing issue is from a "dot" being in the parameter, then doing exactly what the docs recommends does the trick (go figure). You will want to specify a fall back for that particular route like so:

endpoints.MapFallbackToPage("/MyPage/{Param1}/{Param2}", "/_Host");

For WASM projects: you want to specify the html file vs _Host which should be Blazor Server specific.

endpoints.MapFallbackToFile("/MyPage/{Param1}/{Param2}", "index.html");

After this setup is applied, refreshing a page or reaching the URL directly should result in your application working as intended, no more 404 error different from the standard <NotFound> tag setup in the App.razor.

Key points:

  • Check if your url parameters have any known parsing exceptions like dots (Blazor assumes those are files being requested)
  • Use the default page of your application for the fall back, not the page you want to hit. In a Server app that's _Host for wasm it's index.html
Aholah answered 22/2, 2021 at 22:18 Comment(2)
Adding the "/_Host" didn't solve the issue for me. I was passing string with a few dots (IP address). What I did was replacing the dots with hyphens in the link and then replacing them back on the target page.Ascertain
Thank you very much @CoderLee. The provided link was very helpful and my case was also a dot in parameters. So I ended up with: endpoints.MapFallbackToPage("/{param1?}/{param2?}/{param3?}/{param4?}", "/_Host"); that works like a charm.Alfredoalfresco

© 2022 - 2024 — McMap. All rights reserved.