前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我的『MVP.Blazor』快速创建与部署

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

作者头像
老张的哲学
发布2022-04-11 14:35:41
8660
发布2022-04-11 14:35:41
举报
文章被收录于专栏:NetCore 从壹开始

最近一直在录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(开源地址)

(首次加载奇慢,还在研究,文末有说到)

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

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、下载模板

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

代码语言:javascript
复制
dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0

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

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

点击创建:

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

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

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

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

代码语言:javascript
复制
├── 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页面内注入:

代码语言:javascript
复制
{
    "message": "Hello from config!"
}
代码语言:javascript
复制
@page "/"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Configuration example</h1>

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

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

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

F5 查看效果

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

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

核心代码解释

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

代码语言:javascript
复制
// 定义路由
@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信息有两个版本,自己看好就行,毕竟不同的版本,对应不同的方法:

代码语言:javascript
复制
GetFromJsonAsync

可能的错误

开发中可能会报错:

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

4、Blog.MVP.Blazor设计思路

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

1、所用接口

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

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

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

代码语言:javascript
复制
await Http.GetJsonAsync<MessageModel<PageModel<BlogArticle>>>
("/api/Blog?page=1&bcategory=MVP_ids4_2020&intPageSize=20");

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

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

代码语言:javascript
复制
http://apk.neters.club/api/Blog/GoUrl?id=@(bID)

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

2、设计组件

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

代码语言:javascript
复制
// 设计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、调用组件

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

代码语言:javascript
复制
   @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>
   }

而且也可以帮忙命令事件:

代码语言:javascript
复制
<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文件中,直接定义:

代码语言:javascript
复制
 builder.Services.AddBaseAddressHttpClient();
 builder.Services.AddTransient(sp => new HttpClient 
 { BaseAddress = new Uri("http://apk.neters.club") });

5、最后别忘了跨域配置

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

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

6、部署

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

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

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

5、未来的路还是很长的

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

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

2、虽然很像vue,但是操作起来还是没有vue那么丝滑。 3、感觉还是和IIS很兼容,就像IdentityServer4那样。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 NetCore 从壹开始 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档