Forum Discussion

MMannSmartCert's avatar
MMannSmartCert
New Contributor
2 years ago

Generating Documentation Manually via Code

Hello all, I understand that I am probably doing way more work than I need considering C#/.NET offers many built-in tools for generating documentation based on tags and comments, but for various reasons I am not(cannot) do that.

 

I am trying to use the NSwag NuGet package to manually generate the OpenAPI documentation for my rest calls. I have found the tool "https://editor.swagger.io/" to help verify my structure and needless to say it is not happy at all. The main problem seems to be around the JSON Schema for my complex objects when used in body's, responses, or parameters. I have tried setting all sorts of different properties and using different methods to add the schema to my OpenAPI json file with zero luck. I've also scoured the internet and it seems that I can barely find an example of what I am doing, never mind help to achieve it, so here I am...begging for help 🙂

 

Here is a super simplified piece of code, with some values hardcoded/swapped out to make the example easy:

 

 

 

                var openApiDocument = new NSwag.OpenApiDocument()
                {
                    Info = new NSwag.OpenApiInfo()
                    {
                        Version = "1.0",
                        Title = "SOME TITLE",
                        Description = "THIS IS WHAT MY API DOES",
                        Contact = new NSwag.OpenApiContact()
                        {
                            Email = "my email.com",
                            Url = "https://www.mywebsite.com",
                            Name = "Our Company's Name!"
                        }
                    },
                    ExternalDocumentation = new NSwag.OpenApiExternalDocumentation()
                    {
                        Url = "http://swagger.io",
                        Description = "Find out more about Swagger"
                    }
                };
                openApiDocument.Servers.Add(new NSwag.OpenApiServer { Url = "www.myserver.com" });
                openApiDocument.SchemaType = NJsonSchema.SchemaType.OpenApi3;

openApiDocument.Tags.Add(new NSwag.OpenApiTag()
                    {
                        Name = "a group"
                    });

                        NSwag.OpenApiPathItem myPath = new NSwag.OpenApiPathItem();
                            openApiDocument.Paths.Add("/callme", myPath);

                        var newOp = new NSwag.OpenApiOperation()
                        {
                            Description = "cool description bro"
                        };
newOp.Tags.Add("a group");

                            var temp = new NSwag.OpenApiResponse();                        
                            temp.Content.Add(
                                "application/json",
                                new NSwag.OpenApiMediaType
                                {
                                    Schema =             NJsonSchema.JsonSchema.FromType(<MY TYPE>, new JsonSchemaGeneratorSettings() 
            { 
                //Just trying the below properties, I have tried everything here :(
                //AlwaysAllowAdditionalObjectProperties = true,
                //AllowReferencesWithProperties = true
            });,
                                    Example = new NSwag.OpenApiExample()
                                    {
                                        Value = Activator.CreateInstance(<MY TYPE>)
                                    }
                                });

                            newOp.Responses.Add("200", temp);
myPath.Add("get", newOp);

var rawJson = openApiDocument.ToJson();//for file saving or whatever, I do something different here but this gets the point accross

 

 

 

Sorry for the crap formatting.....anyway, the file generated looks like: https://smartcertxstorageshared.blob.core.windows.net/generic/SmartCertOpenAPI-Test.json. The main error message in the testing website is:

Structural error at paths./companies.get.responses.200.content.application/json.schema

should NOT have additional properties additionalProperty: definitions

 
Which I do mostly understand and all of the examples I have found of raw JSON/YAML indicate that the schema should JUST be something like the pet store example(also below). However I cannot figure out how to make the code do that without manually generating JSON strings. How do I use the objects like NSwag.OpenApiMediaType.Schema or whatever? I have tried adding the schema directly as in my examples and then also adding it to NSwag.Components.Schemas and then setting the reponse.Schema = openApiDocument.Components.Schema["some key"], but it still prints the same thing out to the final JSON. I cannot figure out how to make the schema a single "$ref" line.
 
 

 

 

'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'

 

 

 

  • ok, one of my problems solved at least! Not many examples out there and documentation is a bit vague, but if I add all of my schemas to the OpenApiDocument.Components.Schema and then reference them as follows when actually using them it seems to work.

     

    The missing piece was that I needed to make a "new JsonSchema().Reference = XXXXX", which is my reference to the previously added type!

     

    var returnType = Type.GetType(item.ReturnType);
    var temp = new NSwag.OpenApiResponse();
    var schema = ObjectTools.GetSchemaFromType(returnType);

    if (resolver.Schemas.FirstOrDefault(x => x.Title == schema.Title) == null)
    {
    resolver.AddSchema(returnType, false, schema);
    }

    temp.Content.Add(
    "application/json",
    new NSwag.OpenApiMediaType
    {
    Schema = new NJsonSchema.JsonSchema()
    {
    Reference = resolver.GetSchema(returnType, false)
    },
    Example = new NSwag.OpenApiExample()
    {
    Value = Activator.CreateInstance(returnType)
    }
    });

    newOp.Responses.Add("200", temp);

     

     

    However how my problem is that when I add my original object to the OpenApiDocument.Components.Schema, I cannot figure out how to make it remove the "definitions" section(which the tool complains about) and how to force the reference to be "#components/schemas/<SOMEOBJECT> instead of it being nested