ASP.NET Core Web API (OpenAPI) Client issue with NSwag toolchain

Paul Redman 0 Reputation points
2023-04-18T11:20:52.07+00:00

Hi, I wonder if you can help. I'm using VS 2022 and trying to create a client to consume a Web API with open API. Essentially I'm using this older .NET 5.0 explanation - https://www.davidhayden.me/blog/generate-client-for-asp-net-core-web-api-using-openapi As soon as I add the Connected Service - OpenAPI Service Reference, the OpenAPI classes are automatically produced with the NSwag toolchain. As soon as that happens the auto-generated code then flags an error:- error CS0234: The type or namespace name 'EnumMemberAttribute' does not exist in the namespace 'System.Runtime.Serialization' (are you missing an assembly reference?) Specifically :

var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) 
                            as System.Runtime.Serialization.EnumMemberAttribute;

Looking on MS seems to suggest that EnumMemberAttribute is indeed part of Serialization - https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.enummemberattribute?view=net-6.0 As I say, this code is automatically generated so I don't understand why the VS22 IDE would flag this? Any ideas appreciated.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,232 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,363 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,036 Reputation points Microsoft Vendor
    2023-04-20T06:44:38.4866667+00:00

    Hi @Paul redman

    As soon as that happens the auto-generated code then flags an error:- error CS0234: The type or namespace name 'EnumMemberAttribute' does not exist in the namespace 'System.Runtime.Serialization' (are you missing an assembly reference?)

    For this issue, it seems that you are missing the namespace reference. Try to install or re-install the relates package.
    Besides, whether your application is an Asp.net 5, 6 or 7 MVC application?

    I'm using VS 2022 and trying to create a client to consume a Web API with open API. Essentially I'm using this older .NET 5.0 explanation - https://www.davidhayden.me/blog/generate-client-for-asp-net-core-web-api-using-openapi As soon as I add the Connected Service - OpenAPI Service Reference, the OpenAPI classes are automatically produced with the NSwag toolchain.

    According to the tutorial, I tried to create an Asp.net 5 and 6 MVC application using VS 2022 Community (64-bit) 17.5.2 version, the code works well on my side.
    So, I suggest you could refer to the following steps to test again.
    Using NSwag 1.Create an API application using the Asp.net Core Web API template.
    Note: Don't select the "Enable OpenAPI support" option,
    User's image

    2.Add the NSwag.AspNetCore package via NuGet.
    3.In the Program.cs file, register the NSwag middleware and services.

            var builder = WebApplication.CreateBuilder(args);
    
            // Add services to the container.
    
            builder.Services.AddControllers();
            // Register the Swagger services
            //builder.Services.AddSwaggerDocument();
    
            builder.Services.AddSwaggerDocument(config =>
            {
                config.PostProcess = document =>
                {
                    document.Info.Version = "v1";
                    document.Info.Title = "Nswag API";
                    document.Info.Description = "A simple ASP.NET Core web API";
                    document.Info.TermsOfService = "None";
                    document.Info.Contact = new NSwag.OpenApiContact
                    {
                        Name = "Shayne Boyer",
                        Email = string.Empty,
                        Url = "https://twitter.com/spboyer"
                    };
                    document.Info.License = new NSwag.OpenApiLicense
                    {
                        Name = "Use under LICX",
                        Url = "https://example.com/license"
                    };
                };
            });
    
            var app = builder.Build();
    
            // Configure the HTTP request pipeline.
    
            app.UseHttpsRedirection();
    
            app.UseAuthorization();
            // Register the Swagger generator and the Swagger UI middlewares
    
            app.UseOpenApi();
            app.UseSwaggerUi3();
    
            app.MapControllers();
    
            app.Run();
    
    

    User's image

    4.In the launchSettings.json file (in the Properties folder), set the launchUrl to show the swagger ui when the application start.

      "profiles": {
        "NswagAPI": {
          "commandName": "Project",
          "dotnetRunMessages": true,
          "launchBrowser": true,
          "launchUrl": "swagger",
          "applicationUrl": "https://localhost:7050;http://localhost:5164",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
    

    5.The API controller as below:
    User's image

    6.Running the API application, you can see the swagger.json file.
    7. In the same solution, create a Console application, and add a swagger.json file, and paste the swagger.json content from the API swagger UI.
    8.Right click the Console application, then click "Add" => "Connected Services" => "Add new API service reference" => "OpenAPI", in the popup window, select the swagger.json file, and provide the namespace and class name for the generated code:
    User's image

    9.Right click the Console application, select "Open Folder and File Explorer", in the root folder, remove the bin and obj folder. After that rebuild the Console application.
    10.In the Console application program.cs file, use the following code to call the API service:

            using NswagAPIService;
    
            namespace NswagConsole
            {
                internal class Program
                {
                    static async Task Main(string[] args)
                    {
                        Console.WriteLine("Hello, World!");
    
                        var httpClient = new HttpClient();
                        httpClient.BaseAddress = new Uri("https://localhost:7050");
                        var client = new NswagAPIClient(httpClient);
                        var forecast = await client.GetAsync();
    
                        foreach (var item in forecast)
                        {
                            Console.WriteLine($"{item.Summary}");
                        }
                        Console.ReadKey();
                    }
                }
            }
    
    1. Right click the Solution, click the Properties option, set the startup, make sure the API project start before the console application.
      User's image

    The result as below:
    User's image

    Using Swashbuckle swagger.
    1.Create an API application using the Asp.net Core Web API template.
    Note: Select the "Enable OpenAPI support" option. Then, it will enable swagger using the Swashbuckle.
    User's image

    2.After that, the API application contains the controller as below:
    User's image

    3.Running the API application, the swagger UI looks as below: click the swagger.json file and copy the json content.
    User's image

    4.In the same solution, create a console application, and then add a swagger.json file, and paste the previous copied json content.
    User's image

    5.Right click the console application, then click "Add" => "Connected Services" => "Add new API service reference" => "OpenAPI", in the popup window, select the swagger.json file, and provide the namespace and class name for the generated code:
    User's image

    1. Right click the Console application, select "Open Folder and File Explorer", in the root folder, remove the bin and obj folder. After that rebuild the Console application.
    2. In the Console application Program.cs file, add the SwashbuckleAPIServices service and call the relates method:
    using SwashbuckleAPIServices;
    
    namespace SwashbuckleConsole
    {
        internal class Program
        {
            static async Task Main(string[] args)
            {
                Console.WriteLine("Hello, World!");
    
                var httpClient = new HttpClient(); 
                var client = new SwashbuckleAPIClient("https://localhost:7214",httpClient);
                var forecast = await client.GetWeatherForecastAsync();
    
                foreach (var item in forecast)
                {
                    Console.WriteLine($"{item.Summary}");
                }
                Console.ReadKey();
            }
        }
    }
    

    8.Right click the Solution, click the Properties option, set the startup, make sure the API project start before the console application.
    User's image

    After that, the result as below:
    User's image

    Both the above methods work well on my side, the difference between them, you can check the program.cs code in the console application, using the Swashbuckle, we can call the API method via the GetWeatherForecastAsync, but in the NSwag application, we can call the API method via the GetAsync method. It relates the swagger.json file operationId property.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
    Best regards,
    Dillion

    0 comments No comments