You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor项目中JavaScript函数返回Double值至C#时获取null的问题求助

Blazor项目中JavaScript函数返回Double值至C#时获取null的问题求助

我帮你分析下这个问题,核心原因是你JavaScript里的图片加载是异步操作,但原函数没正确处理异步返回,导致DetectSpeed在图片加载完成前就结束了,返回了undefined,所以Blazor那边拿到的是null,反序列化时就抛出了ArgumentNullException。

下面是具体的修复方案:

第一步:修改JavaScript函数,用Promise包裹异步逻辑

因为图片的onload是回调触发的异步操作,我们需要用Promise来封装这个过程,确保函数能等待图片加载完成后再返回计算好的速度值:

window.DetectSpeed = async () => {
  return new Promise((resolve) => {
    const userImageLink = "https://mobilesyrup.com/wp-content/uploads/2021/04/starlink-header-how-to-2048x1151.jpg";
    let time_start, end_time;
    const downloadSize = 898080;
    const downloadImgSrc = new Image();

    downloadImgSrc.onload = function () {
      end_time = new Date().getTime();
      // 计算速度的逻辑保持不变
      const timeDuration = (end_time - time_start) / 1000;
      const loadedBits = downloadSize * 8;
      const bps = (loadedBits / timeDuration).toFixed(2);
      const speedInKbps = (bps / 1024).toFixed(2);
      const speedInMbps = ((speedInKbps / 1024).toFixed(2)) / 100;
      
      console.log(speedInMbps);
      resolve(speedInMbps); // 将计算结果通过Promise返回
    };

    time_start = new Date().getTime();
    downloadImgSrc.src = userImageLink;
    console.log("time start: " + time_start);
  });
};

第二步:简化C# Blazor代码,直接获取Double值

Blazor的IJSRuntime可以自动处理JavaScript基本类型(比如number)到C#类型的转换,不需要手动序列化/反序列化,所以我们可以直接调用InvokeAsync<double>:

protected bool IsVisible { get; set; }
public List<string> VideoTags = new List<string>();

public void ToggleMenu() => IsVisible = !IsVisible;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(firstRender)
    {
        VideoTags = await videos.GetVideoTagsAsync();
        await service.UpdateCurrentUserAsync();
        
        // 直接获取Double类型结果,无需手动处理JSON
        double numm = await JsRuntime.InvokeAsync<double>("DetectSpeed");
        
        Console.WriteLine("Bytearrax: " + numm.ToString());
        Console.WriteLine("OnAfterRenderAsync was ended in Index.razor");
    }
}

为什么原来的代码会报错?

原JavaScript函数DetectSpeed里,displaySpeed是在图片加载完成后才执行的回调函数,但DetectSpeed本身在设置完图片src后就直接结束了,没有任何返回值(相当于返回undefined)。Blazor的IJSRuntime会把undefined转换为C#的null,所以你后续用JsonConvert.DeserializeObject<double>(json)时,就会因为传入了null而抛出参数为空的异常。

用Promise包裹后,函数会等待图片加载完成,把计算好的速度值通过resolve传递给Blazor,这样就能正确拿到有效的数值了。

备注:内容来源于stack exchange,提问作者libertarian1917

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:58:01