1

How can I export a C# class (DTO) in the dtos.ts file generated with npm run typescript-ref http://localhost:5000 src/myproject without referencing in the request class?

Note: we have several C# DTO classes (MutationAddressChange, MutationCEOChange...) that we map to the domain class using automapper. So we want to use the C# DTO classes as well in Angular to populate the corresponding type (e.g.MutationAddressChangesCreateDTO) and send it to the web server. Therefore, in the CreateMutationRequest class, we accept an object instead of a specific class.

example DTO-Class:

public class MutationAddressChangesCreateDTO
{
    public string Street { get; set; }
    public string POBox { get; set; }
    public string Zipcode { get; set; }
}

ServiceStack Request-Class

public class CreateMutationRequest : IPost
{
    public object Mutation { get; set; }
}

Angular expected use:

{
    var mutationAddressChangesCreateDTO= new MutationAddressChangesCreateDTO();
    mutationAddressChangesCreateDTO.dateOfMutation = ...

    const request = new CreateMutationRequest ({
        mutation: mutationAddressChangesCreateDTO,
    });

    this.client.post(request)
    ...
}
Astrophage
  • 1,231
  • 1
  • 12
  • 38

1 Answers1

1

A limitation of Add ServiceStack Reference feature is that your DTOs cannot have any object or interface properties which creates a black hole in your Services contract that's impossible to generate a Typed API for.

I'd recommend against having any object or interface properties in your DTOs which other than being a source of runtime issues is also limited by security restrictions.

You could use an untyped data structure like a Dictionary<string,string> to store arbitrary values, you can some find other alternatives in this Customer Forums thread.

Although it's discouraged you could still have object properties in your ServiceStack Request DTOs, you just wont be able to generate a typed API for them but you should still be able to send them as an anonymous arg, e.g:

this.client.post(request, { mutation: dto });

Object properties are handled with JS Utils by default which should deserialize it into a Dictionary<string,object> which you should be able to convert back into a C# type using ServiceStack's Reflection Utils, e.g:

public object Any(CreateMutationRequest request)
{
    var payload = request.Mutation as Dictionary<string,object>;
    var payloadRequest = payload.FromObjectDictionary(typeof(TheType));
}

A similar approach to this that avoids using object is to send a serialized JSON payload in a string property, e.g:

request.mutation = JSON.stringify(payload);

Which you can deserialize using JS Utils again, e.g:

public object Any(CreateMutationRequest request)
{
    var payload = JSON.parse(request.Mutation);
    var payloadRequest = payload.FromObjectDictionary(typeof(TheType));
}

With that said I don't recommend any of these untyped strategies and would personally create Typed services for each API that's needed which is more intuitive, discoverable & resilient, any shared functionality can easily be handled in your Services implementation using ServiceStack's AutoMapping and .NET's powerful reflection capabilities.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • 1
    Thanks a lot for all the effort of explaining the solution. I will go with typed-services as you recommend. – Astrophage Mar 10 '21 at 16:13