Aleksandar Pasaric

NSwag with .Net Core 3.1

My story with NSwag begun a few months ago when I set out to build a new REST API for a specific domain area. I wanted to have the client SDK's generated for me to save both time and effort, this is when I came across NSwag!

The final API both generates documentation based on the Open API standard with swagger as well as generating client code using NSwag.

After setting up the project with the Controllers and all the relevant Attributes for the documentation, I created the nswag.json file using NSwagStudio (NSwag generates the clients based on the Open API specification file).

In the .csproj file of the API Host Project I have the following.

  <ItemGroup>
    <PackageReference Include="NSwag.AspNetCore" Version="13.10.1" />
    <PackageReference Include="NSwag.MSBuild" Version="13.10.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <Target Name="NSwag" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
    <Copy SourceFiles="@(Reference)" DestinationFolder="$(OutDir)References" />
    <Exec Command="$(NSwagExe_Core31) run /variables:Configuration=$(Configuration)" />
    <RemoveDir Directories="$(OutDir)References" />
  </Target>  

This will update the clients on each build of project!

One thing worth mentioning is that the Open API specification has no support for the application/json-patch+json media type, effectively limiting NSwag's ability to handle this header. This subsequently blocks us from accepting Controller Action argument JsonPatchDocument<T>....

My current workaround for this is to extend the generated client class by implementing the partial PrepareRequest method.

public partial class ApiClient
{
	partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url)
	{
		if (request.Method.Equals(new System.Net.Http.HttpMethod("PATCH")))
		{
			request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json-patch+json");
		}
	}
}

Except for the manual intervention above, I am super happy with how the project turned out. Never again I am writing tedious SDK's for my REST API's!