Open dgmagno opened 4 years ago
I just encountered this issue as well. I ended up using the workaround because I have more than one connected service in visual studio and need the other ones to build and they are all in different namespaces.
I can manually modify the code to build fine but the workaround is the only way to get this to succeed on my build server.
The thing is that we would need a set of exception classes per generated namespace.
If we reference multiple OpenAPI services, we need to group by namespace and, either generate the exception classes in the first generated cs per namespace, or generate a separate file like "$(namespace).Exceptions.cs"
only containing the exception classes.
I think it is easier, though, to assume that exception MUST always be generated, and leave the user the option to add the option /GenerateExceptionClasses:false
when generating multiple clients on the same namespace.
In my case I find it the common case when adding multiple OpenAPI references, because I always add the following attributes to my controller's actions:
[SwaggerResponse(400, "Bad request", typeof(ValidationProblemDetails))]
[SwaggerResponse(404, "Not found", typeof(ProblemDetails))]
[SwaggerResponse(500, "Internal error")]
So, NSwag end's up generating classes for ProblemDetails
and ValidationProblemDetails
on each generated client code. This forces my to generate each client on a different namespace anyway.
I prefer to leave the user with more control instead of assuming a configuration that breaks more complex code.
I stumbled on this one when I had to generate a new version of a client side-by-side.
I had a look at https://github.com/RicoSuter/NSwag/blob/85ae862fd6d68173a201a79e0ad06e0be2ec5de1/src/NSwag.CodeGeneration.CSharp/CSharpClientGeneratorSettings.cs to check the options we have.
Finally, I decided not to use a generated ApiException class, but instead move that to my own file.
<OpenApiReference Include="Example.openapi.v1_3.json" CodeGenerator="NSwagCSharp" Namespace="Example.Api.Clients.v1_3" Condition="'$(Configuration)'=='Debug'">
<OutputPath>..\Clients\Example.openapi.v1_3Client.cs</OutputPath>
<Options>/GenerateClientInterfaces:true /GenerateExceptionClasses:false /AdditionalNamespaceUsages:Example.Api.Client.Exceptions</Options>
</OpenApiReference>
<OpenApiReference Include="Example.openapi.v1_4.json" CodeGenerator="NSwagCSharp" Namespace="Example.Api.Clients.v1_4" Condition="'$(Configuration)'=='Debug'">
<OutputPath>..\Clients\Example.openapi.v1_4Client.cs</OutputPath>
<Options>/GenerateClientInterfaces:true /GenerateExceptionClasses:false /AdditionalNamespaceUsages:Example.Api.Client.Exceptions</Options>
</OpenApiReference>
This is still an issue for me. Is there a real fix in the making for this ?
I found out that if you remove all connected services and re-add them again in a different orders, sometimes it generates it.
Can confirm it is still an issue. If it is not fixed it should at least be mentioned in the official documentation with the description of a workaround for it.
The situation is that I have to add two or more OpenAPIs to a VS2022 project, because my service interfaces to more APIs.
Here is my cumbersome procedure:
<Options>/AdditionalNamespaceUsages:TheOpenApiNamespace /GenerateExceptionClasses:false</Options>
. TheOpenApiNamespace is replaced with the actual namespace.When I have to maintain the OpenAPI services like extending or upgrade to a new version, then I download the OpenAPI swagger json file and overwrite the existing. Next I delete the ..SwaggerClient.cs n the obj folder. VS2022 rebuilds then a new ...SwaggerClient.cs.
I hope it will be easier soon!
@JanRou We use the exact same approach, if I'm not mistaken (@nzeus can you concur?). Thank you for your detailed HOWTO!! ❤️
@JanRou We use the exact same approach, if I'm not mistaken (@nZeus can you concur?). Thank you for your detailed HOWTO!! ❤️
Do you have any tip regarding the duplicated ApiException code?
I'd just like to add that in Aug 2022, this is still a problem with the latest version. Thanks all for the work arounds, but a proper fix would be much appreciated please.
I am also dealing with this issue. I am generating many API models and getting ApiClient.cs, ApiException etc for each.
I do have the same issue. Used the following workaround:
Here is the ApiException code
{
/// <summary>
/// https://github.com/RicoSuter/NSwag/issues/2839
/// </summary>
public partial class [YourClassNameForNswagGenerateClient]
{
public partial class ApiException : System.Exception
{
public int StatusCode { get; private set; }
public string Response { get; private set; }
public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException)
: base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException)
{
StatusCode = statusCode;
Response = response;
Headers = headers;
}
public override string ToString()
{
return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.17.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class ApiException<TResult> : ApiException
{
public TResult Result { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException)
: base(message, statusCode, response, headers, innerException)
{
Result = result;
}
}
}
}
@RicoSuter Still no solution ????
@RyptHunterz Still no PR from you ????
I have added a lazy fix for this issue.
Currently I have a project that uses multiple openapi.json v3 files. We used the official openapi tools described in this link: https://docs.microsoft.com/en-us/aspnet/core/web-api/microsoft.dotnet-openapi?view=aspnetcore-3.1
Because of the following code the generated c# client do not compile:
Why did you make this design decision of not generating the Exception code for the remaining clients? The commented affirmation of only one item is not true.
I managed it to work by adding a
AdditionalNamespaceUsages
options but for me it feels like a hack.Below I added a sample of a csproj to reproduce the issue: