Is this c# to typescript translation correct?

Hi all,

ServiceStack: 5.0.2
Webstorm: 2017.3.2
ServiceStack IDEA: 1.0.12

Can anyone explain why, when I use the New > Typescript Reference tool in Webstorm, this c# dto:

public class Matter
{
    public long Id { get; set; }
    
    public long ClientId { get; set; }
    
    public string Code { get; set; }
    
    public string SearchCode { get; set; }
    
    public string StdCode { get; set; }

    public string Name { get; set; }

    public string ShortName { get; set; }
    
    public int? OwnerId { get; set; }
    
    public int? ManagerId { get; set; }
    
    public int? PartnerId { get; set; }
    
    public bool? IsOpen { get; set; }
    
    public string Stage { get; set; }
    
    public DateTime? AtStage { get; set; }
    
    public DateTime? LastActivity { get; set; }
    
    public string Notes { get; set; }
    
    public bool? IsConfidential { get; set; }
    
    public bool? IsMinor { get; set; }
    
    public DateTime? Created { get; set; }
    
    public int? CreatedByUserId { get; set; }

    public User CreatedByUser { get; set; }

    public DateTime Closed { get; set; }
    
    public int? ClosedByUserId { get; set; }

    public User ClosedByUser { get; set; }

    public int SystemId { get; set; }

    public System System { get; set; }

    public DateTime? Loaded { get; set; }
    
    public DateTime? Archived { get; set; }
    
    public List<int> MatterTypes { get; set; }

    public List<MatterType> MatterTypeList { get; set; }
    
    public List<MatterStage> MatterStages { get; set; }

    public List<MatterKeyDate> MatterKeyDates { get; set; }

    public List<string> MaskedProperties { get; set; }
}

is translated into this typescript class?

export class Matter
{
    id: number;
    clientId: number;
    code: string;
    searchCode: string;
    stdCode: string;
    name: string;
    shortName: string;
    ownerId: number;
    managerId: number;
    partnerId: number;
    isOpen: boolean;
    stage: string;
    atStage: string;
    lastActivity: string;
    notes: string;
    isConfidential: boolean;
    isMinor: boolean;
    created: string;
    createdByUserId: number;
    createdByUser: User;
    closed: string;
    closedByUserId: number;
    closedByUser: User;
    systemId: number;
    system: System;
    loaded: string;
    archived: string;
    matterTypes: number[];
    matterTypeList: MatterType[];
    matterStages: MatterStage[];
    matterKeyDates: MatterKeyDate[];
    maskedProperties: string[];
}

I was expecting the c# DateTimes to translate into Dates in typescript.

Any ideas?

On an aside: I’ve also found the Update ServiceStack Reference doesn’t work. It seems to alter the BaseUrl in the comments and subsequent updates fail because a types/typescript suffix is ultimately appended to the base url more than once…

The TypeScript classes represent the schema of the returned JSON which doesn’t have a Date Type, it’s defined as a string because that’s how it’s returned in JSON.

When you’re adding the reference are you using the BaseUrl?

Hey @mythz,

Yeah, makes sense and tbh I should have thought of that as I am always having to handle dates separately on my son responses.

It feels to me that SS does a lot of the heavy lifting for me in generating these types but stops just short of generating typescript references. It would be nice if, in the generated typescript, a method is created to convert to/from string to Date and some further classes that represent typescript versions of the c# classes rather than json versions.
Thoughts?
Or perhaps I’m missing something? (I’m no js or ts expert tbh)

On the second point:
My workflow is:

  1. Run the SS server and copy the api url (in my case: http://localhost:8088/api)
  2. In Webstorm, go New > Typescript Reference
  3. Paste the api url and enter the name of the file to be generated
  4. The json types are created

My header now begins:

/* Options:
Date: 2018-01-12 00:07:01
Version: 5.02
Tip: To override a DTO option, remove “//” prefix before updating
BaseUrl: http://localhost:8088/api/

  1. I click Update ServiceStack Reference
  2. It succeeds and…

My header now begins (note the change to the BaseUrl value):

/* Options:
Date: 2018-01-12 08:24:16
Version: 5.02
Tip: To override a DTO option, remove “//” prefix before updating
BaseUrl: http://localhost:8088/api/types/typescript

  1. Now all subsequent Update ServiceStack Reference requests fail with an error:

Error Updating Reference: http://localhost:8088/api/types/typescript//types/typescript

Seems a natural workflow to me. Am I doing something wrong?

The TypeScript only generates the Type representation of the JSON Schema, it can’t do more than that because JavaScript doesn’t have any Type Information of classes at runtime. Different ways to convert Dates are listed in this StackOverflow answer: https://stackoverflow.com/a/44268376/85785

E.g. from TypeScript you can do:

import { todate } from "@servicestack/client";
var date = todate(wcfDateString);

Can you provide details of your Server, e.g. ASP.NET / .NET Core / HttpListner + the config mapping you’re using for /api in both code and Web.config please.

OK, understood. Cheers

We’re using the HttpListener.
Our config is split over several files and has quite a lot of content. Is there anything specific that will help?

The configuration you’re using to specify /api path, i.e. are you setting both the Config.HandlerFactoryPath and calling Start("http://*:1234/api") ?

Ah, good shout!

We are using Config.HandlerFactoryPath with:

stackHost.SetConfig(new HostConfig
        {
            //EnableFeatures = Feature.All.Remove(disableFeatures),
            AppendUtf8CharsetOnContentTypes = new HashSet<string> { MimeTypes.Html },
            HandlerFactoryPath = "api",
            DebugMode = false
        });

And we’re also doing:

new AppHost(new InitialisationList(initialisers)).Init().Start("http://*:8088/");
        "RESTful Web API listening at http://localhost:8088 ".Print();
        Process.Start("http://localhost:8088/");

I assume we should just be doing one?

Can’t repro this, can you post the BaseUrl returned in the comments from: http://localhost:8088/api/types/typescript

yeah, happy to share with you but its a large project and I’d rather not post all that IP on the web. Is there a way I can share it privately?

I would just need an empty project with the configuration causing the issue, can you please post the BaseUrl returned in the comments from: http://localhost:8088/api/types/typescript

The BaseUrl returned in the comments is:

http://localhost:8088/api

types only reference

full reference

The issue was due to the plugin sending an empty // double-slash in the URL. Both ASP.NET and .NET Core seem to automatically strip empty double slashes so I’ve updated HttpListener hosts to do the same which fixes this issue.

This change is available from v5.0.3 that’s now available on MyGet.

I’ve also published a fix to the Intellij Plugin to prevent the // but it takes a couple of days for JetBrains to manually verify and approve the plugin.

Ah, great stuff!
Thanks.