Blazor University (43)JavaScript 互操作 —— 类型安全

原文链接:https://blazor-university.com/javascript-interop/calling-dotnet-from-javascript/type-safety/

类型安全

在从 JavaScript 调用 .NET[1] 部分中,您可能已经注意到我们的 JavaScript 的第 6 行在将随机生成的数字传递给 .NET 之前调用了 toString()

var BlazorUniversity = BlazorUniversity || {};
BlazorUniversity.startRandomGenerator = function(dotNetObject) {setInterval(function () {let text = Math.random() * 1000;console.log("JS: Generated " + text);dotNetObject.invokeMethodAsync('AddText', text.toString());}, 1000);
};

尽管对象类型在 JavaScript 中是可以互换的,但是当它们被传递给我们的 .NET Invokable 方法时,它们就不是那么互换了。调用 .NET 时,请确保为要传递的变量选择正确的 .NET 类型。

JavaScript 类型.NET 类型
booleanSystem.Boolean
stringSystem.String
numberSystem.Float / System.Decimal
DateSystem.DateTime 或 System.String

枚举

JSInvokable .NET 方法的参数是枚举时,JavaScript 应该传递枚举的数值。下面的示例将使用值 TestEnum.SecondValue 调用我们的 .NET 方法。

public enum TestEnum
{FirstValue = 100,SecondValue = 200
};[JSInvokable("OurInvokableDotNetMethod")]
public void OurInvokableDotNetMethod(TestEnum enumValue)
{
}

但是,如果我们用 [System.Text.Json.Serialization.JsonConverter] 装饰我们的枚举,我们可以让我们的 JavaScript 改为传递字符串值。

[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
public enum TestEnum
{FirstValue = 100,SecondValue = 200
};

现在调用 JavaScript 可以传递枚举值的名称或其数值。以下两个调用是等效的。

dotNetObject.invokeMethodAsync('OurInvokableDotNetMethod', 'FirstValue');
dotNetObject.invokeMethodAsync('OurInvokableDotNetMethod', 200);

调用静态 .NET 方法

除了在 .NET 对象实例上调用方法外,Blazor 还使我们能够调用静态方法。下一个示例将展示如何从 JavaScript 调用 .NET 并检索 API 调用可能需要的特定设置,例如 Google Analytics

从服务器设置中读取 JavaScript 设置的好处是,在部署过程中可以根据环境(开发/QA/生产)覆盖这些值,而无需更改 JavaScript 文件。

源代码[2]

  • 创建新的 Blazor 服务器端应用程序

  • 打开 /appsettings.json 文件并添加一个名为“JavaScript”的部分

{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"JavaScript": {"SomeApiKey":  "123456789"},"AllowedHosts": "*"
}
  • 接下来我们需要一个类来保存这个设置,创建一个名为 Configuration 的文件夹

  • 在该文件夹中,创建一个名为 JavaScriptSettings.cs 的文件

public class JavaScriptSettings
{public string SomeApiKey { get; set; }
}
  • 编辑 /Startup.cs 文件

  • 在该类的构造函数中,我们将使用注入的 IConfiguration 实例从 /appsettings.json 中获取“JavaScript”部分并将其存储在静态引用中。

public Startup(IConfiguration configuration)
{Configuration = configuration;var javaScriptSettings = configuration.GetSection("JavaScript").Get<JavaScriptSettings>();JavaScriptConfiguration.SetSettings(javaScriptSettings);
}
  • JavaScriptConfiguration 类还不存在,所以接下来我们将在 Configuration 文件夹中创建它。

public static class JavaScriptConfiguration
{private static JavaScriptSettings Settings;internal static void SetSettings(JavaScriptSettings settings){Settings = settings;}public static JavaScriptSettings GetSettings() => Settings;
}

现在我们的配置文件中有一些新设置,一个在 .NET 中表示这些设置的类,我们正在读取这些值并将它们存储在静态引用中。接下来我们需要从 JavaScript 访问它。

  • 编辑 /Pages/_Host.cshtml 文件并在现有 <script> 标记下添加以下内容

<script src="~/scripts/CallingStaticDotNetMethods.js"></script>
  • 接下来,在 /wwwroot 文件夹下创建一个名为 scripts 的文件夹

  • 在该文件夹中,创建一个名为 CallingDotNetStaticMethods.js 的新文件并添加以下脚本

setTimeout(async function () {const settings = await DotNet.invokeMethodAsync("CallingStaticDotNetMethods", "GetSettings");alert('API key: ' + settings.someApiKey);
}, 1000);

DotNet.invokeMethodAsync 至少需要两个参数。可以传递两个以上,并且第二个之后的任何参数都被认为是作为参数传递给方法的值。

  1. 方法所在的二进制文件的全名(不包括文件扩展名)

  2. 要执行的方法的标识符

最后一块拼图是用 [JSInvokable] 属性装饰方法,传入标识符——在本示例中,标识符将是 GetSettings

编辑 /Configuration/JavaScriptConfiguration 类,并更改 GetSettings 方法:

[JSInvokable("GetSettings")]
public static JavaScriptSettings GetSettings() => Settings;

传递给 [JSInvokable] 的标识符不必与方法名称相同。

JavaScript 可调用方法的条件

要成为可通过这种方式调用的候选 .NET 方法,该方法必须满足以下条件:

  • 拥有该方法的类必须是公共的 -方法必须是公开的

  • 必须是静态方法

  • 返回类型必须为 void,或可序列化为 JSON——或者它必须是 TaskTask<T>,其中 T 可序列化为 JSON

  • 所有参数必须可序列化为 JSON

  • 该方法必须用 [JSInvokable] 装饰

  • JSInvokable 属性中使用的同一标识符不能在单个程序集中多次使用。

注意:不要立即从 JavaScript 调用 .NET 静态方法

如果您回顾 JavaScript 启动过程[3]部分,您会记得 JavaScript 在 Blazor 初始化之前已在浏览器中初始化。

6376e418620dd48f03454c92c2c0e65f.png

正是出于这个原因,我们只在初始超时后调用 .NET 静态方法——在这种情况下,我选择了一秒。

setTimeout(async function () {const settings = await DotNet.invokeMethodAsync("CallingStaticDotNetMethods", "GetSettings");alert('API key: ' + settings.someApiKey);
}, 1000);

在撰写本文时,无法从 JavaScript 检查 Blazor 是否已准备好被调用,而无需尝试调用它并失败。

window.someInitialization = async function () {try {const settings = await DotNet.invokeMethodAsync("CallingStaticDotNetMethods", "GetSettings");alert('API key: ' + settings.someApiKey);}catch {// Try againthis.setTimeout(someInitialization, 10);}
}
window.someInitialization();

连接到 Blazor.start

可以在通过调用 Blazor.start 函数初始化 Blazor 时调用我们的 JavaScript。

首先,编辑 /Pages/_Host.cshtml 并更改引用 Blazor 脚本的 <script> 标记,并添加一个名为 autostart 且值为 false 的新属性。

<script src="_framework/blazor.server.js" autostart="false"></script>

接下来,我们需要更改我们的 JavaScript 以便它调用 Blazor.start - 这将返回一个 Promise<void>,一旦 Blazor 初始化,我们就可以使用它来执行我们自己的代码。

Blazor.start({}).then(async function () {const settings = await DotNet.invokeMethodAsync("CallingStaticDotNetMethods", "GetSettings");alert('API key: ' + settings.someApiKey);});

这种方法的问题是您只能使用一次。因此,如果我们在不同的脚本中有多个入口点,那么我们将不得不创建自己的挂钩点来缓存来自 Blazor.start 的结果并将其返回给任何调用脚本。

参考资料

[2]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/JavaScriptInterop/CallingStaticDotNetMethods

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

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

相关文章

分享 60 个神级 VS Code 插件

文章来源&#xff1a;juejin.cn/post/6994327298740600839 本文不做任何编辑器的比较&#xff0c;只是我本人日常使用 vscode 进行开发&#xff0c;并且比较喜欢折腾 vscode &#xff0c;会到处找这一些好玩的插件&#xff0c;于是越攒越多&#xff0c;今天给大家推荐一下我收…

PHP 基础篇 - PHP 中 DES 加解密详解

2019独角兽企业重金招聘Python工程师标准>>> 一、简介 DES 是对称性加密里面常见一种&#xff0c;全称为 Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法。密钥长度是64位(bit)&#xff0c;超过位数密钥被忽略。所谓对…

PerfView专题 (第一篇): 如何寻找热点函数

一&#xff1a;背景 准备开个系列来聊一下 PerfView 这款工具&#xff0c;熟悉我的朋友都知道我喜欢用 WinDbg&#xff0c;这东西虽然很牛&#xff0c;但也不是万能的&#xff0c;也有一些场景他解决不了或者很难解决&#xff0c;这时候借助一些其他的工具来辅助&#xff0c;是…

Centos7设置IP为固定值

1.进入到系统的IP地址保存文件所在目录 [rootlocalhost ~]# cd /etc/sysconfig/network-scripts 2.修改保存IP信息的文件 [rootlocalhost ~]# vim ifcfg-eth0 &#xff08;你机器上的名字有可能不是这个&#xff0c;但是是以ifcfg-eth开头的文件&#xff09; 保存后退出 3.重启…

为 EditorConfig 文件开启错误编译失败

前言上次&#xff0c;我们介绍了 EditorConfig 文件可以自定义代码样式规则。但是&#xff0c;当我们想设置代码样式严重性&#xff0c;比如不允许编译成功时&#xff0c;又踩了不少坑。修改无效想把 var 首选项&#xff0c;从“首选"var" 仅重构”&#xff0c;改成“…

【.NET特供-第三季】ASP.NET MVC系列:传统WebForm站点和MVC站点执行机制对照

本文以图形化的方式&#xff0c;从‘执行机制’方面对照传统WebForm站点和MVC站点。请參看下面图形&#xff1a; 一、执行机制 当我们訪问一个站点的时候&#xff0c;浏览器和server都是做了哪些动作呢&#xff1f; &#xff08;本文仅仅是提供一个简单的执行过程&#xff0c;有…

投阿里被拒,说跳槽太频繁!三年两个工作,问题真的那么大吗?

什么样的跳槽频率才不算频繁&#xff1f;一位网友发问&#xff1a;投阿里被拒&#xff0c;理由是跳槽太频繁&#xff0c;不合适。三年两个工作&#xff0c;问题真的那么大吗&#xff1f;网友说&#xff0c;阿里对稳定性要求非常高&#xff0c;三年两跳和五年三跳都是红线&#…

为什么信息化 ≠ 数字化?终于有人讲明白了

作者&#xff1a;石秀峰 来源&#xff1a;谈数据&#xff08;ID&#xff1a;learning-bigdata&#xff09; 近期&#xff0c;我一做数字化咨询的朋友&#xff08;化名老王&#xff09;遇到了一个头痛的问题&#xff1a;话说老王的团队近期接了一个大单——一大型制造业的数字化…

JAVA代码—算法基础:数独问题(Sodoku Puzzles)

JAVA代码—算法基础&#xff1a;数独问题&#xff08;Sodoku Puzzles&#xff09; 数独问题&#xff08;Sodoku Puzzles&#xff09; 数独游戏&#xff08;日语&#xff1a;数独 すうどく&#xff09;是一种源自18世纪末的瑞士的游戏&#xff0c;后在美国发展、并在日本得以发扬…

Linux系统恢复

实验目的&#xff1a;熟悉了前面的启动流程&#xff0c;系统的一个大致的启动流程是怎样的&#xff0c;而其中牵扯到了些许文件&#xff0c;这些文件在系统启动时用于衔接各个步骤&#xff0c;如果这些文件损坏或缺失&#xff0c;系统将不能正常启动&#xff0c;这次写的内容就…

PerfView专题 (第二篇):如何寻找 C# 中的 Heap堆内存泄漏

一&#xff1a;背景 上一篇我们聊到了如何去找 热点函数&#xff0c;这一篇我们来看下当你的程序出现了 非托管内存泄漏 时如何去寻找可疑的代码源头&#xff0c;其实思路很简单&#xff0c;就是在 HeapAlloc 或者 VirtualAlloc 时做 Hook 拦截&#xff0c;记录它的调用栈以及分…

关于 extern C的说明

在用C的项目源码中&#xff0c;经常会不可避免的会看到下面的代码 1 #ifdef __cplusplus 2 extern "C" { 3 #endif 4 5 /*...*/ 6 7 #ifdef __cplusplus 8 } 9 #endif 它到底有什么用呢&#xff0c;你知道吗&#xff1f;而且这样的问题经常会出现在面试or笔试…

Nginx 面试 40 问

Nginx是一款轻量级的Web服务器、反向代理服务器&#xff0c;由于它的内存占用少&#xff0c;启动极快&#xff0c;高并发能力强&#xff0c;在互联网项目中广泛应用。 那么关于 Nginx 的核心技术点有哪些呢&#xff1f; 什么是Nginx&#xff1f; Nginx是一个 轻量级/高性能的…

用Cocos2dx开发棋牌游戏的观点解析

众所周知&#xff0c;目前棋牌游戏特别的火。很多游戏公司都想在这一块赚钱&#xff0c;可是却不知用什么软件比较好的去开发棋牌游戏&#xff0c;对此&#xff0c;我列出了两款比较靠谱的软件去开发棋牌游戏&#xff0c;希望对大家有帮助&#xff01; 第一款软件是cocos2dx,它…

我把《系统设计》系列整理成了 PDF

大家好&#xff0c;我是等天黑。相信很多朋友应该注意到了&#xff0c;我最近发了很多系统设计的文章。是的&#xff0c;到目前为止&#xff0c;已经发了有 7 篇文章。这些内容主要翻译自 Alex Xu 的 《System Design Interview》&#xff0c;有卷一和卷二两本。System Design …

高性能IO模型浅析

服务器端编程经常需要构造高性能的IO模型&#xff0c;常见的IO模型有四种&#xff1a; &#xff08;1&#xff09;同步阻塞IO&#xff08;Blocking IO&#xff09;&#xff1a;即传统的IO模型。 &#xff08;2&#xff09;同步非阻塞IO&#xff08;Non-blocking IO&#xff09;…

PHP个人博客项目------切切歆语博客

2019独角兽企业重金招聘Python工程师标准>>> phpmysqlapache, ThinkPHP3.2框架开发 我的个人博客项目 适合新手练习 源码地址下载&#xff1a;https://github.com/DickyQie/php-myblog 转载于:https://my.oschina.net/zhangqie/blog/1785867

IOS_SearchBar搜索栏及关键字高亮

搜索框的效果演示: 这个就是所谓的搜索框了,那么接下来我们看看如何使用代码来实现这个功能. 我所使用的数据是英雄联盟的英雄名单,是一个JSON数据的txt文件, JSON数据的处理代码如下所示: ?123456//获取文件的路径pathNSString *path [[NSBundle mainBundle] pathForResourc…

Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

工厂模式&#xff1a; 工厂模式可以分为三类&#xff1a; 1&#xff09;简单工厂模式&#xff08;Simple Factory&#xff09; 2&#xff09;工厂方法模式&#xff08;Factory Method&#xff09; 3&#xff09;抽象工厂模式&#xff08;Abstract Factory&#xff09; 简单工…

今天很多 CTO 都是被干掉的,因为他没有成就业务

作者&#xff5c;乔新亮 编辑&#xff5c;邓艳琴 我可以丝毫不开玩笑地说&#xff0c;今天&#xff0c;很多传统企业里的研发都只是“工人”&#xff0c;哪怕是 CTO&#xff0c;充其量也只是“高级工人”&#xff0c;如果不转换思维去成就业务&#xff0c;就只能停留在工人级…