Aspnetcore: Error when shipping blazor 0.8 razor component project to .NET Core 3.0 Preview 3. Detail: 'IServiceCollectoin' does not contain a definition for 'AddRazorComponents'. 'IApplicationBuilder' does not contain a definition for 'UseRazorComponents'

Created on 8 Mar 2019  路  18Comments  路  Source: dotnet/aspnetcore

My server-side blazor app was working in blazor 0.8.
But after I upgraded it to blazor 0.9, i got a few errors

'IServiceCollection' does not contain a definition for and no accessible extension method accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?
'IApplicationBuilder' does not contain a definition for and no accessible extension method accepting a first argument of type 'IApplicationBuilder' could be found (are you missing a using directive or an assembly reference?)

What i did:

  1. Upgraded SDK to 3.0.100-preview3-010431
  2. Updated the Blazor packages and .NET CLI tool references to 0.9.0-preview3-19154-02.
  3. Updated the remaining Microsoft.AspNetCore.* packages to 3.0.0-preview3-19153-02.
  4. Fixed the JSRuntime.

server.csproj

<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor.Server" Version="0.9.0-preview3-19154-02" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>

App.csproj

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor" Version="0.9.0-preview3-19154-02" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Build" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>
area-blazor

Most helpful comment

This is my scenario:

After follow all instructions, I get the error of this issue when I try to run app as server-side (razor components).

I dig into new generated app from template 0.9.0 code and I see index is now on /Pages folder and other significant changes.

Please, someone can post real instructions to switch between client side and razor components on 0.9.0?

All 18 comments

I'm getting the same issue, even with a brand new project that I upgrade to 0.9.0

They kind of forgot to mention all the other things you have to do to upgrade the projects.
```C#
AddRazorComponents();

 now only exists for IServiceCollection. 

For the IApplicationBuilder you want to use 
```C#
            app.UseRouting(routes =>
            {
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

in lieu of AddRazorComponents.

@darren-zdc

  • server-side Blazor is called Razor Components now. You mustn't use any template or package reference with "Blazor" in its name; those are _only_ for WebAssembly-based, client-side Blazor

  • in particular, there is no two-project Razor Components template. There's only one that contains a single project.

  • the only package reference you should need are:

    <PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />

@chucker
Back to the Blazor 0.5, they were using WepApp.App and WepApp.Server to setup the Server-side blazor project, I didn't realize that they merged these two projects together to be a Razor Component.

Do I have to merge those two projects to be one or there is a way to separate it? I actually like the way they did before (Separated, nice and clean),

If I separate it, what kinds package should be included inside the app project? There are some updates in blazor 0.8

Upgrade a server-side Blazor project to ASP.NET Core Razor Components in .NET Core 3.0
If you've been working with server-side Blazor, we recommend upgrading to use ASP.NET Core Razor Components in .NET Core 3.0.
To upgrade a server-side Blazor app to ASP.NET Core Razor Components:

Update the client-side Blazor project as described previously, except replace the script reference to blazor.server.js with components.server.js
Update the ASP.NET Core app hosting the Razor Components to .NET Core 3.0 as described previously.

From https://devblogs.microsoft.com/aspnet/blazor-0-8-0-experimental-release-now-available/

Right now I have, inside the app project,

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor" Version="0.9.0-preview3-19154-02" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Build" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>

It might be sufficient to remove the Blazor packages, like so:

server.csproj

<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>

App.csproj

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor" Version="0.9.0-preview3-19154-02" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Build" Version="3.0.0-preview3-19153-02" />
  </ItemGroup>

You can also try creating a component library.

@honkmother

They kind of forgot to mention all the other things you have to do to upgrade the projects.

AddRazorComponents();

now only exists for IServiceCollection.

For the IApplicationBuilder you want to use

            app.UseRouting(routes =>
            {
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

in lieu of AddRazorComponents.

With the line you giving to me, that is still not enough to make it working,,,
Getting an error,,,

Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[8]
      Failed to invoke hub method 'StartCircuit'.
System.ArgumentException: The type WebAppBootStrap.App.Startup does not implement IComponent.
Parameter name: componentType
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(Type componentType)
   at Microsoft.AspNetCore.Components.Rendering.Renderer.InstantiateComponent(Type componentType)
   at Microsoft.AspNetCore.Components.Browser.Rendering.RemoteRenderer.AddComponentAsync(Type componentType, String domElementSelector)
   at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.<>c__DisplayClass38_0.<<InitializeAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c__DisplayClass9_0.<<InvokeAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.InitializeAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Components.Server.ComponentHub.StartCircuit(String uriAbsolute, String baseUriAbsolute)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.ExecuteHubMethod(ObjectMethodExecutor methodExecutor, THub hub, Object[] arguments)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.Invoke(HubMethodDescriptor descriptor, HubConnectionContext connection, HubMethodInvocationMessage hubMethodInvocationMessage, Boolean isStreamResponse, Boolean isStreamCall)
fail: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[8]
      Failed to invoke hub method 'BeginInvokeDotNetFromJS'.
System.InvalidOperationException: The CircuitHost is null. This is due to an exception thrown during initialization.
   at Microsoft.AspNetCore.Components.Server.ComponentHub.EnsureCircuitHost()
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.<>c__DisplayClass33_0.<WrapVoidMethod>b__0(Object target, Object[] parameters)
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.ExecuteHubMethod(ObjectMethodExecutor methodExecutor, THub hub, Object[] arguments)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.Invoke(HubMethodDescriptor descriptor, HubConnectionContext connection, HubMethodInvocationMessage hubMethodInvocationMessage, Boolean isStreamResponse, Boolean isStreamCall)

App project:
Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<AppState>();
        }

        public void Configure(IComponentsApplicationBuilder app)
        {
            app.AddComponent<App>("app");
        }

Server project:
Startup.cs
```
public void ConfigureServices(IServiceCollection services)
{
// Adds the Server-Side Blazor services, and those registered by the app project's startup.
services.AddMvc().AddNewtonsoftJson();
services.AddRazorComponents();
services.AddMvc().AddRazorOptions(options =>
{
options.ViewLocationExpanders.Add(new ViewLocationExpander());
});
services.AddMvc();
services.AddRouting();
services.AddResponseCompression();
}

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

        app.UseRouting(routes =>
        {
            routes.MapRazorPages();
            routes.MapComponentHub<App.Startup>("app");
        });
    }

This is my scenario:

After follow all instructions, I get the error of this issue when I try to run app as server-side (razor components).

I dig into new generated app from template 0.9.0 code and I see index is now on /Pages folder and other significant changes.

Please, someone can post real instructions to switch between client side and razor components on 0.9.0?

OK, so I got my solution converted from 0.8.0 using Blazer (WebAssembly) to 0.9.0 using Razor Components (Serverside Blazor).

First, I had to move all my code from my Server project (where the controllers were and some other helper classes) and move it to the Client project.

Then I needed to take what I had for my Server Startup.cs and Program.cs and use that instead of the one that was in Client.

Any services that you had defined in your Client Startup.cs file will need to be moved to the Server Startup.cs file.

I tried following all the steps here as best as I could: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-3/

Then, when that didn't work as expected, I saw this post.

I added the following to ConfigureServices in Startup.cs

services.AddRazorComponents();

I then added the following to Configure in Startup.cs

app.UseRouting(routes =>
            {
                routes.MapDefaultControllerRoute();
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

I had an issue modifying the Nuget Packages, so I opened up the .csproj file and added what I needed manually.

<PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0-preview3-19153-02" />

Also, make sure that your TagetFramework is:
<TargetFramework>netcoreapp3.0</TargetFramework>

I have a folder structure as follows (which seems to be important):

/Components - this folder houses all the razor components and everyting has been renamed to have the .razor file extension
Components/Pages
Components/Shared
/Controllers
/Pages

I had also run into an issue when calling StateHasChanged where it said something about not being on the UI thread or something like that (sorry can't remember exactly what the wording was), I had to call it like this instead: base.Invoke(StateHasChanged);

There were a bunch of other issues I ran into, but these were the ones that were the hardest for me to fix. Also, a lot of the other issues were really just organization and renaming of namespaces and that.

I hope this helps someone else. Took me three days to figure these out and I think I've got some grey hair now.

@sbuchok
I think what we need to do in the end is merging those two (app and server) projects to be one Razor Component project and use Razor Library Class to store the components. That is what I am going to do next,,,

But I am very surprised that you really "upgrade" it to preview 3,,,

Let me know what other issues you run into and I might be able to help.

JSRuntime.Current is not more available, see release notes. Now you can access JSRuntime via DI.

Does not realize the warning The JavaScript runtime is not available during prerendering. will happen every time we run the app. #8327

So now we can't use .Client project as blazor app and easy switch to server-side due developing?
@danroth27

@vchirikov :

[Blazor 0.9.0] How to switch between ASP.NET Core Razor Components and client-side Blazor on 0.9.0? (https://github.com/aspnet/AspNetCore/issues/8523) is already assigned to @danroth27 :)

So now we can't use .Client project as blazor app and easy switch to server-side due developing?

Sadly it looks like we broke this scenario with Blazor 0.9.0 and Razor Components in .NET Core 3.0 Preview 3. We will get this fixed for Preview 4 and the next Blazor update.

@darren-zdc Are you still blocked on migrating? It looks like @sbuchok covered the main migration steps in his comment above.

One clarification: You can still setup an app so that it can be switched between the client and server hosting models, but it requires a bit of code. For details, see Steve's comment here: https://github.com/aspnet/AspNetCore/issues/8523#issuecomment-477563907.

yea, I migrated my app to only one RC project.
One particular thing need to be mentioned,
If you have controllers in the project, you need to add the route inside the app.UseRoute, like the code inside @sbuchok comment

app.UseRouting(routes =>
            {
                routes.MapDefaultControllerRoute();
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

or

app.UseRouting(routes =>
            {
                routes.MapRazorPages();
                routes.MapComponentHub<Components.App>("app");
                routes.MapControllerRoute(name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

app.UseMvcWithDefaultRoute(); will not work anymore

OK, so I got my solution converted from 0.8.0 using Blazer (WebAssembly) to 0.9.0 using Razor Components (Serverside Blazor).

First, I had to move all my code from my Server project (where the controllers were and some other helper classes) and move it to the Client project.

Then I needed to take what I had for my Server Startup.cs and Program.cs and use that instead of the one that was in Client.

Any services that you had defined in your Client Startup.cs file will need to be moved to the Server Startup.cs file.

I tried following all the steps here as best as I could: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-3/

Then, when that didn't work as expected, I saw this post.

I added the following to ConfigureServices in Startup.cs

services.AddRazorComponents();

I then added the following to Configure in Startup.cs

app.UseRouting(routes =>
            {
                routes.MapDefaultControllerRoute();
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

I had an issue modifying the Nuget Packages, so I opened up the .csproj file and added what I needed manually.

<PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.0.0-preview3-19153-02" />

Also, make sure that your TagetFramework is:
<TargetFramework>netcoreapp3.0</TargetFramework>

I have a folder structure as follows (which seems to be important):

/Components - this folder houses all the razor components and everyting has been renamed to have the .razor file extension
Components/Pages
Components/Shared
/Controllers
/Pages

I had also run into an issue when calling StateHasChanged where it said something about not being on the UI thread or something like that (sorry can't remember exactly what the wording was), I had to call it like this instead: base.Invoke(StateHasChanged);

There were a bunch of other issues I ran into, but these were the ones that were the hardest for me to fix. Also, a lot of the other issues were really just organization and renaming of namespaces and that.

I hope this helps someone else. Took me three days to figure these out and I think I've got some grey hair now.

Hi,
I was playing with quick conversion options from client to server side. This is quickes one that i managed to make work:

CLIENT APP

  • Index.html change:
    change