7

ASP.NET Core MVC集成Blazor实现一个简单的dashboard案例分享

 2 years ago
source link: https://masuit.com/76
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Blazor,一个微软发明的神奇的开发框架,它使得通过C#开发前端应用变得更加容易了,不需要写更多繁杂的javascript代码即可实现非常丰富的前端交互。

所以,Blazor=Browser+Razor。

本文就带大家将Blazor集成到MVC应用中,并实现一个简单的dashboard自动推送案例,先看效果:

虽然微软官方没有找到MVC中集成Blazor的文档,但经过摸索和实践,MVC与Blazor是可以完美契合的,它们都在一套框架里,是不需要再引用别的程序包就能集成到一起的。好了,闲话少说,开始实战吧!

MVC集成Blazor步骤

首先,创建一个.NET5的MVC应用,然后在Startup.cs中配置Blazor服务:

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddServerSideBlazor(); // 注入服务端Blazor服务
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub(); // 映射Blazor路由
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}

在项目根目录下添加Blazor专属的_Imports.razor,并导入如下命名空间:

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop

在需要集成的MVC页面中添加Blazor脚本_framework/blazor.server.js,一定要写在html的最后面,因为实测了写在head里面运行不正常:

@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
<div>
</div>
<script src="_framework/blazor.server.js"></script>
</body>
</html>

比如我将上面的代码添加到HomeController的Index的View中。

到此为止,MVC项目就算是把Blazor集成进来了,接下来就可以写Razor组件,然后在cshtml中进行引用了。

实现硬件检测dashboard案例准备

首先引入咱家的Masuit.Tools.Core,因为里面有封装好的硬件监测功能:

PM> Install-Package Masuit.Tools.Core

然后在cshtml页面中引入echarts5的js文件,我们通过echarts图表库实现可视化展示:

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

在echarts官网找的仪表盘案例代码,毕竟是javascript,而且Blazor组件中不能写javascript代码,接下来我们需要通过C#代码去调用javascript代码,所以将echarts的案例代码稍作改变,封装成一个js函数,放入cshtml中:

案例地址:https://echarts.apache.org/next/examples/zh/editor.html?c=gauge-multi-title

function show(){
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var option = {
series: [{
type: 'gauge',
anchor: {
show: true,
showAbove: true,
size: 18,
itemStyle: {
color: '#FAC858'
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 8,
length: '80%',
offsetCenter: [0, '8%']
},
progress: {
show: true,
overlap: true,
roundCap: true
},
axisLine: {
roundCap: true
},
data: [{
value: 0,
name: 'CPU使用率',
title: {
offsetCenter: ['-40%''80%']
},
detail: {
offsetCenter: ['-40%''95%']
}
},
{
value: 0,
name: '内存使用率',
title: {
offsetCenter: ['0%''80%']
},
detail: {
offsetCenter: ['0%''95%']
}
},
{
value: 0,
name: 'CPU温度',
title: {
offsetCenter: ['40%''80%']
},
detail: {
offsetCenter: ['40%''95%']
}
}
],
title: {
fontSize: 14
},
detail: {
width: 40,
height: 14,
fontSize: 14,
color: '#fff',
backgroundColor: 'auto',
borderRadius: 3,
formatter: '{value}'
}
}]
};
myChart.setOption(option);
}

开始写Blazor组件Counter.razor

创建组件Counter.razor组件,并给图表创建个div,供展示用:

<div id="container" style="height: 600px; width: 600px"></div>

在Counter.razor的生命周期OnAfterRenderAsync中,调用上面写好的javascript函数,而C#调用javascript函数我们需要注入IJSRuntime实例;

在组件顶部注入IJSRuntime:

@inject IJSRuntime JS;

生命周期中调用,这里需要注意,C#调用javascript函数只能在OnAfterRender(Async)中进行调用:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await JS.InvokeVoidAsync("show");
}

将Counter.razor添加到cshtml页面中:

<component type="typeof(Counter)" render-mode="ServerPrerendered" />

现在,我们可以运行起来,可以看到图表成功显示出来:

但是,它没有动起来,所以接下来最后一步,就是要让它动起来,我们参照echarts官网的案例,案例通过setInterval生成随机数让图表动起来,那我们就通过setInterval轮询去调用C#的函数不就可以了吗!

我们在Counter.razor组件中添加一个静态的函数GetInfo,用于获取CPU使用率,内存使用率和CPU温度,且这个函数需要被JSInvokable标记才能够被javascript调用到;

[JSInvokable]
public static async Task<List<double>> GetInfo()
{
return await Task.FromResult(new List<double>() {
SystemInfo.CpuLoad,
SystemInfo.GetRamInfo().MemoryUsage,
SystemInfo.GetCPUTemperature()
});
}

然后我们回到cshtml页面中,在javascript的show函数中添加setInterval轮询:

setInterval(function () {
DotNet.invokeMethodAsync('BlazorSamples''GetInfo').then(data => {
option.series[0].data[0].value = data[0].toFixed(2);
option.series[0].data[1].value = data[1].toFixed(2);
option.series[0].data[2].value = data[2].toFixed(2);
myChart.setOption(option, true);
});
}, 1000);

这里需要说明的是:DotNet.invokeMethodAsync的两个参数,其中第一个参数是被调用方的程序集名称,第二个参数是被调用的方法名,invokeMethodAsync调用的是异步C#函数,invokeMethod则是调用同步的C#函数。

接下来再次运行,即可看到图表动起来了

https://ldqk.lanzoux.com/iTKtzjozvmb

实现这么一个案例,真的没有写几行代码,相比之前分享的通过SignalR实现自动推送的案例,是不是简单太多了,而且相比SignalR,Blazor上手简直不要太简单,上手之后,不禁高呼:微软牛逼!Blazor Yes!🥳🥳

https://docs.microsoft.com/zh-cn/aspnet/core/blazor/?view=aspnetcore-3.1


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK