将 JSON 字符串反序列化为 TS 对象

DeSerializing JSON string into a TS object

我正在为一个看似非常简单的程序而苦恼。

在"geolocate.ts"函数"setData"中,模型索引?当从 "model.flightplan" 或 "model.config" 引用时,"flightplan" 和 "config" 被 Chrome 调试器显示为 "undefined"。即使在调试器中展开,"model" 对象本身似乎也没有问题。

如有任何想法或建议,我们将不胜感激;)

geolocate.d.ts

export class FmsFlightPlan {
    public status: string[];
    ...
}

export class Config {
    public airportIcon: IconSettings;
    ...
}

export class InitModel {
    public config: Config;
    public flightplan: FmsFlightPlan;
}

geolocate.ts

import * as passedData from "./geoLocate.d";

let config: passedData.Config;
let flightPlan: passedData.FmsFlightPlan;

export function setModel( json: string): void {
    console.log( json);  // '{"Config": { "AirportIcon": {...} ...}, {"Flightplan": {"Status": [], ... } ...}'  --- As expected (JSONlint OK)

    const model: passedData.InitModel = JSON.parse( json);
    console.log(model);  // Chrome console: {Config: {…}, Flightplan: {…}}

    flightPlan = model.flightplan; // flightPlan and config are assigned "undefined"
    config = model.config;     // "model" looks OK and Intellisense works.

    flightplanDraw();
} 

TSC 生成javascript

function setModel(o) {
    console.log(o);
    var e = JSON.parse(o);
    console.log(e), flightPlan = e.flightplan, config = e.config, flightplanDraw()
}

.NET核心视图Javascript

function gmapsReady() {

    initMap();
    $.getJSON("/Home/GetConfig",
        null,
        function(data) {
            setModel(data);
        });
 }  

.NET MVC 控制器

public JsonResult GetConfig()
{
    // Load fplan and config objects
    ...
    ... 

    InitModel initModel = new InitModel
    {
        Flightplan = fplan,
        Config = _config
    };

    string json = JsonConvert.SerializeObject(initModel);
    return new JsonResult(json);
}

第一个问题似乎是您正在访问 flightplanconfig 等字段,而在 JSON 中它们是 FlightPlanConfig .这就是为什么你得到 undefineds.

之后的一个稍微大一点的问题,如果你打算在你的 classes 中添加方法,这将主要困扰你,是由 JSON.parse 产生的东西是一个简单的 JavaScript 对象,而 ConfigFlightPlan 等是 class,它们的实例属于那个 class。所以如果你有这样的事情:

let x = new Config();
x.airportIcon = 'foo';
console.log(x.constructor); // Prints 'Config'
let y = JSON.parse('{"airportIcon": "foo"}');
console.log(y.constructor); // Prints 'Object something or other'

所以两者在结构上是等价的,但在功能上不会等价。即使进行 TS 转换,您也无法像在 x 上那样在 y 上调用函数。如果这些是简单的 DTO,那也没关系。但如果没有,您需要明确说明这一点,并执行另一个步骤,将 JS 对象转换为您的应用程序对象。


无耻插件:我写了 raynor 来自动化这个确切的过程——在 DTO 类型和更有用的 JavaScript class.

之间进行转换

您还可以在 .net 端配置 JSON 序列化程序,将字段名称从 PascalCase 转换为 'camelCase`。