Skip to content

CSharpClientGenerator

Rico Suter edited this page Dec 7, 2019 · 6 revisions

The following code generates the C# client code and DTO classes from a given Swagger specification:

System.Net.WebClient wclient = new System.Net.WebClient();         

var document = await OpenApiDocument.FromJsonAsync(wclient.DownloadString("Https://SwaggerSpecificationURL.json"));

wclient.Dispose();

var settings = new CSharpClientGeneratorSettings
{
    ClassName = "MyClass", 
    CSharpGeneratorSettings = 
    {
        Namespace = "MyNamespace"
    }
};

var generator = new CSharpClientGenerator(document, settings);	
var code = generator.GenerateFile();

Output

Required dependencies for the client

Library targeting .NET Standard 1.4+ (recommended)

  • Newtonsoft.Json (NuGet)
  • System.Net.Http (NuGet)
  • System.ComponentModel.Annotations (NuGet)

Library targeting the full .NET

  • Newtonsoft.Json (NuGet)
  • System.Runtime.Serialization (GAC)
  • System.ComponentModel.DataAnnotations (GAC)

Library targeting PCL 259 (Portable Class Library)

  • Newtonsoft.Json (NuGet)
  • Microsoft.Net.Http (NuGet)
  • Portable.DataAnnotations (NuGet)

Customize the generated client class

Provide base path via HttpClient

  • Set InjectHttpClient to true.
  • Set UseBaseUrl to false.

You must place a slash at the end of the BaseAddress of the injected HttpClient.

https://stackoverflow.com/a/23438417/876814

Extend the generated partial class

If you generate a C# client class, then it is marked as partial:

Clients.cs:

public partial class MyClient
{
    partial void PrepareRequest(HttpClient request, ref string url);

    partial void ProcessResponse(HttpClient request, HttpResponseMessage response);

    ...
}

This way you can extend the class in another file:

Clients.Extensions.cs:

public partial class MyClient
{
    public void MyAdditionalMethod() 
    {
        ...
    }

    partial void PrepareRequest(HttpClient request, ref string url)
    {
        // TODO: Prepare the request and modify the URL if needed
    }

    partial void ProcessResponse(HttpClient request, HttpResponseMessage response);
    {
        // TODO: Post-process the response
    }
}

Implement a base class

If the ClientBaseClass setting is set, then the generated client inherits from the class:

public partial class MyClient : MyBaseClass
{
    ...
}

If you need to control how the HttpClient is instantiated (or need another HTTP client class), you can also enable the UseHttpClientCreationMethod setting. This way the HTTP client class is created by the CreateHttpClientAsync method of the base class (generated):

public partial class MyClient : MyBaseClass
{
    public Task MyOperationAsync() 
    {
        ...
        var client = await CreateHttpClientAsync(cancellationToken).ConfigureAwait(false);
        ...
    }
}

The MyBaseClass (your partial class) class would look like this:

public partial class MyBaseClass
{
    protected async Task<HttpClient> CreateHttpClientAsync(CancellationToken cancellationToken)
    {
        var client = new HttpClient();
        // TODO: Customize HTTP client
        return client; 
    }
}

You can also customize the creation of the HttpRequestMessage with the UseHttpRequestMessageCreationMethod setting.

Provide configuration object

It is possible to specify a configuration class via the ConfigurationClass setting. If the configuration class is set, then the generated client class has an additional constructor accepting on object of the given configuration class. This configuration object is then passed to the base constructor of the base class.

The following code snippet shows the generated client class when ClientBaseClass and ConfigurationClass is set:

public partial class MyClient : MyBaseClass
{
    public MyClient() : this("", null) { }
  
    public MyClient(string baseUrl) : this(baseUrl, null) { }
    
    public MyClient(string baseUrl, MyConfig configuration) : base(configuration)
    {
        BaseUrl = baseUrl; 
    }
Clone this wiki locally