Adding Server-Side Blazor to an existing MVC Core app

ⅰ亾dé卋堺 提交于 2019-12-05 07:48:20

I've got to the bottom of this now. After all the trial and error described in my question the solution turns out to involve surprisingly little code.

Example With Server-Side Blazor And MVC In The Different Projects In The Same Solution

The answer below assumes you have a working server-side Blazor project in your solution and are trying to use components from that project in a separate MVC project in that same solution. I did this in VS2019, using Core 3 Preview 5.

See the bottom of the page or a link to an example of MVC and Blazor in the same project.

Changes to the MVC project's .csproj file

You just need to add a reference to your blazor project:

    <ProjectReference Include="..\MyClient.Web.Blazor\MyClient.Web.Blazor.csproj" />

Changes to the MVC project's Views\Shared\_Layout.cshtml file

Add a reference to the Blazor JS Script

<script src="_framework/blazor.server.js"></script>

(This doesn't actually exist on your local file system, Blazor automagically sorts it out by the time the app gets to the browser)

Changes to the MVC project's Startup.cs

This is where the real work is done

In the ConfigureServices method add:

services.AddServerSideBlazor();

I then switched my configuration over to the new style Core 3 configuration (so no longer using the AddMvc method):

services.AddControllersWithViews()            
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    });

services.AddRazorPages();

And then the change that finally got it all working for me was to switch to Core 3's endpoint routing in the Configure(IApplicationBuilder app, IWebHostEnvironment env) method:


app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
    endpoints.MapBlazorHub();
});

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

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

The commented out code shows the old style routing I was using. I think it was the absence of endpoints.MapBlazorHub(); that was causing my button click issue

Changes to the Blazor project

No changes were needed to the Blazor project to get this working.

How to then put the Blazor component on an MVC page

Once you've done all of the above, all that's needed to get your component to render on an MVC page is to add

 @(await Html.RenderComponentAsync<YourComponent>())

That should work on both an MVC page and a Razor page.

Known routing issue in Core 3 Preview 5

The above changes were all that I needed to make to get it working. There is a known issue with Core 5 where once you navigate to an MVC or Razor page with a Blazor component on it, the routing will no longer work until the page is refreshed - the URLs will change in the browser's address bar, but no navigation will occur.

I'm now running on Preview 6 and I can confirm the routing issue is now fixed from Preview 6 onward.

Example With Server-Side Blazor And MVC In The Same Project

Chris Sainty has an example of server-side Blazor components added in to an existing MVC project here: Using Blazor Components In An Existing MVC Application (source here)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!