Skip to content

[Pre7] NotFound support updates #35861

@ilonatommy

Description

@ilonatommy

[EDIT by guardrex to add the metadata]

Added support for NotFound in applications without Blazor's Router.

Applications that implement their custom router can now use NavigationManager.NotFound().

The custom router can render not found content from two sources, depending on the state of response:

  • Regardless of the response state, re-execution path to page can used. It can be passed to UseStatusCodePagesWithReExecute like that:
    app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);.
  • Adittionally, when the response has started, Path of NotFoundEventArgs can be used. It can be populated by subscribing to OnNotFoundEvent in the router:
    private void OnNotFoundEvent(object sender, NotFoundEventArgs e)
    {
        // Only execute the logic if HTTP response has started,
        // because setting args' Path blocks re-execution
        if (_httpContext?.Response.HasStarted == false)
        {
            return;
        }

        var type = typeof(CustomNotFoundPage);
        var routeAttributes = type.GetCustomAttributes(typeof(RouteAttribute), inherit: true);
        if (routeAttributes.Length == 0)
        {
            throw new InvalidOperationException($"The type {type.FullName} " +
                $"does not have a {typeof(RouteAttribute).FullName} applied to it.");
        }

        var routeAttribute = (RouteAttribute)routeAttributes[0];
        if (routeAttribute.Template != null)
        {
            e.Path = routeAttribute.Template;
        }
    }

Implementation of this feature required changes to the existing process. From this reason, NotFound in applications that have Blazor's default Router also has changed.

Simplified the 404 handling with default Router

  • NotFound fragment is getting obsolete.
  • NavigationManager.NotFound() removes the support for NotFound fragment. Fragment cannot be rendered using NavigationManager.NotFound().

Summary of how apps with Blazor Router should expect not found to work, regardless if the response started or not:

  • If Path of NotFoundEventArgs set, render contents of page it is pointing to (this is a new thing).
  • If Router.NotFoundPage set, render it. (It was already there in the previous previews). Otherwise check:
  • If re-execution middleware set up, render contents of page it is pointing to. (Also not new). Otherwise, nothing happens.

@guardrex, sorry for the constant changes, we did not expect the new feature will force behavioral changes to default Router case. However, from good things, this update unifies the behavior and thus, simplifies the docs.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions