question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

API Proposal RoutingStateProvider; RouteData breaking change

See original GitHub issue

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

Issue Analytics

  • State:closed
  • Created 5 months ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
halter73commented, May 15, 2023

API Review Notes for RootComponentMetadata (we already approved the rest of the proposal):

  • This helps distinguish between multiple invocations of MapRazorComponents<TRootComponent>() where RootComponentMetata.Type is typeof(TRootComponent).
  • Typical users would read it via httpContext.GetEndpoint().Metadata.GetMetadata<RootComponentMetata>().
  • What do we think about the Microsoft.AspNetCore.Builder namespace?

API Approved! Make sure we update the namespace for both RootComponentMetadata and RootComponentMetadata.

- namespace Microsoft.AspNetCore.Builder;
+ namespace Microsoft.AspNetCore.Components.Endpoints;

public class ComponentTypeMetadata
{
    public ComponentTypeMetadata(Type componentType);
    public Type Type { get; }
}

+  public class RootComponentMetadata
+  {
+      public RootComponentMetadata(Type rootComponentType);
+      public Type Type { get; }
+  }
1reaction
halter73commented, May 12, 2023

Reopening for API review.

Thanks for the updated proposal. Can you update the latest comment to show interface IRoutingStateProvider instead of class RoutingStateProvider? It looks like there was a copy-paste issue.

Can you also provide usage examples for RootComponentMetadata since that’s new?

I also wonder if we should put RootComponentMetadata in the Microsoft.AspNetCore.Components.Endpoints rather than the Microsoft.AspNetCore.Builder namespace. Microsoft.AspNetCore.Builder is consistent with ComponentTypeMetadata, but I’m not sure this type will be commonly used enough to warrant including in a namespace that’s a default global using.

Read more comments on GitHub >

github_iconTop Results From Across the Web

8.0-preview5 Milestone
[Blazor] Update discovery APIs and automatically configure the endpoints ... API Proposal RoutingStateProvider; RouteData breaking change ...
Read more >
Web Api Routing Handler Change Route Data
Im trying to intercept the request and change some of the route data before it hits the actual method. However the below doesnt...
Read more >
Authorization: Resource in endpoint routing is HttpContext ...
Learn about the breaking change in ASP.NET Core 5.0 titled Authorization: Resource in endpoint routing is HttpContext.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found