Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSwag v14 preview announcement & breaking changes #4524

Open
RicoSuter opened this issue Sep 26, 2023 · 112 comments
Open

NSwag v14 preview announcement & breaking changes #4524

RicoSuter opened this issue Sep 26, 2023 · 112 comments

Comments

@RicoSuter
Copy link
Owner

RicoSuter commented Sep 26, 2023

Please test the preview packages for NSwag v14 and NJsonSchema v11 and report problems here.

Note: NSwag/NJS still uses Newtonsoft.Json for serializing/deserializing schemas internally, so for now it still requires newtonsoft as a reference, internal serialization will hopefully migrated to STJ in the next major version.

This whole major version is about dropping old stuff to make the project maintainable again. I'm testing it with my more or less modern ASP.NET Core applications. The goal is that the tooling still works with them and there are no regressions or very hard to mitigate breaking changes.

NSwag v14

PR: #3758

Breaking changes

  • NJsonSchema generator settings moved from being directly on the generator settings to the "SchemaSettings" property.
  • nswag.json now only supports .csproj based specification generation (reflection/assembly based removed, only aspnetcore2openapi)
  • Now only supports .NET Standard 2.0, .NET 4.6.2, .NET Core 3.1, .NET 5, .NET 7 and up
  • Requires latest Newtonsoft.Json v13.0.0.3
  • Removed many deprecated properties, settings and methods (marked a long time as obsolete)
  • Removed WebApiToOpenApiCommand: Use the WebApiOpenApiDocumentGenerator to build your own CLI referencing controllers project to generate OpenAPI without starting the app
  • Renamed UseSwaggerUi3 to UseSwaggerUi (v2 has been removed)

NJsonSchema v11

PR: RicoSuter/NJsonSchema#1450 (merged)

Breaking changes

  • All Newtonsoft.Json based generators moved to NJsonSchema.NewtonsoftJson
  • Requires latest Newtonsoft.Json v13.0.0.3
  • Now only supports .NET Standard 2.0, .NET 4.6.2 and up
  • Updated to latest Namotion.Reflection v3
  • Breaking change in IJsonExtensionObject interface (now supports multiple data tuples)

Other changes:

  • Add support for STJ-native inheritance schema generation (JsonDerivedType, JsonPolymorphic)
  • Many more smaller improvements and fixes (see git history)
@RicoSuter RicoSuter pinned this issue Sep 26, 2023
@Numpsy
Copy link
Contributor

Numpsy commented Sep 27, 2023

Hi,

The 14.0.0-preview004 package for NSwag.ApiDescription.Client seems to have a dependency of

NSwag.MSBuild (>= 14.0.0)

and when I try to update in Visual Studio it complains because NSwag.MSBuild only has 14.0.0-preview00N packages

@RicoSuter
Copy link
Owner Author

@Numpsy try v14.0.0-preview005

@Numpsy
Copy link
Contributor

Numpsy commented Sep 27, 2023

Ok, the new version has installed ok

@RicoSuter RicoSuter changed the title NSwag v14 (preview) announcement & breaking changes NSwag v14 preview announcement & breaking changes Sep 28, 2023
@olegd-superoffice
Copy link
Contributor

Both .NET Core 3.1 and .NET 5 are out of support already and .NET 8 is around the corner. So maybe drop support for old versions?

@lahma
Copy link
Collaborator

lahma commented Sep 28, 2023

@olegd-superoffice there's #4001 for that

@Numpsy
Copy link
Contributor

Numpsy commented Sep 28, 2023

fwiw I've dropped the v14 test packages into a project that contains an asp .net core 3.1 web service and a mix of client builds using different .net versions, but one of the reasons for that is that I'm trying to see what's going on with the Mend complaints described at #2824 - and as long as I can generate client code that can build as .NET Standard 2.0 it doesn't matter if the code generator itself needs .NET 6+ and I don't have any pressing need to update the server side itself

@lahma
Copy link
Collaborator

lahma commented Oct 1, 2023

  • nswag.json now only supports .csproj based specification generation (reflection/assembly based removed, only aspnetcore2openapi)

I wonder if this now makes it impossible to generate API specification and clients via MSBuild. Seems that now MSBuild will invoke NSwag's run target (with nswag.json etc) like documented in MSBuild integration guidance which in turn now needs to gather the project metadata by invoking MSBuild against the csproj (DLL no longer supported), which in turn will again invoke the nswag run and the recursion will continue...

There's also quite a lot of performance penalty from invoking the build pipeline multiple times.

EDIT, so the way nswag.json needs to be configured is to have "noBuild": true in it when invoked from csproj.

@RicoSuter
Copy link
Owner Author

EDIT, so the way nswag.json needs to be configured is to have "noBuild": true in it when invoked from csproj.

Exactly, if you run this as part of the csproj build (after build) then you need to enable noBuild

@Tomius
Copy link

Tomius commented Oct 4, 2023

nswag.json now only supports .csproj based specification generation (reflection/assembly based removed, only aspnetcore2openapi)

Nit: the docs will eventually need to be updated to reflect this, e.g. WebApiToOpenApiCommand

Out of curiosity, what was the reason to remove this feature?

I mean, I understand that having fewer commands makes the code easier to maintain. But it feels very sad to have start up the application to generate swagger from it, when it's used at large scale. E.g. the build and prod enviornments might be very different and the app might not start up on the build machine. Or it might do some very expensive intialisation, like read from databases, that might significantly increase build times (if the nswag generation happens during the build).

I am aware that I could put all the controllers into a library and have two Asp.Net core apps, one for prod doing the real initialisation, and a "dummy one" just for nswag. But having to do this just feels so painful compared to how easy it was to use NSwag v13.

@RicoSuter
Copy link
Owner Author

RicoSuter commented Oct 4, 2023

Out of curiosity, what was the reason to remove this feature?

Main reason is that all this legacy stuff puts a lot of maintenance effort.
The main pain is this whole dynamic assembly loading stuff.
I cannot maintain legacy frameworks, .net runtimes forever alone without even being paid for it...

The web api generator is still available, so the simplest solution for you would be to just build your own simple CLI tool which uses the
https://github.com/RicoSuter/NSwag/wiki/WebApiOpenApiDocumentGenerator
and references the project with the controllers...

I am aware that I could put all the controllers into a library and have two Asp.Net core apps

Did you use WebApiToOpenApiCommand for ASP.NET Core? That's a very bad idea as it uses reflection and not the API explorer which might lead to completely wrong results...

@m-demydiuk
Copy link

m-demydiuk commented Oct 24, 2023

Version 14.0.0-preview008 has a reference to Microsoft.Extensions.ApiDescription.Server v6.0.3.
Is it correct?
image

@RicoSuter
Copy link
Owner Author

Is this a problem?

@m-demydiuk
Copy link

@RicoSuter we have all other packages (also transitive) in our project updated to the latest version, except this. Is there any blocker not to update this one to latest?

@olegd-superoffice
Copy link
Contributor

@m-demydiuk This reference is only setting minimal supported version of the package, but you always can use newer ones in your project if you reference the dependency directly of if you use NuGet's central package management with CentralPackageTransitivePinningEnabled.
But there are many use cases where it is not possible to use the latest version and keeping this reference to minimal supported version allows it to be used in those cases.

@Herdo
Copy link

Herdo commented Nov 4, 2023

@RicoSuter Will there also be a preview of the NSwagStudio 14.x ? 😄

@lahma
Copy link
Collaborator

lahma commented Nov 4, 2023

@Herdo the studio setup MSI should now be part of the release assets.

@Gigas002
Copy link

What's about OpenAPI v3.1.0/swagger-ui v5? This is being constantly asked since 2021 in a #3761, but haven't been answered still. Are these a planned features, at least?

@vipwan
Copy link

vipwan commented Nov 15, 2023

In v14 preview AspNetCoreOpenApiDocumentGeneratorSettings removed the SchemaProcessors property , how should I register a custom ISchemaProcessor

@chriscameron-vertexinc
Copy link

It looks like JsonSchemaGeneratorSettings is gone, removing the UseXmlDocumentation option on AddSwaggerDocument. Should we not be using XML documentation to drive the Swagger documentation anymore?

@lahma
Copy link
Collaborator

lahma commented Nov 15, 2023

@vipwan @chriscameron-vertexinc

services.AddSwaggerDocument(document =>
{
    document.SchemaSettings.SchemaProcessors.Add(null!);
    document.SchemaSettings.UseXmlDocumentation = true;
});

@chriscameron-vertexinc
Copy link

chriscameron-vertexinc commented Nov 15, 2023

nswag.json
Here's an odd one. I'm using a post build step to run NSwagExe_Net80:

  <Target Name="NSwag" AfterTargets="Build">
    <Exec Command="$(NSwagExe_Net80) run nswag.json /variables:Configuration=$(Configuration)" />
  </Target>

My nswag.json aspNetCoreToOpenApi document generator has the following assembly path:

      "assemblyPaths": [
        "bin/$(Configuration)/net8.0/CNR.Example.API.dll"
      ],

Since following the advice above to set noBuild to true this is working perfectly in VS2022 when I build for Debug or Release.

In my CI/CD pipeline I'm doing the following:

dotnet restore ./src/CNR.Example.API.sln
dotnet build ./src/CNR.Example.API.sln --maxcpucount --configuration Release --no-restore

This also works perfectly from my local command line, however on my build machine I get:

  NSwag command line tool for .NET Core Net80, toolchain v14.0.0.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))
  Visit http://NSwag.org for more information.
  NSwag bin directory: /root/.nuget/packages/nswag.msbuild/14.0.0-preview009/tools/Net80
  
  Executing file 'nswag.json' with variables 'Configuration=Release'...
  System.InvalidOperationException: Project outputs could not be located in '/home/ubuntu/actions-runner/_work/cnr-example-api/cnr-example-api/src/CNR.Example.API/bin/Debug/net8.0/'. Ensure that the project has been built.
     at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCommand.cs:line 82
     at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 270
     at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 67
     at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 76
     at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 33
     at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
     at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
     at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 62
/home/ubuntu/actions-runner/_work/cnr-example-api/cnr-example-api/src/CNR.Example.API/CNR.Example.API.csproj(54,5): error MSB3073: The command "dotnet "/root/.nuget/packages/nswag.msbuild/14.0.0-preview009/buildTransitive/../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release" exited with code 255.

It looks like NSwagExe_Net80 isn't replacing the $(Configuration) value in my nswag.json properly. It clearly says Executing file 'nswag.json' with variables 'Configuration=Release' and then complains that it can't find the file in the Debug directory.

The exact same script, and exact same machine, when working with .net7.0:

  NSwag command line tool for .NET Core Net70, toolchain v13.20.0.0 (NJsonSchema v10.9.0.0 (Newtonsoft.Json v13.0.0.0))
  Visit http://NSwag.org for more information.
  NSwag bin directory: /root/.nuget/packages/nswag.msbuild/13.20.0/tools/Net70
  
  Executing file 'nswag.json' with variables 'Configuration=Release'...
  Done.
  
  Duration: 00:00:01.3889592

@RicoSuter
Copy link
Owner Author

@chriscameron-vertexinc assembly path loading has been removed, use “project” with path to csproj instead

@RicoSuter
Copy link
Owner Author

JsonSchemaGeneratorSettings Is part of NJsonSchema and now a property and not inheritance anymore.. mainly because there are now two variants: system.text.json and newtonsoft..

@chriscameron-vertexinc
Copy link

@chriscameron-vertexinc assembly path loading has been removed, use “project” with path to csproj instead

I've now updated my nswag.json to use project instead of assemblyPaths and I'm seeing the exact same problem.

It looks like I misspoke when I said I couldn't reproduce the problem locally. After deleting my bin directories to clear out the Debug output my post build step is failing in VS2022 release builds.

image

@yfital
Copy link

yfital commented Nov 16, 2023

Sorry, i would really appreivcate a clarification on how we are supposed to work here with the removal of the WebApi2Swagger.
We have 2 use cases:

  1. We have an internal SDK which includes our hosting capabilities and various controllers
    1.2. These are dlls, not .exes which do not contain startup
    1.3. All our of programs inherit these
    1.4 Our UI uses a document create from the SDK for all general purpose controllers and specific code from documents from the console applications

  2. We have a multi dll console application, where the controllers sit in the DLLs and not in the console

Our current solution was simple, in the SDK, we used WebApi2Swagger to create the openapi

In our DLLs

(Notice, in the DLL we also exported the document for the SDK counterpart)
  • Our actual .exe doesn't have any reference to nswag.msbuild, it doesn't need it
  • Our .exe(s) are heavy one, i prefer to create the openapi it without having to run it

am i missing something here? are we working completly wrong?

@lahma
Copy link
Collaborator

lahma commented Nov 16, 2023

@chriscameron-vertexinc

We had to tune the configuration a bit after enabling <UseArtifactsOutput>true</UseArtifactsOutput> (docs) . Maybe this can give some configuration clues for you, key is to point msBuildProjectExtensionsPath to obj folder and have configuration passed in as variable, our mileage may vary.

{
  "runtime": "Net70",
  "defaultVariables": null,
  "documentGenerator": {
    "aspNetCoreToOpenApi": {
      "project": null,
      "documentName": "v1",
      "msBuildProjectExtensionsPath": "../../artifacts/obj/TheProjectFolder",
      "configuration": "$(Configuration)",

@chriscameron-vertexinc
Copy link

Thanks so much @lahma !

In summary, I've had to change the following to get NSwagExe_80 to work for me:

  • Change API csproj post build to use NSwagExe_80
  • Change nswag.json runtime to net80
  • Change nswag.json nobuild to true
  • Change nswag.json project to the path to my csproj file
  • Change nswag.json configuration to "$(Configuration)"
  • Change nswag.json assemblyPaths to []
  • Fix instances of UpdateJsonSerializerSettings in the clients to be static
  • Move UseXmlDocumentation from the document to the schema settings

@andreicalin246
Copy link

We had to migrate our api from .net7 to .net 8. After migration our typescript client has some issues:

export class UserDto implements IUserDto {
    id?: string;
    name?: string;
    email?: string;
    phone?: string;

    constructor(data?: IUserDto) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.id = _data["Id"] !== undefined ? _data["Id"] : <any>null;
            this.name = _data["Name"] !== undefined ? _data["Name"] : <any>null;
            this.email = _data["Email"] !== undefined ? _data["Email"] : <any>null;
            this.phone = _data["Phone"] !== undefined ? _data["Phone"] : <any>null;
        }
    }

Main issue is because we have _data["Name"] instead _data["name"]. Is there a setting to make it camelCase instead PascalCase?

@lahma
Copy link
Collaborator

lahma commented Feb 13, 2024

@andreicalin246 see #4524 (comment)

@dmitry-pavlov
Copy link

In v14 preview AspNetCoreOpenApiDocumentGeneratorSettings removed the SchemaProcessors property , how should I register a custom ISchemaProcessor

Something like that @vipwan

services.AddOpenApiDocument(options =>
{
    options.SchemaSettings.SchemaProcessors.Add(new MyISchemaProcessor());
});

@IanKemp
Copy link

IanKemp commented Mar 13, 2024

Seems like the operationProcessorTypes parameter in nswag.json is now silently ignored, you have to manually add them:

        services.AddOpenApiDocument(options =>
        {
            options.OperationProcessors.Add(new MyOperationProcessor());
        });

Yet another breaking change that is not documented in any way shape or form. This is why my organisation is moving to Kiota.

@xantari
Copy link

xantari commented Mar 18, 2024

UseXmlDocumentation doesn't seem to load XML documentation for other assemblies in V14... Has anyone got this to work?

@SSRazvan
Copy link

SSRazvan commented Mar 19, 2024

Upgrade to .NET 8.0 and NSwag.AspNetCore 14.0.3 Exec NSwag exited with code -1. Has anyone any idea how to fix this?

My command:

<Target Name="NSwag" AfterTargets="PostBuildEvent" Condition=" '$(Configuration)' == 'Debug' ">
    <Exec ConsoleToMSBuild="true" WorkingDirectory="$(ProjectDir)" EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Localhost" Command="$(NSwagExe_Net80) run /variables:Configuration=$(Configuration)">
    </Exec>
</Target>

My nswag.json
{ "runtime": "Net80", "defaultVariables": null, "documentGenerator": { "aspNetCoreToOpenApi": { "project": "WebUI.csproj", "msBuildProjectExtensionsPath": null, "configuration": null, "runtime": null, "targetFramework": null, "noBuild": true, "msBuildOutputPath": null, "verbose": false, "workingDirectory": null, "requireParametersWithoutDefault": true, "apiGroupNames": null, "defaultPropertyNameHandling": "CamelCase", "defaultReferenceTypeNullHandling": "Null", "defaultDictionaryValueReferenceTypeNullHandling": "NotNull", "defaultResponseReferenceTypeNullHandling": "NotNull", "generateOriginalParameterNames": true, "defaultEnumHandling": "Integer", "flattenInheritanceHierarchy": false, "generateKnownTypes": true, "generateEnumMappingDescription": false, "generateXmlObjects": false, "generateAbstractProperties": false, "generateAbstractSchemas": true, "ignoreObsoleteProperties": false, "allowReferencesWithProperties": false, "useXmlDocumentation": true, "resolveExternalXmlDocumentation": true, "excludedTypeNames": [], "serviceHost": null, "serviceBasePath": null, "serviceSchemes": [], "infoTitle": "Test API", "infoDescription": null, "infoVersion": "1.0.0", "documentTemplate": null, "documentProcessorTypes": [], "operationProcessorTypes": [], "typeNameGeneratorType": null, "schemaNameGeneratorType": null, "contractResolverType": null, "serializerSettingsType": null, "useDocumentProvider": true, "documentName": "v1", "aspNetCoreEnvironment": null, "createWebHostBuilderMethod": null, "startupType": null, "allowNullableBodyParameters": true, "useHttpAttributeNameAsOperationId": false, "output": "wwwroot/api/specification.json", "outputType": "OpenApi3", "newLineBehavior": "Auto", "assemblyPaths": [], "assemblyConfig": null, "referencePaths": [], "useNuGetCache": false } }, "codeGenerators": { "openApiToTypeScriptClient": { "className": "{controller}Client", "moduleName": "", "namespace": "", "typeScriptVersion": 4.3, "template": "Angular", "promiseType": "Promise", "httpClass": "HttpClient", "withCredentials": false, "useSingletonProvider": true, "injectionTokenType": "InjectionToken", "rxJsVersion": 7.0, "dateTimeType": "Date", "nullValue": "Undefined", "generateClientClasses": true, "generateClientInterfaces": true, "generateOptionalParameters": false, "exportTypes": true, "wrapDtoExceptions": false, "exceptionClass": "SwaggerException", "clientBaseClass": null, "wrapResponses": false, "wrapResponseMethods": [], "generateResponseClasses": true, "responseClass": "SwaggerResponse", "protectedMethods": [], "configurationClass": null, "useTransformOptionsMethod": false, "useTransformResultMethod": false, "generateDtoTypes": true, "operationGenerationMode": "MultipleClientsFromOperationId", "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", "enumStyle": "Enum", "useLeafType": false, "classTypes": [], "extendedClasses": [], "extensionCode": null, "generateDefaultValues": true, "excludedTypeNames": [], "excludedParameterNames": [], "handleReferences": false, "generateConstructorInterface": true, "convertConstructorInterfaceData": false, "importRequiredTypes": true, "useGetBaseUrlMethod": false, "baseUrlTokenName": "API_BASE_URL", "queryNullValue": "", "useAbortSignal": false, "inlineNamedDictionaries": false, "inlineNamedAny": false, "includeHttpContext": false, "templateDirectory": null, "typeNameGeneratorType": null, "propertyNameGeneratorType": null, "enumNameGeneratorType": null, "serviceHost": null, "serviceSchemes": null, "output": "ClientApp/src/app/web-api-client.ts", "newLineBehavior": "Auto" } } }

@SoleCode
Copy link

SoleCode commented Mar 25, 2024

I have upgraded to v14 and the build is failing. Here is configuration I have and it works with v13

<OpenApiReference Include="OpenAPIs\swagger.json" CodeGenerator="NSwagCSharp" Namespace="Portal.Api" ClassName="ApiClient">
	<OutputPath>$(ProjectDir)/OpenAPIs/ApiClient.cs</OutputPath>
	<Options>/JsonLibrary:SystemTextJson /OperationGenerationMode:SingleClientFromOperationId /InjectHttpClient:false /ClientClassAccessModifier:public /GenerateClientInterfaces:true /UseBaseUrl:false /GeneratePrepareRequestAndProcessResponseAsAsyncMethods:true /DateType:System.DateOnly /GenerateDefaultValues:false /InjectHttpClient:fasle /UseHttpClientCreationMethod:true</Options>
</OpenApiReference>

@MoeHamdan
Copy link

Hello

I used to use
"apiGroupNames": [
"v2"
],
now it is being replaced by
"documentName": "v1",

I am setting it to "documentName": "v2", however this throws the following exception System.InvalidOperationException: No registered OpenAPI/Swagger document found for the document name 'v2'. Add with the AddSwagger()/AddOpenApi() methods in ConfigureServices().

Note that "documentName": "v1", works but generates both v1 and v2, I only want to generate v2.

Thanks.

@Saibamen
Copy link
Contributor

Saibamen commented Jun 27, 2024

app.UseSwagger(typeof(WebApiApplication).Assembly, settings => {});

This code is not working on the latest version of NSwag. Do we have any migration documentation? Nothing about it in release changelog

EDIT: OK, I changed it to app.UseSwaggerReDoc, but I don't know if this is correct, because of build error (see my next comment).

@Saibamen
Copy link
Contributor

Saibamen commented Jun 27, 2024

And how to update this code? SerializerSettings it not exists anymore...

app.UseSwagger(typeof(WebApiApplication).Assembly, settings => {});
{
    settings.GeneratorSettings.SerializerSettings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        // Show enums as string, not integers
        Converters = { new StringEnumConverter() },
    };
});

EDIT: Fixed by:

RouteTable.Routes.MapOwinPath("swagger", app =>
{
   app.UseSwaggerUi(typeof(WebApiApplication).Assembly, settings =>
   {
       var schemaSettings = new NewtonsoftJsonSchemaGeneratorSettings
       {
           SerializerSettings = new JsonSerializerSettings
           {
               ContractResolver = new CamelCasePropertyNamesContractResolver(),
               // Show enums as string, not integers
               Converters = { new StringEnumConverter() },
           },
       };

       settings.GeneratorSettings.SchemaSettings = schemaSettings;
   });
});

Now I have runtime exception:

The class 'NSwag.AspNet.Owin.Middlewares.SwaggerUiIndexMiddleware`1[[NSwag.Generation.WebApi.WebApiOpenApiDocumentGeneratorSettings, NSwag.Generation.WebApi, Version=14.0.8.0, Culture=neutral, PublicKeyToken=c2d88086e098d109]]' does not have a constructor taking 4 arguments.]

.NET Framework v4.8, NSwag v14.0.8

@trejjam
Copy link
Contributor

trejjam commented Jun 28, 2024

You might wanna use it this way:

if (settings.GeneratorSettings.SchemaSettings is NewtonsoftJsonSchemaGeneratorSettings newtonsoftJsonSchemaGeneratorSettings)
{
...
}

To do not drop defaults

@trejjam
Copy link
Contributor

trejjam commented Jun 28, 2024

Ad runtime error: Are you sure you have all NSwag packages in the same version?
The current version has a constructor with precisely four arguments: https://github.com/RicoSuter/NSwag/blob/master/src/NSwag.AspNetCore/Middlewares/SwaggerUiIndexMiddleware.cs

Checking the version of the NJsonSchema packages might be a good idea as well.

@trejjam
Copy link
Contributor

trejjam commented Jun 28, 2024

Instead of ReDoc, you might use UseOpenApi, but it's just another frontend. (Swagger was renamed)

@MathiasZander
Copy link

MathiasZander commented Jun 29, 2024

Can I prevent the configuration file from being overwritten by NSwag on build?

<Target Name="NSwag" AfterTargets="Build" Condition="'$(DeployOnBuild)' != 'true' "> <Exec EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Development" Command="$(NSwagExe_Net80) run properties/generator.nswag /variables:Configuration=$(Configuration),AssemblyName=$(AssemblyName),ShortName=Clients" /> </Target>

@Saibamen
Copy link
Contributor

Saibamen commented Jul 1, 2024

Thanks @trejjam

Runtime exception was fixed by changing UseSwaggerReDoc() to UseOpenApi().

Checking the version of the NJsonSchema packages might be a good idea as well.

My NJsonSchema version is 11.0.1 - the latest for today.

Now I can open Swagger - it is also showing v1 and v2 endpoints :)


But JSON settings are not working :(
if (settings.GeneratorSettings.SchemaSettings is NewtonsoftJsonSchemaGeneratorSettings newtonsoftSettings)
{
    newtonsoftSettings.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    // Show enums as string, not integers
    newtonsoftSettings.SerializerSettings.Converters = [new StringEnumConverter()];
}

image

image

@trejjam
Copy link
Contributor

trejjam commented Jul 1, 2024

NSwag is transitioning to System.Text.Json; it uses the serializer used in your project. You can check what applies to your project:
https://github.com/RicoSuter/NSwag/blob/master/src/NSwag.AspNetCore/Extensions/NSwagServiceCollectionExtensions.cs#L71

You can check (by debugger) if you are using NewtonsoftJsonSchema in settings.GeneratorSettings.SchemaSettings or if you have SystemTextJsonSchemaGeneratorSettings, which implies that your project is using STJ. After gaining that knowledge, you can decide which JSON library you will use for your project. I prefer STJ since most libraries are moving towards it from Newtonsoft.

Then, you can solve the issues you are having in the library you are using.
(for Newtonsoft: add&configure it in ServiceCollection, for STJ: configure .Configure<AspNetCore.Http.Json.JsonOptions>(x=>x.SerializerOptions))

@Saibamen
Copy link
Contributor

Saibamen commented Jul 1, 2024

I'm using .NET Framework for this project and I don't have IServiceCollection in my Global.asax.cs file.

@trejjam
Copy link
Contributor

trejjam commented Jul 1, 2024

Then, it would be best to look at how it's done for the .Net Framework. I have 0 knowledge of the .Net Framework.

@hershize
Copy link

hershize commented Jul 2, 2024

I'm using .NET 8 framework and have NSwag.AspNetCore v14.0.8 installed. When I startup my application, I'm receiving the follow message:

System.Reflection.ReflectionTypeLoadException: 'Unable to load one or more of the requested types.
Could not load type 'NSwag.AspNetCore.SwaggerUiSettingsBase`1' from assembly 'NSwag.AspNetCore, Version=14.0.8.0, Culture=neutral, PublicKeyToken=c2d88086e098d109'.'

The exception is thrown during startup when it hits the following code:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages(); <-- here
    endpoints.MapControllerRoute(<removed for brevity>); <-- and here if comment out the line above
});

Here is my stacktrace:

   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFeatureProvider.PopulateFeature(IEnumerable`1 parts, ControllerFeature feature)
   at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateFeature[TFeature](TFeature feature)
   at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetControllerTypes()
   at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetDescriptors()
   at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection()
   at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.Initialize()
   at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.GetChangeToken()
   at Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration`1..ctor(Func`1 changeTokenProducer, Action`1 changeTokenConsumer, TState state)
   at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)
   at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.Subscribe()
   at Microsoft.AspNetCore.Builder.RazorPagesEndpointRouteBuilderExtensions.GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
   at Microsoft.AspNetCore.Builder.RazorPagesEndpointRouteBuilderExtensions.MapRazorPages(IEndpointRouteBuilder endpoints)
   at Company.ProjectName.Startup.<>c.<Configure>b__6_5(IEndpointRouteBuilder endpoints) in <removed>\Startup.cs:line 315
   at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
   at Company.ProjectName.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in <removed>\Startup.cs:line 313
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)

Does anyone have suggestions on how to remediate this? Let me know what else I can provide.

@trejjam
Copy link
Contributor

trejjam commented Jul 3, 2024

I think you are mixing Owin and Core integration:

@hershize
Copy link

hershize commented Jul 3, 2024

@trejjam

I think you are mixing Owin and Core integration:

How would I identify if it is using Owin as opposed to Core? I'm farily certain I am using Core.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests