首页 > 解决方案 > 如何将 SignalR 有效负载映射到 TypeScript 类?

问题描述

我们使用 signalR 从服务器请求使用的 cpu 和 ram:

// create connection
let hubConnection = new signalR.HubConnectionBuilder().withUrl("/MyUrl").build();

// response message
hubConnection.on("ReceiveMessage", (pMessage: string) => {

  // convert to json
  let lObj = JSON.parse(pMessage);
  let lServerResources = new ServerResources(lObj.cpu, lObj.ram);

  // do something with this result [...]
});

这是简单的 ServerResources 类:

// simple data class
export class ServerResources
{
  constructor(public cpu: string, public ram: string)
  {  }
}

问题:参数pMessage包含一个 json 字符串作为值:'{"cpu":"72%","ram":"2540MB"}'我们需要将其转换为 javascript 对象,然后映射到ServerResources类。我们要保存这两个步骤。我们想ServerResources直接得到一个-object。

我们尝试了以下方法。但它仍然是一个字符串:

hubConnection.on("ReceiveMessage", (pMessage: ServerResources) => {
    // [...]
}

无论如何,Angular 通过泛型映射 http 请求的有效负载:

this.http.get<ServerResources>("MyUrl").pipe( [...] );

问题:我们如何将 singnalR 有效负载自动映射到 typescript 类?

标签: angulartypescriptsignalrasp.net-core-2.1

解决方案


我写了一个通用函数来从 JSON 中水合 TypeScript 类

function hydrate<T>(constr: { new(...args: any[]): T }, data: string, strictMode: boolean = true, ...args: any[]): T {
    const obj = JSON.parse(data);
    const instance = new constr(...args);

    for (let key in obj) {
        if (!strictMode || instance.hasOwnProperty(key)) {
            instance[key] = obj[key];
        }
    }

    return instance;
}

这是在您的特定情况下使用它的示例(我在类中添加了一个方法以进行说明):

class ServerResources {
  constructor(public cpu: string, public ram: string)
  { }

  getSomething() {
    alert(this.cpu + ' ' + this.ram)
  }
}

const data = `{ "cpu": "SUPER-8", "ram": "FAST-SHEEP"}`;

const example = hydrate(ServerResources, data, false);

example.getSomething();

推荐阅读