dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.38k stars 10k forks source link

Can not reference razor components of another Blazor-WASM project #26228

Closed CuteLeon closed 4 years ago

CuteLeon commented 4 years ago

Describe the bug

Hi Guys: I created two Blazor-WASM projects: BlazorWASM_A and BlazorWASM_B, and I am going to run A project and display B project's Razor component in A.

To Reproduce

Here is my code:

BlazorWASM_A.csproj

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0-rc.1.20451.17" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0-rc.1.20451.17" PrivateAssets="all" />
    <PackageReference Include="System.Net.Http.Json" Version="5.0.0-rc.1.20451.14" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\BlazorWASM_B\BlazorWASM_B.csproj" />
  </ItemGroup>

</Project>

PageA.razor of BlazorWASM_A

@page "/"

<h1>Hello, world!</h1>

This is Page From App_A

<PageB></PageB>

BlazorWASM_B.csproj

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0-rc.1.20451.17" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0-rc.1.20451.17" PrivateAssets="all" />
    <PackageReference Include="System.Net.Http.Json" Version="5.0.0-rc.1.20451.14" />
  </ItemGroup>

</Project>

PageB.razor of BlazorWASM_B

@page "/"

<h1>Hello, world!</h1>

This is Page From App_B

Issue

Everytime I try to run Project A, an exception will be thrown:

Duplicate base paths '/' for content root paths 'C:\*\BlazorWASMDemo\BlazorWASM_B\wwwroot\' and 'C:\*\BlazorWASMDemo\BlazorWASM_A\bin\Debug\net5.0\wwwroot\'. ('C:\*\BlazorWASMDemo\BlazorWASM_B\wwwroot\css\app.css', 'obj\Debug\net5.0\blazor.boot.json') BlazorWASM_A   C:\PROGRAM FILES\DOTNET\sdk\5.0.100-rc.1.20452.10\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.StaticWebAssets.targets  195 

Exceptions

I readed code of Microsoft.AspNetCore.Components project, and I found that the Components project is using the Microsoft.NET.Sdk SDK while not Microsoft.NET.Sdk.BlazorWebAssembly, and it worked, but what I dont like is that *.razor file will not be complied when working on the Microsoft.NET.Sdk SDK, so that I have to design component via BuildRenderTree(RenderTreeBuilder builder) in project B. Is there a way to design a component in *.razor file and use this component in other projects? Waitting for your reply, thanks!

Further technical details

dotnetspark commented 4 years ago

Your component PageB.razor is routable and responds to the base address "/". PageA.razor is also routable and responds to base address as well. It is reasonable you'll have a conflict. Either PageB.razor is not routable or change the route so there is no conflict.

CuteLeon commented 4 years ago

Hi @ylr-research : Thanks for reply. I tried your solution but it doesn't work... I removed the **@page** of Page B, and make sure that there are no pages using the same route address in both project A and project B, but I got the same Exception when I compile. It seemed that the conflict is about 'wwwroot' folder?

CuteLeon commented 4 years ago

Hi @ylr-research : I found a new solution as below:

  1. Create a .Net Core Class Library project

    1. Edit project file to Microsoft.NET.Sdk.Razor SDK
    2. Add Microsoft.AspNetCore.Components.WebAssembly Nuget package
    <Project Sdk="Microsoft.NET.Sdk.Razor">
    <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0-rc.1.20451.17" />
    </ItemGroup>
    </Project>
    
  2. Create Razor components in Class Library project

    1. You will find Razor Component when you right click on the project and click Add

    2. Design your component as whatever you like

    @inject IServiceProvider provider
    @inject ILogger<MyComponent> logger
    
    <h3>My Component in Class Library project !</h3>
    <h3>@this.Now.ToString("yyyy-MM-dd")</h3>
    
    @code {
       DateTime Now = DateTime.Now;
    
       protected override Task OnInitializedAsync()
       {
           this.logger.LogInformation("Initialize my component ...");
           return base.OnInitializedAsync();
       }
    }
  3. Render components in the Class Library project

    1. Reference the Class Library project into the Main Blazor WASM project
    2. Render components in the Class Library project
    @page "/"
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    <ClassLibrary_C.MyComponent></ClassLibrary_C.MyComponent>

But I still want to know what you recommend. Thanks!

mkArtakMSFT commented 4 years ago

Thanks for contacting us. We recommend using Razor Class Library for sharing components between projects.

CuteLeon commented 4 years ago

Thanks for your reply. Hope this will help others.