BlazorServer中C#与JavaScript的相互调用
BlazorServer中C#与JavaScript的相互调用
前言:
虽然BlazorServer中推荐使用C#在razor页面中的替代JavaScript来完成逻辑的编写,但当需要使用第三方的javascript文件/组件里的内容时,则难免要在C#中调用其方法或对象。反之当你的(用到第三方组件的)Javascript代码想要和后台交互时,则需要调用C#的代码。好在BlazorServer中这两种通信都是支持的。下面将介绍其具体的实现方式。
🌮一.C#调用JavaScript方法
Blazor提供了IJSRuntime组件来提供与JavaScript的交互。
🍎 BlazorServer启动时就已经创建了IJSRuntime的实例,所以你可以直接使用构造方法注入
public class CustomService
{private readonly IJSRuntime _runtime;public CustomService(IJSRuntime runtime){_runtime = runtime;}
}
🍌在razor页面(组件)中也是直接获取即可
page "/mytest"<!--直接使用@inject标签获取即可-->
@inject IJSRuntime runtime <h3>MyTest</h3>
1.调取公用函数
page "/mytest"<!--直接使用@inject标签获取即可-->
@inject IJSRuntime runtime <h3>MyTest</h3><button type="button" @onclick="DoNothing">点击</button>@code {public void DoNothing(){await runtime.InvokeVoidAsync("alert",new object[1] { "FUCKYOU" }); //无返回值//runtime.InvokeAsync<>(); 有返回值}
}
测试结果:

2.调取外部JavaScript函数
上面的只单独调用公共函数的时候不多,大多数时候需要从别的地方获取。调用方法如下
现有一自定义js文件如下(TestScript.js)
function WhatTheHell() {alert("WTF");
}function WhatTheHell_2() {alert("这次有返回值");return 123
}function WhatTheHell_3(param) {alert("有返回值及参数");console.log(JSON.stringify(param));return 10086
}
先将其放到BlazorServer的js文件指定目录下(wwwroot/js/)

再在_Host.cshtml中引入该js文件

在razor页面中使用
@page "/mytest"@inject IJSRuntime runtime <h3>MyTest</h3><button type="button" @onclick="MethodOne">方法一(无返回值和参数)</button> <br/>
<button type="button" @onclick="MethodTwo">方法二(无返回值)</button> <br/>
<button type="button" @onclick="MethodThree">方法三(返回值和参数)</button> <br/>@code {public async void MethodOne(){await runtime.InvokeVoidAsync("WhatTheHell",null);}public async void MethodTwo(){var num = await runtime.InvokeAsync<int>("WhatTheHell_2",null);Console.WriteLine("获取js的返回值为" + num);}public async void MethodThree(){var num = await runtime.InvokeAsync<int>("WhatTheHell_3", new object[1] { "尼哥" });Console.WriteLine("获取js的返回值为" + num);}}
测试结果为:

当JS的返回值为复杂对象时,则推荐使用IJSObjectReference来获取,具体可以参考
IJSObjectReference 接口 (Microsoft.JSInterop) | Microsoft Learn
🍕 二.JavaScript调用C#方法
在JavaScript中调用C#的方法则比较复杂,需要考虑到静态/动态区分的问题
🌀1.静态方法的调用
DotNet.invokeMethodAsync('AssemblyName', 'Namespace.ClassName', 'MethodName', arg1, arg2);
这将调用指定程序集(AssemblyName)、命名空间(Namespace[可以省略])和类名(ClassName)中的静态方法(MethodName),并传递arg1和arg2作为参数。
例:
@page "/jstest"@inject IJSRuntime runtime<h3>Jsusecsharp</h3><span style="font-size:36px">到达世界最高城 @Title</span><button type="button" @onclick="Change">前往朝圣</button>@code {public static string Title = "沈阳!"; public async void Change(){await runtime.InvokeVoidAsync("use_csharp",null);}[JSInvokable]public static void ChangeTheTitle(){Title = "理塘";}
}
js文件
async function use_csharp() {await DotNet.invokeMethodAsync('BlazorApp2','ChangeTheTitle', null);
}
测试结果:

✈️ 2…动态方法的调用
下面是微软文档的内容
若要从 JavaScript (JS) 调用实例 .NET 方法,请执行以下操作:
-
通过将实例包装在 DotNetObjectReference 中并对其调用 Create,将 .NET 实例通过引用传递给 JS。
-
使用传递的 DotNetObjectReference 中的
invokeMethodAsync(推荐)或invokeMethod(仅限 Blazor WebAssembly)从 JS 调用 .NET 实例方法。 传入实例 .NET 方法的标识符以及任意自变量。 在从 JS 调用其他 .NET 方法时,也可以将 .NET 实例作为参数传递。如下示例中:
dotNetHelper为 DotNetObjectReference。{.NET METHOD ID}占位符是 .NET 方法标识符。{ARGUMENTS}占位符是要传递给该方法的以逗号分隔的可选参数,其中每个参数都必须是可执行 JSON 序列化的。
⛵️ 总结:
动态方法的调用需要传递实例(使用DotNetObjectReference对象),需要在方法中设置实例参数,再由实例进行invoke操作。
例:
@page "/jstest"
@using BlazorApp2.Utils@inject IJSRuntime runtime<h3>Jsusecsharp</h3><span style="font-size:36px">到达世界最高城 @Title</span><button type="button" @onclick="Change">前往朝圣</button>@code {public static string Title = "沈阳!";//用于传递给JS的实例private DotNetObjectReference<Jsusecsharp> objref;protected override void OnInitialized(){objref = DotNetObjectReference.Create(this);}public async void Change(){//将实例作为参数传给调用的JSawait runtime.InvokeVoidAsync("use_csharp_dy",objref);}/// <summary>/// 静态方法/// </summary>[JSInvokable]public static void ChangeTheTitle(){Title = "理塘";}[JSInvokable("ChangeTheTitle_2")]public void ChangeTheTitle_2(){Title = "通辽";}}
JS:
async function use_csharp_dy(instance) {//instance 即为razor中的objref,由其进行调用await instance.invokeMethodAsync('ChangeTheTitle_2', null);}
参数结果:

未完。。。。。
相关文章:
BlazorServer中C#与JavaScript的相互调用
BlazorServer中C#与JavaScript的相互调用 前言: 虽然BlazorServer中推荐使用C#在razor页面中的替代JavaScript来完成逻辑的编写,但当需要使用第三方的javascript文件/组件里的内容时,则难免要在C#中调用其方法或对象。反之当你的(用到第…...
深入理解 MD5 消息摘要算法和在密码存储中的应用及安全隐患
MD5 算法相信很多开发人员都听说过, 一个最常见的使用到它的地方就是密码的存储. 当然, 很多人会说, 这个算法已经不太安全了, 确实如果你想更安全的保存密码, 则应该考虑其它更安全的算法, 不过这不属于此次讨论的主题. 什么是 MD5 MD5 是一种算法, MD5 中的 MD 代表 Message…...
python网络爬虫指南二:多线程网络爬虫、动态内容爬取(待续)
文章目录 一、多线程网络爬虫1.1 线程的基础内容、GIL1.2 创建线程的两种方式1.3 threading.Thread类1.4 线程常用方法和锁机制1.5 生产者-消费者模式1.5.1 生产者-消费者模式简介1.5.2 Condition 类协调线程 1.6 线程中的安全队列1.6 多线程爬取王者荣耀壁纸1.6.1 网页分析1.6…...
华为AirEgine9700S AC配置示例
Vlan97为管理Vlan <AirEgine9700S>dis cu Software Version V200R021C00SPC100 #sysname AirEgine9700S #http timeout 60http secure-server ssl-policy default_policyhttp secure-server server-source -i allhttp server enable #set np rss hash-mode 5-tuple # md…...
VUE3基础
一、vue-router v4.x 介绍 | Vue Router 1、安装 yarn add vue-routernext next代表最新的版本 2、路由配置 在src目录下,新建router/index.ts,具体配置如下 import {RouteRecordRaw,createRouter,createWebHashHistory} from vue-router const r…...
Qt应用开发(基础篇)——日历 QCalendarWidget
一、前言 QCalendarWidget类继承于QWidget,是Qt设计用来让用户更直观的选择日期的窗口部件。 时间微调输入框 QCalendarWidget根据年份和月份初始化,程序员也通过提供公共函数去改变他们,默认日期为当前的系统时间,用户通过鼠标和…...
Python学习笔记:正则表达式、逻辑运算符、lamda、二叉树遍历规则、类的判断
1.正则表达式如何写? 序号实例说明1.匹配任何字符(除换行符以外)2\d等效于[0-9],匹配数字3\D等效于[^0-9],匹配非数字4\s等效于[\t\r\n\f],匹配空格字符5\S等效于[^\t\r\n\f],匹配非空格字符6\w等效于[A-Za-z0-9]&…...
【滑动窗口】leetcode1004:最大连续1的个数
一.题目描述 最大连续1的个数 这道题要我们找最大连续1的个数,看到“连续”二字,我们要想到滑动窗口的方法。滑动窗口的研究对象是一个连续的区间,这个区间需要满足某个条件。那么本题要找的是怎样的区间呢?是一个通过翻转0后得到…...
力扣:73. 矩阵置零(Python3)
题目: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 来源:力扣(LeetCode) 链接:力扣(LeetCode)官网 - 全球极客挚…...
VB|基础语法 变量定义 函数定义 循环语句 IF判断语句等
文章目录 变量定义函数定义控制台输入输出switch case语句IF语句FOR循环语句不等于逻辑运算符 变量定义 int Dim 变量名 As Int32 0 string Dim 变量名 As String "" bool Dim 变量名 As Boolean False 枚举 Dim 变量名 As 枚举名 数组 Dim array(256) As String…...
Github 博客搭建
Github 博客搭建 准备工作 准备一个 github 账号;建立 github 仓库,仓库名为 username.github.io,同时设置仓库为 public;clone 仓库,写入一个 index.html 文件,推送到仓库(许多网上的教程会有…...
模型预测笔记(三):通过交叉验证网格搜索机器学习的最优参数
文章目录 网络搜索介绍步骤参数代码实现 网络搜索 介绍 网格搜索(Grid Search)是一种超参数优化方法,用于选择最佳的模型超参数组合。在机器学习中,超参数是在训练模型之前设置的参数,无法通过模型学习得到。网格搜索…...
创建型模式-建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部…...
Rust常用加密算法
哈希运算(以Sha256为例) main.rs: use crypto::digest::Digest;use crypto::sha2::Sha256;fn main() { let input "dashen"; let mut sha Sha256::new(); sha.input_str(input); println!("{}", sha.result_str());} Cargo.toml: [package]n…...
[管理与领导-55]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -2- 自律与自身作则,管理者管好自己时间的五步法
前言: 管理好自己的时间,不仅仅是理念,也是方法和流程。 步骤1:理清各种待办事项 当提到工作事项时,这通常指的是要完成或处理的工作任务或事务。这些事项可以包括以下内容: 任务分配:根据工作…...
电子商务员考试题库及答案(中级)--判断题
电子商务员题库 一、判断题 1.EDI就是按照商定的协议,将商业文件分类,并通过计算机网络,在贸易伙伴的计算机网络系统之间进行数据交换和自动处理。〔〕 2.相互通信的EDI的用户必须使用相同类型的计算机。〔 〕 3.EDI采用共同…...
(WAF)Web应用程序防火墙介绍
(WAF)Web应用程序防火墙介绍 1. WAF概述 Web应用程序防火墙(WAF)是一种关键的网络安全解决方案,用于保护Web应用程序免受各种网络攻击和威胁。随着互联网的不断发展,Web应用程序变得越来越复杂&#x…...
SpringMVC拦截器常见应用场景
在Spring MVC中,拦截器是通过实现HandlerInterceptor接口来定义的。该接口包含了三个方法: preHandle:在请求到达处理器之前执行,可以进行一些预处理操作。如果返回false,则请求将被拦截,不再继续执行后续的…...
爬虫:绕过5秒盾Cloudflare和DDoS-GUARD
本文章仅供技术研究参考,勿做它用! 5秒盾的特点 <title>Just a moment...</title> 返回的页面中不是目标数据,而是包含上面的代码:Just a moment... 或者第一次打开网页的时候: 这几个特征就是被Cloud…...
数据仓库环境下的超市进销存系统结构
传统的进销存系统建立的以单一数据库为中心的数据组织模式,已经无 法满足决策分析对数据库系统的要求,而数据仓库技术的出现和发展,为上述问题 的解决提供了强有力的工具和手段。数据仓库是一种对多个分布式的、异构的数据 库提供统一查询…...
RT-Thread Nano 3.0.3移植STM32F103后,第一个实战:用FinSH组件实现串口命令行调试
RT-Thread Nano 3.0.3移植STM32F103实战:FinSH组件实现串口命令行调试 当你成功将RT-Thread Nano移植到STM32F103开发板后,第一个令人兴奋的里程碑就是让系统真正"活"起来——而FinSH组件正是实现这一目标的完美起点。这个内置的命令行交互工具…...
告别卡顿!用UniApp的RenderJS为你的APP手势和动画性能提速(实战解析)
告别卡顿!用UniApp的RenderJS为你的APP手势和动画性能提速(实战解析) 在移动应用开发中,流畅的用户体验往往决定了产品的成败。当你在UniApp框架下开发APP时,是否遇到过这样的场景:地图拖拽时出现明显延迟&…...
8255A工作方式0实战:手把手教你用汇编语言驱动八路抢答器LED与数码管
8255A工作方式0实战:从零构建八路抢答器驱动框架 记得第一次在实验室见到8255A芯片时,那块黑色的DIP封装器件看起来平平无奇,直到它让八颗LED随着我的汇编指令跳起"灯光芭蕾"。本文将带你深入这个经典可编程并行接口芯片的实战应用…...
你的爬虫被识别了?可能是浏览器指纹惹的祸!教你用Playwright伪装Canvas/WebGL指纹
浏览器指纹识别:爬虫工程师的终极伪装术 当你的爬虫程序已经完美解决了User-Agent轮换、IP代理池和请求频率控制,却依然被目标网站精准识别并封禁时,你可能正面临着现代反爬技术的终极挑战——浏览器指纹识别。这种技术不依赖于传统的请求特征…...
vLLM-v0.17.1行业落地:法律科技公司合同关键条款抽取与风险提示服务
vLLM-v0.17.1行业落地:法律科技公司合同关键条款抽取与风险提示服务 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库,最初由加州大学伯克利分校的天空计算实验室开发,现已发展成为社区驱动的开源项目。这个框架…...
解锁智能导航核心:从基础到进阶的路径规划实践指南
解锁智能导航核心:从基础到进阶的路径规划实践指南 【免费下载链接】PathPlanning Common used path planning algorithms with animations. 项目地址: https://gitcode.com/gh_mirrors/pa/PathPlanning 路径规划算法是机器人导航、自动驾驶和游戏AI等领域的…...
为什么流水线ADC能用Dither,而SAR ADC效果差?深入解析两种架构下的Dither技术差异与改进方案
流水线ADC与SAR ADC中Dither技术的差异化设计与工程实践 在高速高精度数据采集系统中,量化噪声的非线性特性始终是困扰设计者的核心难题。当我们用频谱分析仪观察一个理想正弦波经过ADC转换后的输出时,那些突兀的谐波分量往往源自量化过程的非线性失真。…...
OpenClaw成本优化方案:ollama GLM-4-7-Flash替代OpenAI API实测
OpenClaw成本优化方案:ollama GLM-4-7-Flash替代OpenAI API实测 1. 为什么需要寻找OpenAI API的替代方案 去年我开始在个人项目中使用OpenClaw实现自动化办公流程时,很快被OpenAI API的token消耗速度震惊了。一个简单的"读取邮件附件-解析内容-生…...
Cartool实战:手把手教你完成静息态EEG微状态分析的组水平聚类与模板匹配
Cartool实战:静息态EEG微状态分析全流程解析与避坑指南 在认知神经科学研究中,静息态EEG微状态分析正成为探索大脑动态功能网络的重要工具。不同于传统频域分析,微状态分析通过捕捉毫秒级地形图变化,揭示大脑信息处理的离散状态转…...
CMake+vcpkg环境配置避坑指南:从命令行到GUI的完整流程
CMakevcpkg环境配置避坑指南:从命令行到GUI的完整流程 刚接触C/C开发的工程师们,往往会在环境配置阶段经历"从入门到放弃"的心路历程。面对复杂的依赖库管理、跨平台编译问题,以及各种晦涩的错误提示,不少开发者甚至还没…...
