2017-08-09 1 views
1

Ich kämpfe über was sollte ein sehr einfaches Verfahren sein.DeSerializing JSON-Zeichenfolge in ein TS-Objekt

In der "geolocate.ts" -Funktion "setData", die Modellindizes? "Flugplan" und "Config" werden vom Chrome-Debugger als "nicht definiert" angezeigt, wenn sie von "model.flightplan" oder "model.config" referenziert werden. Das "Modell" -Objekt selbst scheint in Ordnung zu sein, selbst wenn es im Debugger expandiert ist.

Irgendwelche Gedanken oder Zeiger würden sehr geschätzt;)

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 erzeugt Javascript

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

.NET Core-Ansicht Javascript

function gmapsReady() { 

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

.NET MVC-Controller

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); 
} 
+0

versuchen Sie 'flightPlan = model.Flightplan' und stellen Sie sicher, dass der Name genau der gleiche ist einschließlich der Kappen. JSON in JS ist case sensitive (; –

+0

@ Helder De Baere: Vielen Dank für den Vorschlag, aber die Verwendung von model.Flightplan führt zu einem TSC-Kompilierungsfehler (wie zu erwarten) – JcMaltaDev

+1

Dann würde ich vorschlagen, "Flugplan" in Ihrem umbenennen InitModel zu 'Flightplan' und auch für Config.Wenn das nicht funktioniert, ist wahrscheinlich etwas mit der Analyse des JSON zu Ihrem Modell nicht in Ordnung. –

Antwort

1

Ein erstes Problem scheint zu sein, dass Sie Felder wie flightplan und config zugreifen, während in der JSON sind sie FlightPlan und Config. Deshalb bekommst du undefined s.

Ein etwas größeres Problem danach, die Sie meistens beißen, wenn Sie über das Hinzufügen von Methoden zu Klassen planen ist, dass das Ding produziert von JSON.parse ist ein einfaches JavaScript-Objekt, während Config, FlightPlan etc sind Klassen und Instanzen sie würden zu dieser Klasse gehören. Also, wenn Sie so etwas wie dieses hatte:

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' 

So sind die beiden strukturell gleichwertig, aber nicht funktionell gleichwertig sein. Selbst wenn Sie einen TS-Cast durchführen, können Sie keine Funktion auf y aufrufen, wie Sie es unter x tun würden. Wenn das einfache DTOs sind, dann ist das OK. Wenn nicht, müssen Sie dies explizit angeben und einen weiteren Schritt des Übersetzens vom JS-Objekt in Ihre Anwendung durchführen.


Shameless Stecker: Ich raynor schrieb genau dieses Verfahren zu automatisieren - von zwischen einem DTO-Typ und einer nützlichen JavaScript-Klasse zu übersetzen.


Sie können auch die JSON Serializer auf .net Seite so konfigurieren, dass Feldnamen aus PascalCase zu ‚camelCase` konvertieren.

+0

Danke - Ich werde die Namensprobleme auf Konsistenz untersuchen. Ich habe Namen über C#/TS/JS "prowlamatic" gefunden, da sie alle unterschiedliche Namensstandards für öffentlich/privat usw. haben! - es sendet meine Resharper und Lints verrückt !!! Ich benutze "TypeScriptSyntaxPaste", um D.ts-Dateien aus C# -Klassen zu erstellen, aber ich werde Raynor immer einen Blick geben. – JcMaltaDev

+0

Danke. Es war tatsächlich ein Fallproblem während der JSON-Serialisierung. Die Verwendung von CamelCasePropertyNamesContractResolver "löste" das Problem. Diese Objekte sind (gerade) einfache DTOs, aber ich habe für zukünftige Referenz ein Lesezeichen mit dem Radynor erstellt. Danke noch einmal. – JcMaltaDev

Verwandte Themen