Popular blog tags

Blazor is a new web UI framework based on C#, Razor, and HTML.  This runs in the browser via WebAssembly.  It helps build interactive web UI using C# instead of JavaScript.  This post demonstrates how to build a SPA using Blazor.  Blazor simplifies the task of building fast and beautiful SPAs that run in any browser. It does this by enabling developers to write Dotnet based web apps that run client-side in web browsers using open web standards. Let’s get started with Blazor.

 

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

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:

https://blazor.skywell.net/

 

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

https://github.com/daveabrock/AspNetCore.Docs/blob/daveabrock/css-isolation/aspnetcore/blazor/components/css-isolation.md