Skip to content

API Proposal RoutingStateProvider; RouteData breaking change #47854

@surayya-MS

Description

@surayya-MS

Background and Motivation

As part of Blazor United we want to make Static, Server, and Webassembly app models similar to each other. As part of that, Blazor United will always render the root component you specify in MapRazorComponents<App>(). Your App component needs to have a Router component to ensure the appropriate page is rendered.

For static rendering we want to add a scoped service RoutingStateProvider that holds RouteData from httpContext. With this RouteData we already know what page to render. This way we will avoid routing twice in Router component. The Router component will check RouteData to render the appropriate page.

namespace Microsoft.AspNetCore.Components.Routing;

public class RoutingStateProvider
{
    public virtual RouteData? RouteData { get; }
}

We also want to change RouteData.

public sealed class RouteData
{
-   public RouteData([DynamicallyAccessedMembers(Component)] Type pageType, IReadOnlyDictionary<string, object> routeValues) {}
+   public RouteData([DynamicallyAccessedMembers(Component)] Type pageType, IReadOnlyDictionary<string, object?> routeValues) {}

    [DynamicallyAccessedMembers(Component)]
    public Type PageType { get; }

-    public IReadOnlyDictionary<string, object> RouteValues { get; }
+   public IReadOnlyDictionary<string, object?> RouteValues { get; }
}

The reason for this is when creating RouteData for routeValues parameter we provide httpContext.GetRouteData().Values of type RouteValueDictionary : IReadOnlyDictionary<string, object?>. There is CS8620.

Proposed API

namespace Microsoft.AspNetCore.Components.Routing;

public class RoutingStateProvider
{
    public virtual RouteData? RouteData { get; }
}
public sealed class RouteData
{
-   public RouteData([DynamicallyAccessedMembers(Component)] Type pageType, IReadOnlyDictionary<string, object> routeValues) {}
+   public RouteData([DynamicallyAccessedMembers(Component)] Type pageType, IReadOnlyDictionary<string, object?> routeValues) {}

    [DynamicallyAccessedMembers(Component)]
    public Type PageType { get; }

-    public IReadOnlyDictionary<string, object> RouteValues { get; }
+   public IReadOnlyDictionary<string, object?> RouteValues { get; }
}

Usage Examples

Router component will check if RoutingStateProvider RouteData is not null and render the page. If it is null then it will work as usual (try to match current url to a page and then render that page).

if (RoutingStateProvider.RouteData != null)
{
     _renderHandle.Render(Found(RoutingStateProvider.RouteData));
     return;
}

RouteData

new RouteData(componentType, httpContext.GetRouteData().Values)

Alternative Designs

Suppress CS8620.

Risks

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-blazorIncludes: Blazor, Razor Componentsfeature-full-stack-web-uiFull stack web UI with Blazor

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions