Blazor WASM 实现人民币大写转换器

点击上方蓝字关注“汪宇杰博客”

导语

.NET 5 正式发布已经有一段时间了,其中 Blazor 技术是该版本的亮点之一。作为微软技术的被坑者,年少的我曾经以为 SilverLight 能血虐 Flash,Zune 能团灭 iPod,WP 能吊打 iPhone,UWP 能统一全平台…… 可是后…… 最终步入大龄程序员的我发现,只有陪伴了我将近 20 年的ASP.NET 还没有完蛋。于是我这两天花了点时间,尝试将我的一个 UWP 小工具用 Blazor 重写,分享给大家。

无法抢救的 UWP

人民币大写转换器” 是我年少无知时开发的小工具之一,它的主要功能有:

- 将数字金额转化为大写中文

- 复制结果

- 使用中文语音朗读结果

- 显示参照表

可惜 UWP 不论是充满 Bug 的 SDK,Runtime,还是微软的龟速更新与混乱的规划,都已经无可救药了,是时候给应用找个新家了。

Blazor

Blazor 是 .NET Core 时代微软推出的用于 Web 应用开发的新框架,它可以运行在服务器端,也可使用 WASM 运行在客户端,即浏览器中。

对我来说,这个技术最吸引人的,就是 WASM。像我这种已经30多岁,学不了新东西的 .NET 程序员,根本搞不定 Angular、Vue、React 这些花里胡哨的框架,而 Blazor WASM 是把 .NET 运行时搬到了浏览器端,和 SilverLight 类似,但这次是以WASM标准的形式运行,不需要安装插件,并且也能跨平台。

于是我可以继续使用熟悉的 .NET 和 C# 开发 SPA Web 应用。更重要的是,既然是原汁原味的 .NET,就可以很方便的重用以前的代码,以及现成的成千上万个 NuGet 包,而不用像一个新发明的框架那样从0开始积累生态。

我 996 了 2 小时,成功将“人民币大写转换器”重写到 Blazor WASM,效果如下:

Demo:https://rmbcap.azurewebsites.net/
源代码:https://github.com/EdiWang/RMBCapitalization-Blazor

由于篇幅关系,本文不叙述重写的每处细节,只参数关键点。其他细节大家可到 GitHub 阅读源代码了解。

创建 Blazor WASM 工程

我们可以使用 Visual Studio 2019 创建 Blazor WASM 工程。

选择 Blazor WebAssembly App 就可以了

工程结构

一个 Blazor WASM 项目的典型结构如上图。Program.cs 包含应用如何启动与承载的逻辑。

wwwroot 中的文件为纯 HTML/CSS/JS 文件,不包含.NET的逻辑。其中 index.html 为承载应用的默认页面,和 Angular 等 SPA 框架非常类似,它将会把应用页面加载到 <div id="app"> 中。

MainLayout.razor 是整个应用的布局页面,如果你有多个页面和视图,那么通常这里会放 Header,Footer 等内容。

Index.razor 为应用的默认主页。我这个应用只有一个页面,所以一切逻辑都在这里实现就可以了。

可重用的代码

人民币大写的转换类与框架和平台无关,因此完全可以直接复制到Blazor工程里用,即 RMBConverter.cs。

UWP 应用的视图通常采用 MVVM 模式开发,这些逻辑可以很方便的迁移到 Blazor。

Index.razor

就像写 MVC 的 cshtml 一样,使用熟悉的 Razor 语法,就能绑定数据和事件。

对于 input,简单的双向数据绑定可以直接用 @bind="属性" 实现。但我这个应用里要求用户一边输入金额一边进行实时计算,所以只能写成事件绑定。

<div>

    <h3> @Result </h3>

</div>

<div>

    <div>

        <input type="text" @bind-value="InputAmount" @bind-value:event="oninput" />

    </div>

    <div>

        <button @οnclick="CopyResult">复制</button>

        <button @οnclick="ReadAloud">朗读</button>

        <button @οnclick="Clear">清除</button>

    </div>

</div>

对于有参数的事件处理函数,要注意它和正常 C# 写事件一样,是个 Lambda 表达式,如果放在循环里的话要注意变量的值是在循环里被修改。

下面的代码必须使用 var num = i 来存储 i 的值,如果直接使用 KeyPadClicked(i),那么 i 一定永远等于1。

<div class="row">

    @for (int i = 1; i <= 9; i++)

    {

var num = i;

        <div class="col-4">

   <button class="btn btn-light key" @οnclick="() => KeyPadClicked(num.ToString())">@i</button>

        </div>

    }

</div>

<div class="row">

    <div class="col-8">

 <button class="btn btn-light key" @οnclick='() => KeyPadClicked("0")'>0</button>

    </div>

    <div class="col">

 <button class="btn btn-light key" @οnclick='() => KeyPadClicked(".")'>.</button>

    </div>

</div>

和 XAML 的 MVVM 以及 Angular 稍有不同的是,处理逻辑不是在 code behind 文件里写的,而是在 razor 页面本身写。如果能写成 Index.razor.cs 就干净了。

@code {

    private string _inputAmount;

    public string InputAmount

    {

        get => _inputAmount;

        set

        {

            _inputAmount = value;

            // 验证和处理逻辑...

            Result = string.IsNullOrWhiteSpace(_inputAmount) ?

                    string.Empty :

                    RMBConverter.GetCapitalizedRmb(InputAmount);

        }

    }

    public string Result { get; set; }

    private async Task CopyResult()

    {

        // ...

    }

    private async Task ReadAloud()

    {

        // ...

    }

    private void Clear()

    {

        InputAmount = string.Empty;

    }

    private void KeyPadClicked(string value)

    {

        InputAmount += value switch

        {

            "0" when InputAmount != "0" => 0,

            "." when !InputAmount.Contains(".") => ".",

            _ => value

        };

    }

}

需要重新实现的功能

复制文字

在 UWP 中,复制可以调用 Windows 的 Clipboard API 来完成。但是在浏览器端,没有 Windows 的 API,Blazor 也没有封装剪切板 API,因此我们只能借用 JS 来完成。

index.html

window.clipboardCopy = {

    copyText: function (text) {

        navigator.clipboard.writeText(text).then(function () {

            console.log(text);

        })

            .catch(function (error) {

                alert(error);

            });

    }

};

Index.razor

使用依赖注入,引入 IJSRuntime 的实例。这是 Blazor 用于和 JavaScript 交互的接口。

@inject IJSRuntime JavaScriptRuntime

然后就可以调用 JS 进行复制

private async Task CopyResult()

{

    if (!string.IsNullOrWhiteSpace(Result))

    {

        await JavaScriptRuntime.InvokeVoidAsync("clipboardCopy.copyText", Result);

    }

}

朗读

类似的,在 UWP 里,朗读使用的是 Windows 的 SpeechSynthesizer API。浏览器端也有个类似的 SpeechSynthesisUtterance。

index.html

window.readAloud = {

    readText: function (text) {

        let utterance = new SpeechSynthesisUtterance(text);

        utterance.lang = 'zh-CN';

        speechSynthesis.speak(utterance);

    }

}

Index.razor

private async Task ReadAloud()

{

    if (!string.IsNullOrWhiteSpace(Result))

    {

        await JavaScriptRuntime.InvokeVoidAsync("readAloud.readText", Result);

    }

}

本地应用

目前 Blazor WASM 还没有本地应用的官方支持,必须打开浏览器才能使用,现有的版本只能使用PWA完成一部分本地应用化操作。但在今年即将发布的 .NET 6 版本中,Blazor 会迎来官方最纯正的本地应用支持。只要不出自 SilverLight、Zune、WP、WinRT、UWP 团队之手,就不会被坑!

现存的问题

Blazor WASM 虽然看着香,但目前有一些痛点还有待解决。

首先,框架本身的体积依然较大,由于众所周知而不可描述的原因,如果服务器部署在海外,那么我国网络加载 Blazor 应用会比较慢。

另外,不是所有版本的浏览器都可以跑 WASM,尤其是手机端。Blazor 的兼容性相比 Angular,Vue,React 等,还有些差距。

总结

使用 Blazor WASM 开发 Web 应用能够让 .NET 程序员充分利用既有的知识和技能快速上手,结合 Web 的强大生态 与 .NET 的高效生产力,成就不凡。而 UWP 只能哭晕在厕所也没人听见……

汪宇杰博客

Azure | .NET | 微软 MVP

无广告,不卖课,做纯粹的技术公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金山安全实验室公布中国互联网六大类钓鱼网站

金山安全实验室公布中国互联网六大类钓鱼网站金山安全实验室研究人员对中国大陆钓鱼网站的普遍特征进行分析&#xff0c;发现以下六个领域最容易被钓鱼网站***&#xff1a;1.QQ十年庆典、QQ抽奖、腾讯活动&#xff1b;2.证券、股票分析、黑庄、理财专家等财经领域&#xff1b;3…

程序员过关斩将--领导说我的类的职责不单一

“为什么类的职责要单一化&#xff1f;“类的职责单一化很容易吗&#xff1f;首先&#xff0c;我要提醒一下看到这篇文章的同学&#xff0c;我认为保证类&#xff08;一定是类吗&#xff1f;&#xff09;的单一职责并不容易软件开发过程中&#xff0c;自古就流传着几大规则&…

从概念到案例,机器学习应该掌握的20个知识点

随着科技的发展&#xff0c;计算机对人类的生产活动和社会活动产生了极为重要的影响&#xff0c;同时以强大的生命力飞速发展着。目前计算机正广泛用于社会各个领域&#xff0c;并朝着微型化、网络化、智能化和巨型化的方向前进。说到智能化&#xff0c;大家最先想到的应该就是…

闲来没事写个记事本玩玩!!!

这两天工作压力大&#xff0c;还好今天见着太阳了&#xff0c;这会儿没事写了个记事本&#xff0c;功能单一&#xff0c;适合练手&#xff0c;可能对新手会有所帮助&#xff0c;贴上来看看吧&#xff0c; 说到实现 记事本&#xff0c;我们应该选择什么样的控件呢&#xff0c;Te…

LG将授权webOS给其他电视厂商使用

喜欢就关注我们吧&#xff01;LG 将向其他公司提供 webOS。根据 LG 发布的公告&#xff0c;其自家电视机搭载的专有系统 webOS 将会授权给其他的外部电视厂商使用。被授权使用 webOS 的电视厂商还会获得来自 LG 的 Magic Motion 遥控器&#xff0c;此外&#xff0c;系统的语音控…

数据之美,堪比好莱坞大片!

看完下面的几张图&#xff0c;你就知道自己有多无知了。堪称是好莱坞大片啊&#xff01;1城市3D空间通过2D瓦片图层的3D化&#xff0c;能够在经度维度、量级、时间多个维度上真实还原城市3D空间。例子中为模拟的轨迹数据和旧金山食物供应商分布。2GPS轨迹分布以三种不同的方式描…

HSRP的配置问题

HSRP的配置问题<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />实验目的&#xff1a;理解和掌握路由热备份的配置步骤和原理实现网关的冗余功能实验环境&#xff1a;如下图所示<?xml:namespace prefix v ns "urn:sch…

数学从小学开始“梯次掉队”?别让课本的枯燥“浇灭”孩子对数学的兴趣

1、2、3、4、5……从孩子用手指数数开始&#xff0c;就与数学结下了不解之缘。进入幼儿园&#xff0c;在老师的指导下画出三角形&#xff0c;圆形等&#xff0c;这是数学中的几何。稍大一点&#xff0c;到商店里买东西&#xff0c;开始懂得买的东西是多还是少&#xff0c;是大还…

用算法撩妹都不会,别跟我说你是程序员

程序员浪漫的表白方式可以说是花样百出&#xff0c;为什么用在自己身上就没效果呢&#xff1f;作为一个程序员“身边的女生”&#xff0c;小编觉得&#xff0c;大部分程序员没有女朋友&#xff0c;很可能是恋爱技能bug太多&#xff0c;当你还不确定那个女生对你的喜欢程度&…

从工作经历和实践理论看工业互联网的发展

一.前言本篇文章是对以前点点滴滴的记录整理而成&#xff0c;也是我们做iNeuOS工业互联网操作系统进行的深入思考。本篇文章有宣传产品之嫌&#xff0c;但是确实是我们理念与实践相结合的产物。下面的图是我2017年参加完工博会后&#xff0c;在QQ群里做的调查&#xff0c;仅供大…

关于c语言的符号常量以下叙述中正确的是,关于C语言的符号常量,以下叙述中正确的是...

摘要&#xff1a;项指需要哪一以下标不上报&#xff0c;关于女病工作普查普治评价进行对妇时。下列正确的是说法&#xff0c;符号治愈率达&#xff0c;告说治疗者某广某药斑狼了2例红疮患&#xff0c;其中痊愈0例。行为个体这种矫正称为方法&#xff0c;常量吸烟济处烟者予经当…

2017年终奖发放,程序员人均11776元排名第一!

又到了一年一度的“晒年终奖”时刻了&#xff01;你敢晒一波吗&#xff1f;快过年了&#xff0c;又到了一年一度的年终奖盘点时间&#xff01;此可谓扎心扎心再扎心&#xff01;那么&#xff0c;你2017年的年终奖有多少&#xff1f;满意不&#xff1f;2017年全国白领人均年终奖…

因MemoryCache闹了个笑话

前言是这么一回事&#xff1a;我正在苦思一个业务逻辑&#xff0c;捋着我还剩不多的秀发&#xff0c;一时陷入冥想中……突然聊天图标一顿猛闪&#xff0c;打开一看&#xff0c;有同事语音&#xff1b;大概意思是&#xff1a;同事把项目中Redis部分缓存换成MemoryCache/Memcach…

Coursera吴恩达《卷积神经网络》课程笔记(1)-- 卷积神经网络基础

推荐阅读时间&#xff1a;8min~15min主要内容&#xff1a;卷积神经网络《Convolutional Neural Networks》是Andrw Ng深度学习专项课程中的第四门课。这门课主要介绍卷积神经网络&#xff08;CNN&#xff09;的基本概念、模型和具体应用。该门课共有4周课时&#xff0c;所以我将…

纯c语言实现的改进暗通道去雾算法测试程序(附赠大量测试图像),基于改进暗通道先验算法的图像去雾...

邱清辉摘要&#xff1a;针对普通暗通道先验算法去雾能力的不足&#xff0c;本文提出了一种改进算法&#xff0c;通过采用高斯平滑将原图像分为基础子图和细节子图&#xff0c;基础子图采用暗通道先验算法&#xff0c;细节子图采用gamma变换方法&#xff0c;再采用图像融合进行融…

为什么离开学校后,学习能力直线下降?

最近几年&#xff0c;人工智能浪潮层层推进&#xff0c;对各大科技公司产生巨大影响。百度推出Apollo无人车计划&#xff0c;阿里建立达摩院&#xff0c;腾讯成立的AI Lab虽布局较晚却也不甘人后。ChinaAI已是大势所趋&#xff0c;吸引的不仅是大公司&#xff0c;更有许多人工智…

android6.0重力工具箱,重力工具箱 GravityBox For Android8.0/8.1(Oreo)稳定版发布!

作为功能最强大的Xposed框架模块之一&#xff0c;重力工具箱 GravityBox的更新适配一直也是最积极的&#xff0c;本次发布的8.x专用版本也算是比较及时&#xff0c;每一个大的Android版本&#xff0c;重力工具箱基本都会有一个专门的版本来适配&#xff0c;当然基础功能也会略有…

如何在 ASP.Net Core 中使用 MediatR

MediatR 是一个 中介者模式 的.NET开源实现&#xff0c; 中介者模式 管控了一组对象之间的相互通讯并有效的减少了对象之间错综复杂的相互依赖&#xff0c;在 中介者模式 中&#xff0c;一个对象不需要直接和另一个对象进行通讯&#xff0c;而是通过 中介者 进行转达&#xff0…

全球100款大数据工具汇总(前50款)

01 Talend Open Studio是第一家针对的数据集成工具市场的ETL(数据的提取Extract、传输Transform、载入Load)开源软件供应商。Talend的下载量已超过200万人次&#xff0c;其开源软件提供了数据整合功能。其用户包括美国国际集团&#xff08;AIG&#xff09;、康卡斯特、电子港湾…

NLP快速入门:手把手教你用HanLP做中文分词

导读&#xff1a;随着自然语言处理(Natural Language Processing, NLP)技术日趋成熟&#xff0c;实现中文分词的工具也越来越多。中文分词技术作为中文自然语言处理的第一项核心技术&#xff0c;是众多上层任务的首要基础工作&#xff0c;同时在日常的工作中起着基础性的作用。…