Blazor wasm JS 互操作序列化

huangapple go评论55阅读模式
英文:

Blazor wasm JS Interop serialization

问题

我正在尝试将JS中的任何类型序列化为C#中的对象,但似乎没有任何效果。

我在我的EventAction<T>上有一个属性:

public DotNetObjectReference&lt;EventAction&lt;T&gt;&gt; DotNetObjRef { get; }

这个属性用于从JS代码中调用事件。一个示例是:

function onCellValueChanged(data, handler) {
    var mapped = {
        columnName: data.column.colId, // string
        rowIndex: data.rowIndex, // number
        oldValue: data.oldValue, // any
        newValue: data.newValue, // any
    };

    handler.dotNetObjRef.invokeMethodAsync('Invoke', mapped);
}

调用方法部分运行正常。但是序列化只部分完成。在上面的示例中,我有一个名为CellValueChangedArgs的类:

public class CellValueChangedArgs
{
    public string ColumnName { get; set; } = string.Empty;
    public int RowIndex { get; set; }
    public object? OldValue { get; set; }
    public object? NewValue { get; set; }
}

当调用此类的实例时,string和int属性被正确序列化,但是object?类型不是(它们包含JsonElement实例而不是实际值,可以是string、number、datetime等)。

如果我将NewValue和OldValue的类型更改为string,然后它可以工作。

有人知道为什么吗?这是否是将其序列化为字符串的正确方式,然后手动处理转换的方法?

英文:

I am trying to serialize any type in JS to object in C#, and nothing seems to work.

I have a property on my EventAction<T>

public DotNetObjectReference&lt;EventAction&lt;T&gt;&gt; DotNetObjRef { get; }

which is used to call an event from JS code. An example would be:

function onCellValueChanged(data, handler) {

    var mapped = {
        columnName: data.column.colId // string
        rowIndex: data.rowIndex, // number
        oldValue: data.oldValue, // any
        newValue: data.newValue, // any
    };

    handler.dotNetObjRef.invokeMethodAsync(&#39;Invoke&#39;, mapped);
}

The calling method part works fine. The serialization is only partially done. In above example, I have a class called

public class CellValueChangedArgs
{
    public string ColumnName { get; set; } = string.Empty;
    public int RowIndex { get; set; }
    public object? OldValue { get; set; }
    public object? NewValue { get; set; }
}

and when instance of this class is called, string and int properties are serialized properly, object? types are not (they contain JsonElement instance instead of actual value, which can be string, number, datetime...).

If I change NewValue and OldValue types to string, then it works.

Anyone has any idea why? Is it a proper way to serialize it to string, and then dial with the conversion manually?

答案1

得分: 1

请问自己这个问题,当你不知道要反序列化成什么时,该如何操作?

当属性的类型是 object 时,序列化时可以知道类型并执行操作。但反序列化则完全不同,除非你能定义类型,否则不可能进行反序列化。

我建议通过使用泛型或在 JavaScript 中传递类型来添加你期望的类型。

也许可以使用这个示例:

public class CellValueChangedArgs
{
    public string ColumnName { get; set; } = string.Empty;
    public int RowIndex { get; set; }
    public string? OldValue { get; set; }
    public string? NewValue { get; set; }
}

然后使用 ReflectionTryParse 方法将你的字符串转换为期望的值类型。

英文:

Ask yourself this, how do you deserialize to something when you do not know what it is?

When the property with type object is serialized, the type is known and can be done. But deserialization is a completely different story and is impossible unless you can define the type.

I suggest adding your expected type by either using generics or passing the type to and from JavaScript.

Perhaps use this

public class CellValueChangedArgs
{
    public string ColumnName { get; set; } = string.Empty;
    public int RowIndex { get; set; }
    public string? OldValue { get; set; }
    public string? NewValue { get; set; }
}

And cast your strings to your expected value type using Reflection and TryParse methods.

huangapple
  • 本文由 发表于 2023年6月1日 17:49:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定