{"record":{"id":"a6ca5d0f0113233f","repo":"dotnet/aspnetcore","slug":"the-value-must-implement-icomponent","errorCode":null,"errorMessage":"The value must implement IComponent.","messagePattern":"The value must implement IComponent\\.","errorType":"validation","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/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/Routing/RouteData.cs#L8-L44","documentation":"Thrown by the RouteData constructor. The first argument (pageType) must be a component — it must implement IComponent because RouteData later instantiates that type as a rendered page. Passing a plain class, model, or non-component type fails this guard.","triggerScenarios":"Calling new RouteData(pageType, routeValues) where pageType is a type that does not implement IComponent (e.g., a ViewModel, a record, or a Razor page handler class). Happens in custom routers or test helpers that build RouteData from reflected [Route] types.","commonSituations":"A custom routing solution scanning assemblies for [Route]-decorated types and feeding them to RouteData without an IComponent check; a test that constructs RouteData with a stub type; a type annotated with [Route] that is not a Blazor component.","solutions":["Filter candidate types with typeof(IComponent).IsAssignableFrom(t) before constructing RouteData.","Ensure the page type is a Blazor component (decorated with @page / [Route] and inherits from ComponentBase or implements IComponent).","If the type genuinely should be a page, make it implement IComponent."],"exampleFix":"// before\nvar rd = new RouteData(typeof(MyViewModel), values); // MyViewModel is not a component\n\n// after\nif (!typeof(IComponent).IsAssignableFrom(typeof(MyPage)))\n    throw new InvalidOperationException(\"page must implement IComponent\");\nvar rd = new RouteData(typeof(MyPage), values);","handlingStrategy":"type-guard","validationCode":"static RouteData? SafeRouteData(Type pageType, IReadOnlyDictionary<string,object?> values)\n    => typeof(IComponent).IsAssignableFrom(pageType) ? new RouteData(pageType, values) : null;","typeGuard":"static bool IsComponentType(Type t) => typeof(IComponent).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Filter scanned [Route] types with typeof(IComponent).IsAssignableFrom(t) before constructing RouteData.","Only Blazor components (deriving from ComponentBase or implementing IComponent) are valid page types.","In custom routers/tests, assert the page type implements IComponent up front."],"tags":["blazor","routing","routedata","icomponent","type-guard"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}