轻识Logo
目录

    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 @onclick="CopyResult">复制</button>

            <button @onclick="ReadAloud">朗读</button>

            <button @onclick="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" @onclick="() => KeyPadClicked(num.ToString())">@i</button>

            </div>

        }

    </div>

    <div class="row">

        <div class="col-8">

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

        </div>

        <div class="col">

     <button class="btn btn-light key" @onclick='() => 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 只能哭晕在厕所也没人听见……


    往期精彩回顾




    【推荐】.NET Core开发实战视频课程 ★★★

    .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

    【.NET Core微服务实战-统一身份认证】开篇及目录索引

    Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

    .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    10个小技巧助您写出高性能的ASP.NET Core代码

    用abp vNext快速开发Quartz.NET定时任务管理界面

    在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

    现身说法:实际业务出发分析百亿数据量下的多表查询优化

    关于C#异步编程你应该了解的几点建议

    C#异步编程看这篇就够了

    浏览 42
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报
    转换器
    转换器
    0
    mmlsharpMathML转换器
    mmlsharp (MathML to C#) 是一个用来将 MathML 数学公式标识语言转换成
    mmlsharpMathML转换器
    0
    数字转换器
    数字转换器
    0
    通信转换器
    一款通过将LoRaWAN通信信号与RS485/MBUS信号进行转换,实现对表计设备的数据透传通信。
    博高信息
    0
    svg2pngSVG-to-PNG 转换器
    svg2png 是一个使用 PhantomJS 将 SVG 转换为 PNG 的工具。const fs
    svg2pngSVG-to-PNG 转换器
    0
    svg2pngSVG-to-PNG 转换器
    svg2png是一个使用PhantomJS将SVG转换为PNG的工具。constfs=require("pn/fs");//https://www.npmjs.com/package/pnconsts
    svg2pngSVG-to-PNG 转换器
    0
    数字转换器
    数字转换器
    0
    Regenerator转换器
    Regenerator是用来转换ECMAScript6的yield语法到现今的浏览器的一个转换器最简单使用:regeneratores6.js>es5.js#Justthetransform.r
    Regenerator转换器
    0
    迅捷转换器
    迅捷转换器
    0
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报

    深圳SEO优化公司福永seo优化大芬百度竞价包年推广罗湖seo南联百度爱采购龙岗网站制作设计永湖网络推广大浪SEO按效果付费大鹏百搜词包大运网站优化按天扣费双龙网站制作设计东莞SEO按天扣费东莞建网站民治SEO按天计费龙华设计公司网站平湖模板制作大芬百度标王南澳SEO按天收费南联网络营销大鹏外贸网站制作福永企业网站建设福永SEO按天收费坂田网站建设塘坑网站优化推广大鹏网站优化按天收费沙井优秀网站设计丹竹头网站推广工具永湖网站优化软件坪山模板制作平湖网站搭建塘坑百度seo歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

    深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化