{"record":{"id":"b67395552f2f293b","repo":"dotnet/aspnetcore","slug":"the-value-must-implement-nameof-icomponent","errorCode":null,"errorMessage":"The value must implement {nameof(IComponent)}.","messagePattern":"The value must implement (.+?)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/Routing/RouteData.cs","lineNumber":26,"sourceCode":"\n/// <summary>\n/// Describes information determined during routing that specifies\n/// the page to be displayed.\n/// </summary>\npublic sealed class RouteData\n{\n    /// <summary>\n    /// Constructs an instance of <see cref=\"RouteData\"/>.\n    /// </summary>\n    /// <param name=\"pageType\">The type of the page matching the route, which must implement <see cref=\"IComponent\"/>.</param>\n    /// <param name=\"routeValues\">The route parameter values extracted from the matched route.</param>\n    public RouteData([DynamicallyAccessedMembers(Component)] Type pageType, IReadOnlyDictionary<string, object?> routeValues)\n    {\n        ArgumentNullException.ThrowIfNull(pageType);\n\n        if (!typeof(IComponent).IsAssignableFrom(pageType))\n        {\n            throw new ArgumentException($\"The value must implement {nameof(IComponent)}.\", nameof(pageType));\n        }\n\n        PageType = pageType;\n        RouteValues = routeValues ?? throw new ArgumentNullException(nameof(routeValues));\n    }\n\n    /// <summary>\n    /// Gets the type of the page matching the route.\n    /// </summary>\n    [DynamicallyAccessedMembers(Component)]\n    public Type PageType { get; }\n\n    /// <summary>\n    /// Gets route parameter values extracted from the matched route.\n    /// </summary>\n    public IReadOnlyDictionary<string, object?> RouteValues { get; }\n\n    /// <summary>","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Routing/RouteData.cs#L8-L44","documentation":"RouteData's constructor enforces that the page type it carries is a Blazor component (implements IComponent), because RouteView will later instantiate and render it through the component pipeline. Passing a non-component type (a plain class, a model, a controller) would fail later with a less clear cast, so the constructor throws ArgumentException at the boundary. The parameter is annotated with [DynamicallyAccessedMembers(Component)] for trim safety.","triggerScenarios":"Constructing new RouteData(typeof(SomeNonComponentType), routeValues) where the type does not implement IComponent. Common when route data is built from reflection over arbitrary types or when a page type is mistakenly replaced with a view-model.","commonSituations":"Custom routing code that maps URL patterns to handler types without filtering by IComponent; refactoring a page class into a non-component base type; passing a model type instead of its bound component; testing RouteData with stub types.","solutions":["Verify the type passed as pageType implements IComponent (typical pages are Razor components with @page or a [Route] attribute).","Filter candidate types with typeof(IComponent).IsAssignableFrom(t) before constructing RouteData.","If you have a non-component handler, wrap it in a Razor component instead.","Check that DI and assembly scanning did not pick up a model or interface type as a route handler."],"exampleFix":"// before\nvar routeData = new RouteData(typeof(UserProfileViewModel), values); // ViewModel is not a component\n// after\nvar routeData = new RouteData(typeof(UserProfile), values); // UserProfile.razor implements IComponent","handlingStrategy":"type-guard","validationCode":"// Filter candidate page types before constructing RouteData.\nif (!typeof(IComponent).IsAssignableFrom(pageType))\n    throw new ArgumentException($\"{pageType} is not a Blazor component.\", nameof(pageType));\nvar data = new RouteData(pageType, routeValues);","typeGuard":"static bool IsComponentType(Type? t) => t is not null && typeof(IComponent).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Restrict route-discovery assembly scanning to types implementing IComponent.","Use [DynamicallyAccessedMembers(Component)] annotations consistently so the trimmer keeps page types.","Add a unit test that asserts every route handler type implements IComponent.","Avoid pointing RouteData at view-models or MVC controllers."],"tags":["blazor","routing","routedata","icomponent","argumentexception"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}