【ASP.NET Core】在node.js上托管Blazor WebAssembly应用

asp,net,core,node,js,托管,blazor,webassembly,应用 · 浏览次数 : 367

小编点评

**创建 Blazor wasm 应用** 1. 使用 `dotnet new blazorwasm-empty` 创建一个新的 Blazor wasm 项目。 2. 在 `Program.cs` 中精简代码,将 `var builder = WebAssemblyHostBuilder.CreateDefault(args);` 和 `builder.RootComponents.Add<App>(\"#app\")` 移除,并添加 `builder.UseDefaultViewModelProvider();`。 3. 在 `Index.razor` 中添加一些交互功能,例如按钮点击事件。 4. 运行项目,检查是否正常启动。 **发布项目** 1. 将 `_framework` 目录中的所有文件复制到 `Server` 目录中。 2. 在 `index.html` 中添加一个 `id` 为 `app` 的元素,并引用 `app.js` 文件。 3. 在 `app.js` 中引入 `node:url`、`node:path` 和 `node:http` 模块,并使用它们读取文件并设置 MIME 类型。 4. 在 `Server` 目录中创建一个 `app.js` 文件,并将其内容设置为以下代码: ```javascript const url = require("node:url"); const path = require("node:path"); const http = require("node:http"); const fs = require("node:fs"); const host = 'localhost'; const port = 6748; const mimeType = path.extname(fileName).toLowerCase(); http.createServer((request, response) => { let reqPath = url.parse(request.url).pathname; let fileName = reqPath.substring(1); if (fileName.length === 0) { fileName = "index.html"; } fs.readFile(fileName, (err, data) => { if (err) { // 直接回个404 response.writeHead(404, { "Content-Type": "text/html" }); } else { // 设置 MIME 类型 response.writeHead(200, { "Content-Type": mimeType }); // 发送正文 response.write(data); } }); }).listen(port, host); console.log(`服务器:${host}:${port}`); ``` **运行应用程序** 1. 在浏览器中打开 `http://localhost:6748` 地址。 2. 验证 Blazor 应用是否成功启动。 **注意** * 在发布过程中,确保所有文件都有读取权限。 * 可以使用 `dotnet publish` 命令将应用程序发布到 `Server` 目录中。

正文

由于 Blazor-WebAssembly 是在浏览器中运行的,通常不需要执行服务器代码,只要有个“窝”能托管并提供相关文件的下载即可。所以,当你有一个现成的 Blazor wasm 项目,没必要用其他语言重写,或者你不想用 ASP.NET Core 来托管(有些大材小用了),就可以试试用 node.js 来托管。

要实现这个不需要掌握什么新的知识,所以咱们直接开工干活。

首先,咱们做好 Blazor wasm 应用的开发。

dotnet new blazorwasm-empty -n Demo -o .

blazorwasm-empty 模板创建的项目只带一些基本代码和 Hello World,没有演示代码——无Counter无假天气预报。

然后,Program.cs 文件也可以精简一下。

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");

await builder.Build().RunAsync();

#app 是CSS筛选器,即选择 id 为 app 的元素来呈现 Razor 组件。这个相信各位都懂。

为了更好地演示,咱们把 Index 组件改一下,加一点交互功能,以便后面可以验证 Blazor 是否正常启动。

@page "/"

<h1>Hello, world!</h1>
<button @onclick="ClickMe">点这里中大奖</button>
<div>@Message</div>

@code{
    private string? Message{get;set;}

    void ClickMe()
    {
        int xx = Random.Shared.Next(100, 700);
        Message = $"恭喜你获得{xx}万假钞!";
    }
}

这个不复杂,就是点击一下按钮,然后生成个随机整数,并修改 Message 属性。处理 click 事件要注意加上 @,如果是 onclick 你只能用 js 去写,要想用 C# 来写代码,就得用 @onclick。

接着,试执行一下,保证没有错误,能正常运行。

 

现在,你打开 \bin\Debug\net7.0\wwwroot 目录,里面你看到有个 _framework 目录,这个目录就是我们要的。不过,这个体积太大,不适合。咱们将项目发布一下,这样体积会变小很多。

我们不需要 wwwroot 目录下的东东,把整个目录“咔嚓”掉(这里指的是项目中的 wwwroot 目录,不是输出目录的)。为了防止重新生成时有文件错误(一般不会),可以把 obj 和 bin 目录也删除。

执行发布命令。

dotnet publish -c PublishRelease

-c 参数也可以用 Release,差别不大。

另外新建一个目录,路径随便,不要有非英文字符(防止出错),比如这里我命名为 Server。把刚才发布的整个 _framework 目录复制到 Server 目录中。现在你可以关闭 Blazor 项目了,没它什么事了。

在 Server 目录下新建一个文件,叫 index.html。

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8"/>
        <title>高级示例</title>
    </head>
    <body>
        <div id="app">正在加载……</div>
        <script src="_framework/blazor.webassembly.js"></script>
    </body>
</html>

这里注意两处:

1、要有一个 id 为 app 的元素,它用来呈现组件。

2、<script> 要引用 blazor.webassembly.js 文件。

 

在 Server 目录下再新建一个文件,名为 app.js。这个用来写服务器主程序(js 代码)。

const url = require("node:url");
const path = require("node:path");
const http = require("node:http");
const fs = require("node:fs");

// 主机
const host = 'localhost';
// 端口
const port = 6748;
// MIME 映射
function getFileMap(fileExt)
{
    switch(fileExt)
    {
        case ".js":
        case ".mjs":
            return "text/javascript";
        case ".json":
            return "application/json";
        case ".htm":
        case ".html":
            return "text/html";
        case ".css":
            return "text/css";
        case ".jpg":
        case ".jpeg":
            return "image/jpeg";
        // 其他的自己看情况添加
        default:
            // 其余的如.dll、.gz等,就是二进制文件
            return "application/octet-stream";
    }
}

http.createServer((request, response)=>
{
    // 获取请求路径
    let reqPath = url.parse(request.url).pathname;
    // 去掉路径开头的“/”
    let fileName = reqPath.substring(1);
    // 如果空白,默认文件名 index.html
    if(fileName.length === 0)
    {
        fileName = "index.html";
    }
    // 读取文件内容
    fs.readFile(fileName, (err, data)=>{
        // 如果出错
        if(err)
        {
            // 直接回个404
            response.writeHead(404, {"Content-Type": "text/html"});
        }
        else
        {
            // 获取文件扩展名,以决定MIME类型
            let ext = path.extname(fileName);
            let mimeType = getFileMap(ext.toLowerCase());
            // 发送HTTP头
            response.writeHead(200, {"Content-Type": mimeType});
            // 发送正文
            response.write(data);
        }
        // 这一行必须,结束响应消息
        response.end();
    });
})
.listen(port, host);

console.log(`服务器:${host}:${port}`);

运行它,执行:node app.js。接着在浏览器中输入地址:http://localhost:6748。再验证 Blazor 应用程序是否成功启动。

 

如果看到随机数能正确生成,说明运行成功了。

 

与【ASP.NET Core】在node.js上托管Blazor WebAssembly应用相似的内容:

【ASP.NET Core】在node.js上托管Blazor WebAssembly应用

由于 Blazor-WebAssembly 是在浏览器中运行的,通常不需要执行服务器代码,只要有个“窝”能托管并提供相关文件的下载即可。所以,当你有一个现成的 Blazor wasm 项目,没必要用其他语言重写,或者你不想用 ASP.NET Core 来托管(有些大材小用了),就可以试试用 node

【ASP.NET Core】在 Mini-API 中注入服务

经过版本更新,Mini API 的功能逐步完善,早期支持得不太好的 mini API 现在许多特性都可以用了,比如灰常重要的依赖注入。 咱们先来个相当简单的注入测试。来,定义一个服务类,为了偷懒,老周这里就不使用 接口 + 实现类 的方式了。 public class MyService : IDi

.NET 8 Release Candidate 1 (RC1)现已发布,包括许多针对ASP.NET Core的重要改进!

这是我们计划在今年晚些时候发布的最终.NET 8版本之前的两个候选版本中的第一个。大部分计划中的功能和变更都包含在这个候选版本中,可以供您尝试使用。您可以在文档中找到完整的ASP.NET Core在.NET 8中的新功能列表。一些领域(尤其是Blazor)仍然有一些重大的变更待完成,我们预计将在下一

NET9 AspnetCore将整合OpenAPI的文档生成功能而无需三方库

OpenAPI 规范是用于描述 HTTP API 的标准。该标准允许开发人员定义 API 的形状,这些 API 可以插入到客户端生成器、服务器生成器、测试工具、文档等中。尽管该标准具有普遍性和普遍性,但 ASP.NET Core 在框架内默认不提供对 OpenAPI 的支持。 当前 ASP.NET

【源码解读】asp.net core源码启动流程精细解读

引言 core出来至今,已经7年了,我接触也已经4年了,从开始的2.1,2.2,3.1,5,6再到如今的7,一直都有再用,虽然我是一个Winform仔,但是源码一直从3.1到7都有再看,然后在QQ上面也一直比较活跃,之前好几年前一直说给大家解读asp.net core源码,在之前的博客中,讲的都是比

Asp-Net-Core开发笔记:使用RateLimit中间件实现接口限流

前言 最近一直在忙(2月份沉迷steam,3月开始工作各种忙),好久没更新博客了,不过也积累了一些,忙里偷闲记录一下。 这个需求是这样的,我之前做了个工单系统,现在要对登录、注册、发起工单这些功能做限流,不能让用户请求太频繁。 从 .Net7 开始,已经有内置的限流功能了,但目前我们的项目还在使用

Asp-Net-Core学习笔记:gRPC快速入门

## 前言 此前,我在做跨语言调用时,用的是 Facebook 的 Thrift,挺轻量的,还不错。 >Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码

【ASP.NET Core】MVC操作方法如何绑定Stream类型的参数

咱们都知道,MVC在输入/输出中都需要模型绑定。因为HTTP请求发送的都是文本,为了使其能变成各种.NET 类型,于是在填充参数值之前需 ModelBinder 的参与,以将文本转换为 .NET 类型。 尽管 ASP.NET Core 已内置基础类型和复杂类型的各种 Binder,但有些数据还是不能

【ASP.NET Core】修改Blazor.Server的Hub地址后引发的问题

Blazor Server,即运行在服务器上的 Blazor 应用程序,它的优点是应用程序在首次运行时,客户端不需要下载运行时。但它的代码是在服务器上执行的,然后通过 SignalR 通信来更新客户端的 UI,所以它要求必须建立 Web Socket 连接。 用于 Blazor 应用的 Signal

Asp-Net-Core学习笔记:单元测试和集成测试

## 前言 我在使用 AspNetCore 的这段时间内,看了很多开源项目和博客,发现各种 .Net 体系的新技术很多人都有关注和使用,但却很少有人关注测试。 测试是软件生命周期中的一个非常重要的阶段,对于保证软件的可靠性具有极其重要的意义。在应用程序的开发过程中,为了确保它的功能与预期一致,必须对