In this post, we will discuss the following
Hosting Models
Enable Authentication and Authorization
Dive deep into Default Blazor pages
Prerequisites
Visual Studio 2019
Install the latest .NET 5 SDK.
Install Blazor Templates
Table of Contents
step 1.Create a Blazor Server App with Visual Studio
step 2.引入几个项目
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Stockso.BlazorServer.Services\Stockso.BlazorServer.Services.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0-rc.1.*" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.0-rc.1.20451.17" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-rc.1.*" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0-rc.1.*" />
</ItemGroup>
</Project>
step 3.Authentication and Authorization
add <CascadingAuthenticationState>
add <CascadingAuthenticationState>
//change from RouteView to AuthorizeRouteView
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
to
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
\src\BlazorServer\Stockso.BlazorServer\App.razor
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
step 4.注入服务
public void ConfigureServices(IServiceCollection services)
{
services.AddDI();
//注册所有服务
services.AddCustomRegistrarServices(Configuration);
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
}
step 5.前台显示页面
List.razor
@page "/Pages/Log/List"
@using Nop.Core;
@using Nop.Core.Domain.Logging;
@using Nop.Services.Logging;
@using Microsoft.AspNetCore.Authorization
@inject Nop.Services.Logging.INopLogger NopLogger
<h2>用户角色</h2>
@if (users == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class='table'>
<thead>
<tr>
@*<th>用户图像</th>
<th>用户昵称</th>*@
<th>ID</th>
<th>Name</th>
<th>IsSystemRole</th>
<th>SystemName</th>
<th>Active</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
@*<td><img src="@user.headimgurl" /></td>
<td>@user.nickname</td>*@
<td>@user.Id</td>
<td>@user.ShortMessage</td>
<td>@user.PageUrl</td>
<td>@user.IpAddress</td>
<td>@user.CreatedOnUtc</td>
<td>
<a href='/editemployee/@user.Id'>Edit</a>
<a href='/deleteemployee/@user.Id'>Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
@code {
IPagedList<Log> users;
protected override async Task OnInitializedAsync()
{
users = NopLogger.GetAllLogs(null, null, "", null, 0, 10);
}
}
新建Nop.Models项目
采用netstandard2.0,安装System.ComponentModel.Annotations,便于winform等多项目引用
Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
</ItemGroup>
</Project>
添加System.ComponentModel.Annotations后,可使用[Display(Name = "Account.Login.Fields.Email")]
using System.ComponentModel.DataAnnotations;
namespace Nop.Models.Messages
{
/// <summary>
/// Represents a queued email model
/// </summary>
public partial class QueuedEmailModel
{
#region Properties
public int Id { get; set; }
[Display(Name = "Account.Login.Fields.Email")]
public string PriorityName { get; set; }
1.NopCommerce and ASP.NET Core 3 Blazor
I have finally found a solution after struggling for a whole day.
The solution is to follow the instructions from the blog posts above but instead of registering Blazor the normal way, add this class in Nop.Web.Framework.Infrastructure
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Nop.Core.Infrastructure;
namespace Nop.Web.Framework.Infrastructure
{
public class BlazorStartup : INopStartup
{
public int Order => 999;//It has to be registered before NopMVCStartup
public void Configure(IApplicationBuilder application)
{
application.UseRouting();
application.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToController("Blazor", "Home");
});
}
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddServerSideBlazor();
}
}
}
2.I experimented and have ported nopCommerce to blazor and what I have:
3.I need to clear the code from unnecessary notes and implement a demo db before publishing. Maybe I will publish without db implementation. But I am tired a little bit of the project and I am lazy to do it right now. Your question is very wide. I changed target framework (for client-side in future), overrode the router, implemented native DI (memory leak of Autofac on preview stages), rewrote all necessary views to razor pages, rewrote all necessary controllers to the same razor pages, moved out all scripts to a js file, wrote some of extensions and utilities. I tried hard not to modify the native nopcommerce code like core, data, services and framework, only wrapping or overriding if it had needed.
asp.net core 3 blazor server-side.
Experimental based on nopCommerce v4.10 single page eStore.
Use DB v4.10
The source code https://github.com/aybelanov/spaCommerce
ASP.NET Core Blazor CSS isolation