Blazor JavaScript互操作 - 将对象从js转换为.NET

4
我正在使用Blazor JavaScript互操作(调用.NET的js),就像这样:
//js
dotNetObjRef.invokeMethodAsync("DotNetMethod", jsObject);
---------------------------------------------------------
//C#
[JSInvokable]
public void DotNetMethod(object jsObject)
{
    Console.WriteLine($"jsObject type is {jsObject.GetType()}");
}

在浏览器控制台中,我得到:

'jsObject type is SimpleJson.JsonObject'

现在我想将jsObject转换为具体的SimpleJson.JsonObject,例如:
[JSInvokable]
public void DotNetMethod(object jsObject)
{
    JsonObject jsObject = (JsonObject)jsObject; //error
}

但是我使用C#社区实现的SimpleJson(如https://github.com/facebook-csharp-sdk/simple-json)进行所有尝试时,都会失败并抱怨转换无效。

为了解决这个问题,我通过字符串来解决:

//js
dotNetObjRef.invokeMethodAsync("DotNetMethod", JSON.stringify(jsObject));
.
//C#
[JSInvokable]
public void DotNetMethod(string jsObjectJSON)
{
    JsonObject jsObject = SimpleJson.DeserializeObject<JsonObject>(jsObjectJSON);
}

有人知道是否可以直接使用已收到的jsObject,避免序列化/反序列化(且不使用反射)吗?


通常情况下,JSInterop确实需要您进行字符串序列化。事实上,您想将参数作为“JsonObject”与之交互似乎意味着这正是您试图做的。因此,我有点困惑,为什么您认为您的解决方法不完全正确? - Kirk Woll
Blazor提供JS互操作性,包括隐式转换CLI <=> JSON。如果我知道类型的类签名,我可以在两个世界之间传递实例,Blazor会自动转换它们。当我看到从js到C#的对象的类型是JsonObject时,我希望我可以依赖Blazor内置的功能,只需将其强制转换为JsonObject而不是手动序列化/反序列化它,但显然Blazor正在寻找一个强类型的目标。换句话说,如果我想要像JsonObject这样的弱类型表示,我必须明确说明。不过,这不是什么大问题。 - Franco Tiveron
1个回答

4

为什么不接收一个预定义的对象,而不是直接接收JSON?

let x = {
    "data": "test",
    "moreData": "another test"
}

dotnetHelper.invokeMethodAsync('selectionChanged', x);

然后

//C#
public class InteropHelper
{
    public event Action OnSelectionChanged;

    [JSInvokable]
    public void selectionChanged(TestItem data)
    {
        OnSelectionChanged?.Invoke();
    }

    class TestItem
    {
        public string data { get; set; }
        public string moreData { get; set; }
    }
}

Blazor会自动知道JSON中的哪些字段对应TestItem中的哪些字段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接