1. Dotnet9首页
  2. .NET
  3. Blazor

我的『MVP.Blazor』快速创建与部署

我的『MVP.Blazor』快速创建与部署

最近一直在录Blog.Core相关的操作视频,也没有研究过什么新的东西,公司也各种项目迭代,特别是从Fwk迁移到NetCore,真的是不是一个容易的事,闲的时候,为了歇歇脑子,就抽出时间简单看了看又有哪些新技术,最近聊的挺多的就是Blazor了吧,所以我也看了看,这里声明一点,我并打算出一个完整的Blazor系列教程(最近老有人让我出系列教程🙃),只是走马观花的过一遍,看看这个到底是一个什么东西,感兴趣的自己可以去深入学习下,毕竟现在的资料还不是最多的,可以锻炼下自己,而且也算是一个吃螃蟹的人,毕竟有历史价值,好啦,废话不多说,直接开整。

1、这个项目的立项初衷

可能还有一部分小伙伴不太了解,我年初申请上了微软的MVP,我也没有过多的宣传,毕竟这只是一个鼓励而已,平时该解答的我还是会解答。MVP呢,每次只有一年的有效期,所以每个新的一年都还需要风雨兼程的往前走,还是需要传递知识,那就少不了将自己做过的,写过的,分享过的东西给列出来(注意:这里可能有转载别人的文章),作为一个展示,所以呢,我就想着自己写个小的Portal吧,把自己整理的东西给放出来,多半是微信公众号的,也可以给大家做一个方便查找和学习的列表。

但是在项目选型的时候,我犹豫了好几天,用什么呢,ASP.NET Core MVC么,其实我已经写了好多个了,公司的小项目也一直在使用,所以不想写了,无非就是增删改查。

前后端分离项目?也写的吐了,不想学React,我看国内外包企业用的比较多,但是我还是想结合下我的Blog.Core项目,毕竟已经封装的很好了,可以做为一个后端的资源服务器来使用。

与此同时,看到有人推送了多个关于微软的Blazor框架的相关内容,号称可以使用C#来写前端组件,个人表示很好奇。

基于以上三点呢,就选用了(Blazor+Blog.Core)的架构,你也可以把它理解成一个前后端分离的项目,因为我用的是wasm的客户端,用Blog.Core提供资源服务器,两者是分开部署的:

http://mvp.neters.club(这个就是客户端地址)

https://github.com/anjoy8/Blog.MVP.Blazor(开源地址)

我的『MVP.Blazor』快速创建与部署
(首次加载奇慢,还在研究,文末有说到)

目前这个只是一个小的版本,当然后边还是有很多问题的,可能会一直维护,慢慢添加,好啦,下边正式开始。

2、开发环境准备

1、更新工具

目前BlazorWebAssembly版本是3.2.0Previ,如果要使用它的话,必须要安装.NET Core3.1.2+的SDK,注意小版本也要2以上。

我的系统环境是:

VS 2019 16.4.0、.NET Core SDK 3.1.3

如果你想调试blazor的话,需要更新vs2019到16.6+的最新版本,

更新到16.6+后,不仅可以调试Blazor,它也自带了相应的开发模板,如果你现在还不想把自己的vs2019升级的话,只能手动先安装下模板了。

截至发稿,我已经升级到vs2019 16.6.1了。 

2、下载模板

使用前,需要安装对应的模板

dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0

安装完成后,可以看到我们的电脑里有模板:

我的『MVP.Blazor』快速创建与部署

然后我们可以打开VS2019,可以看到已经有对应的快捷入口:

我的『MVP.Blazor』快速创建与部署

点击创建:

我的『MVP.Blazor』快速创建与部署

可以看到,和我们的ASP.NetCore的webapi项目还是很像的,那到了这里,我们的项目环境就正式的搭建完成,下一步开始创建Demo了。

请注意:这里我们使用的是wasm客户端项目,不是server项目,从名字上也能明白两个对应的职能是什么,关于server的使用,我以后会说到。

3、创建一个默认的示例项目

通过上边的步骤,我们创建了一个wasm的初始化示例项目,结构如下:

我的『MVP.Blazor』快速创建与部署
├── launchSettings.json    // 配置文件(注意多了一个inspectUri的调试节点)
├── wwwroot // 静态文件夹
├── Pages // 页面文件夹
│   ├── Counter.razor // 页面内计数功能
│   ├── FetchData.razor // 远程获取数据功能
│   └── Index.razor // 网站首页
├── Shared // 项目公共组件库
│   ├── MainLayout.razor // 主要布局组件
│   ├── NavMenu.razor // 导航条组件
│   └── SurveyPrompt.razor // 提示组件
├── _Imports.razor // 项目常用引用导入
├── App.razor // 项目根文件
└── Program.cs // 项目主入口

从上边的项目结构中,我们基本也能看懂七七八八,当然,前提是稍微学过NetCore或者是MVC的Razor页面。

添加配置文件

你可以在wwwroot文件夹下,创建appsettings.json文件,然后在razor页面内注入:

{
    "message": "Hello from config!"
}
@page "/"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Configuration example</h1>

<p>@Configuration["message"]</p>

是不是很简单,可见依赖注入是多么的重要!

那分析完结构,直接运行下,看看效果。

F5 查看效果

我们直接执行F5,项目是会自动执行Build操作的,就像我们之前学习vue,执行了serve命令后,就能运行项目,监听端口了:

我的『MVP.Blazor』快速创建与部署
我的『MVP.Blazor』快速创建与部署

过程特别简单,而且渲染的也很快,具体的渲染逻辑这里不说了,自行研究吧,只要是会vue的话,肯定这个也能理解。

核心代码解释

官方给了三个例子,我这里简单说一下获取数据的吧,很简单,还是mvc的老路子,只不过增加了些MVVM的影子:

// 定义路由
@page "/fetchdata"

// 依赖注入对应的服务(注意命名空间System.Net.Http)
@inject HttpClient Http

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

// 渲染过程
@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

// c# 代码
@code {
    // 定义data变量
    private WeatherForecast[] forecasts;

    // 重写初始化函数,类似vue的 mounted
    protected override async Task OnInitializedAsync()
    {
        // 异步获取远程api接口数据
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
    }

    // 定义model 
    public class WeatherForecast
    {
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public string Summary { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}

核心的部分我都做了注释,相信都能看的懂,毕竟我相信,只有netcore学会了的小伙伴,才回去看blazor,如果netcore都不会,我不建议看。

这里强调的是,Http信息有两个版本,自己看好就行,毕竟不同的版本,对应不同的方法:

Microsoft.AspNetCore.Blazor.HttpClientSystem.Net.Http.Json
GetJsonAsyncGetFromJsonAsync
PostJsonAsyncPostAsJsonAsync
PutJsonAsyncPutAsJsonAsync

可能的错误

开发中可能会报错:

我的『MVP.Blazor』快速创建与部署

好啦,示例项目说完了,那接下来说说我的项目吧。

4、Blog.MVP.Blazor设计思路

其实也不算是设计思路,就说下如何做的吧。

我的『MVP.Blazor』快速创建与部署

1、所用接口

毕竟是辛辛苦苦搭建的Blog.Core项目,所以能用还是尽量用的,而且很巧的是,正好能和我这个无缝对接,仅仅需要用到博客表BlogArticle即可:

我的『MVP.Blazor』快速创建与部署

当时正好我做了博客分类bcategory这个字段,这里可以派上用场,因为我不想和Blog.Vue项目搞混,所以我新建的分类MVP_xxxx_这种格式,作者字段用的是微信公众号链接,其他的就是很基本的了。

接口1:获取指定分类的文章:

await Http.GetJsonAsync<MessageModel<PageModel<BlogArticle>>>
("/api/Blog?page=1&bcategory=MVP_ids4_2020&intPageSize=20");

这里很人性化,还可以指定返回类型,无缝对接我们的Blog.Core资源服务器。

接口2:做页面跳转,增加阅读量:

http://apk.neters.club/api/Blog/GoUrl?id=@(bID)

因为我们的地址是外链地址,而且还是微信文章的地址,如果是微信客户端外访问的话,系统是不会记录阅读量的,只能我们自己记录,所以我增加了这个跳转链接,很简单,自己查看代码即可。

2、设计组件

本来文章页只需要一个页面就行,然后通过参数传递,来实现不同信息展示,但是我偷懒了,直接多个页面,通过路由地址,强行的进行分类展示,这样不好,第一版先这么吧,但是也做了几个组件,比如:

// 设计html样式
<article class="article-post-summary">
    <div class="post-summary-box">
        <h4 class="post-summary-title">
            <a href="http://apk.neters.club/api/Blog/GoUrl?id=@(bID)">
                @btitle
            </a>
        </h4>
        // 参数的绑定
        <p class="post-summary-text">@bcontent</p>

        <div class="post-date-box d-md-block">
            <div class="post-date-day">
                @(bCreateTime.ToString("yyyy-MM-dd"))  (Reader:@btraffic)
            </div>
        </div>
    </div>
</article>
<div class="mb-4 d-md-block"></div>
<hr class="d-none d-md-block">

// 这里也可以写css

// 这里定义逻辑和data,是不是和vue的组件很像
@code {
    // Demonstrates how a parent component can supply parameters
    [Parameter]
    public int bID { get; set; }
    [Parameter]
    public string btitle { get; set; }
    [Parameter]
    public string bcontent { get; set; }
    [Parameter]
    public DateTime bCreateTime { get; set; }
    [Parameter]
    public int btraffic { get; set; }
}

还是三模块的形式,HTML-CSS-JS(这里是C#)的模式,是不是和vue的组件设计很像,当然至于能不能双向绑定,应该是可以的,你可以试试。

3、调用组件

这个也很简单,直接进行绑定数据即可:

@if (_blogs != null)
   {
       foreach (var item in _blogs.response.data)
       {
           <ArtBody bID="@item.bID" btitle="@item.btitle" bcontent="@item.bcontent" bCreateTime="@item.bCreateTime" btraffic="@item.btraffic" />
       }
   }
   else
   {
       <p><em>Loading...</em></p>
   }

而且也可以绑定命令事件:

<button class="btn btn-primary"  @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount =  0;
    // 定义事件方法
    private void IncrementCount()
    { 
        currentCount++;
    }
}

到了这里,如果你会vue开发,是不是感觉很blazor真的很像:

无论是数据的获取,

还是组件的定义,

然后是数据的绑定,

甚至是渲染的过程

4、绑定资源服务器地址

我们既然要用http请求,肯定要定义地址,在Program.cs文件中,直接定义:

builder.Services.AddBaseAddressHttpClient();
 builder.Services.AddTransient(sp => new HttpClient 
 { BaseAddress = new Uri("http://apk.neters.club") });

5、最后别忘了跨域配置

这个是老生常谈了,既然是分离,肯定要配置跨域,

我这里使用的是CORS跨域,NGINX部署,暂时还没有来得及代理的方式,以后有机会慢慢研究吧,CORS也是很简单的,配置后端口号就行了。

6、部署

其实这个很简单的,我们直接publish下我们的项目,就能看到打包好了,但是并没有我们想象中的项目名称的的dll,

我的『MVP.Blazor』快速创建与部署

如果你是IIS部署,那直接路径设置这个publish文件夹即可。

如果是Nginx部署,可以直接指定wwwroot路径,就像是部署打包好的vue项目一样。

5、未来的路还是很长的

其实你看完了文章,会发现目前还是遇到了很多问题,比如:

1、首次打开太慢了,竟然把dll文件也加载了,我怀疑是我的问题,但是还没有找到合适的资料,有知道的欢迎告诉我。

我的『MVP.Blazor』快速创建与部署

2、虽然很像vue,但是操作起来还是没有vue那么丝滑。

3、感觉还是和IIS很兼容,就像IdentityServer4那样。

但是!毕竟是一门新兴的技术,取名MVP.Blazor,也是希望能给Blazor一个好的未来吧,希望未来可期!

原文出处:微信公众号【老张的哲学 MVP NetCore 从壹开始】

原文链接:https://mp.weixin.qq.com/s/05bPydP1wZ6DUUQB-GnUuw

本文观点不代表Dotnet9立场,转载请联系原作者。

发表评论

登录后才能评论