TIL: Generate Required & Optional Parameters with NSwag
Tags: dotnet, csharp, api
Published: 2021-03-10 02:23:11

---
title: TIL: Generate Required & Optional Parameters with NSwag
published: true
description: How to use NSwag to generate properly defined required and optional parameters on a Web Api
tags: dotnet, csharp, api
canonical-url: https://scribblesofcode.com/2021/03/10/til-generate-required-optional-parameters-with-nswag/
//cover_image: https://direct_url_to_image.jpg
---

I use NSwag to generate a Swagger page for each of our .NET Core services, and I also use NSwag to generate a .NET Standard proxy client for other services to use when talking to that service. 

However, sometimes the signature of the generated client is not accurate in describing which parameters are required and which parameters cannot be null. This is how to fix that.

This is the example endpoint. userId and age are required and not nullable. faveNumber is optional and nullable. 

        [HttpGet()]
        public ActionResult GetValues(
            FromHeader] string userId,
            [FromQuery] int age,
            [FromQuery] int? faveNumber)
        {
            return Ok();
        }

I want the generated client code to create the following method signature:

    GetValues(string userId, int age, int? faveNumber = null)

### Fix the swagger.json

First, I need to properly describe the endpoint parameters on the endpoint, so that the generated swagger.json describes the parameters correctly:

        "parameters": [
          {
            "name": "userId",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "x-position": 1
          },
          {
            "name": "age",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "x-position": 2
          },
          {
            "name": "faveNumber",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "nullable": true
            },
            "x-position": 3
          }
        ],

The required and nullable fields are the key to getting a properly generated client. Use Nullable (?) to denote parameters which are nullable, and use BindRequired to denote parameters which must be included:

        [HttpGet()]
        public ActionResult GetValues(
            [BindRequired][FromHeader] string userId,
            [BindRequired][FromQuery] int age,
            [FromQuery] int? faveNumber)
        {
            return Ok();
        }
    }

In Startup.cs set the default null reference to NotNull, which will prevent the required fields from accepting null as a value.

        services.AddOpenApiDocument(settings =>
        {
            settings.DefaultReferenceTypeNullHandling = NJsonSchema.Generation.ReferenceTypeNullHandling.NotNull;
        });

### Generate the Client

Now that we have a proper swagger.json, use that to build the NSwag client.

Make sure that the "Generate optional parameters" setting is selected. I end up with a generated client with the following method: 

        public async System.Threading.Tasks.Task<FileResponse> Values_GetValuesAsync(
            string userId, 
            int age, 
            int? faveNumber = null))


### Summary

When generating an NSwag client, don't just play with the Client generation settings, make sure that the swagger.json that is being generated properly represents the endpoints you've built in code. 

Building the correct swagger.json is key to building a correct client.