Tez Wingfield
Tez Wingfield

Reputation: 2251

XML comments file could not be found - Swagger

This is certainly one of those that drives you nuts. As the title indicates all I'm simply trying to do is display comments pulled from an xml file using swagger.

I appear to have taken all steps according to the swagger documentation but to no avail. Hopefully you kind folk can point me in the right direction.

Steps Taken: enter image description here

Ensured file exists:

enter image description here

Configured SwaggerConfig.cs

enter image description here

I've tried changing the path too: @"bin/....xml"

Nothing seems to work.

**The Error "Could not find file": **

enter image description here

Can anyone point me in the right direction please?

Regards,

Upvotes: 57

Views: 71116

Answers (11)

Narish
Narish

Reputation: 760

This answer is being added for .NET Framework specifically, as the majority of the documentation seems to be for Core. I have done this on 4.6.2 specifically

Using the Core MS docs as a point of reference

  1. You want to source Swashbuckle from Nuget. You do not need to get anything else, as Gen and UI are embedded into the framework version of the nuget package. For the Core version, there are 3 seperate packages
  2. Build the solution, verify that ~/App_Start/SwaggerConfig.cs has been added to your solution. Customize as needed. We will deal with the XML comments line later on

Note: the following may be possible entirely using the project's "Properties" UI, I don't know, but this was my process

  1. Unload the web api startup project -> Open the .csproj file
  2. At the bottom of <PropertyGroup>, add two things <GenerateDocumentationFile>true</GenerateDocumentationFile> & <NoWarn>$(NoWarn);1591</NoWarn>. This will allow the XML documentation resource to be generated, and suppresses a warning that may now plague your project because you didn't document things like members
  3. Reload the project, open up the project properties UI
  4. Go into "Build" -> for your desired configuration, you want to check "XML Documentation file". This will default to ~\bin\MyProj.xml as the directory for it, so the next step will assume that path
  5. Go back into SwaggerConfig.cs. Look for the line beginning with c.IncludeXmlComments(). This is what you want to add, again, assuming you kept the default generated XML path
string xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "bin", xmlFilename));
  1. Save, run your project locally or publish to your dev environment, and navigate to https://localhost:xxxxx/swagger (local run, default) or whatever custom path you may have setup on your own
  2. Verify that Swagger is up and running for the solution. You should not be seeing any ASP.NET style error pages or anything of that sort
  3. Now go into your controllers, and begin to write your documentation. The Get Started link I included at the beginning of this post will have examples of what types of XML elements you can include in your docstrings. This will be generated into that XML file, which is the resource that swagger uses to generate the views with your documentation

I have not attempted any frontend customization of the generated swagger pages, so I am unsure if doing that will complicate this procedure at all. This presumes you just want the stock "look" of it. If in doubt, follow this through to the end and verify that its working, and then you can figure out about adding custom styles to it

Upvotes: 3

Raghubir Singh
Raghubir Singh

Reputation: 227

You will get this file by enabling option under project properties. Just right click on project->properties->Build->Output-> select 'Generate a file containing API documentation'. Refer the option on below given screenshot. This option is available for all .net core versions. Hope this would help someone.

enter image description here

var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);

Upvotes: 3

Kasun Asela
Kasun Asela

Reputation: 53

I found below solution from Microsoft Document site. Right-click the project in Solution Explorer and select Edit <project_name>.csproj. Manually add the highlighted lines to the .csproj file:

<PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Upvotes: 5

Jpsy
Jpsy

Reputation: 20862

These are the steps I needed in .Net Core 2.2:

Put this in Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {

        ...

        // Register the Swagger generator, defining 1 or more Swagger documents
        services.AddSwaggerGen(c =>
            {
                ...

                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            });
    }

Edit your .csproj file and add / change these nodes:

  <PropertyGroup>
    ...
    <!-- 
    Make sure documentation XML is also included when publishing (not only when testing)
    see https://github.com/Azure/service-fabric-issues/issues/190
    -->
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    ...
    <DocumentationFile>bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
  </PropertyGroup>

Upvotes: 51

Altaf
Altaf

Reputation: 319

May be I am little late but would like to share my fixes, I opened the .csproj file in Notepad++ and removed all the comments (), saved the file and opened the solution again, a (if your solution has more then one projects, do with all .csproj files)

Upvotes: 0

Chev Paredes
Chev Paredes

Reputation: 771

As indicated by the exception, the application looks for the XML in the base directory of the project, not in the "bin" folder.

Why does the app search in the base directory? Look at these lines:

var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".XML";//"G2F.Collective.Api.XML"
var commentsFile = Path.Combine(baseDirectory, commentsFileName);

The name of the comment file is configured with the combination of the base directory and the xml with the name of the project

c.IncludeXmlComments(commentsFile);

Finally, this instruction tells Swagger which file to use to take the comments, it is the real reason why it looks for that file in that directory.

So what is indicated in this last instruction must be according to what is configured in the Build tab of the project configuration. swagger_net_core

Upvotes: 32

Akin_Glen
Akin_Glen

Reputation: 767

I just wanted to put an answer to this question to further explain why those codes didn't work for Tez (and didn't work for me either).

The code in question is:

var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

For this to work, your swagger documentation configuration must be written in the "startup.cs" or in a .cs file within the same project as the controller.

Also, you must ensure that your XML file is being generated. So, right-click on your project, go to properties, go to build, scroll down to the "output" section, and check the "XML documentation file" option. (These steps are for Visual Studio 2019).

XML files are usually named "your-project-name".xml by default.

$"{Assembly.GetExecutingAssembly().GetName().Name}.xml"

Thus, this line of code ensures that the name of the xml file in your swagger configuration will be: "your-project-name".xml, where your controller documentation sits.

In my case, I had my swagger configuration in an extension method in class library, so that line of code produced the xml file name: "class-library-project-name".xml, when it should have been "controller-resident-project-name".xml.

The solution, like Tez suggested, is to manually set the XML file name, since you already know what it is.

Another solution would be to configure swagger in the startup.cs, which is usually in the same project as your controllers.

Hope this helps.

Upvotes: 1

mosess
mosess

Reputation: 1163

in .net core 3.0

<GenerateDocumentationFile>true</GenerateDocumentationFile>

in PropertyGroup tag of .csproj file

Upvotes: 96

Mike Gledhill
Mike Gledhill

Reputation: 29171

Using .Net Core 2, here's the lines I needed:

var pathIncludeXmlComments = $@"{env.ContentRootPath}\Events.xml";

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info { Title = "Events API", Version = "v0.1" });
    c.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
    c.IncludeXmlComments(pathIncludeXmlComments);
});

If you're having problems, put a breakpoint after that first line, check the value of "pathIncludeXmlComments", and confirm that VS2017 has stored an .xml file there.

And remember that under Project Properties, in the "Build" tab, you need to tick the "XML documentation file" box, and set the name to the same as shown in the filename above (Events.xml, in this example).

Upvotes: 3

Bruno Jesus Santos
Bruno Jesus Santos

Reputation: 79

Make sure that the project properties in the XML Generate configuration match the XML name of your swagger configuration file. Follow print's to facilitate understanding

Project Properties

swagger configuration

Upvotes: 8

Tez Wingfield
Tez Wingfield

Reputation: 2251

Ok, So I managed to get it to work by pointing to the root directory.

I still have no idea why it cannot detect the xml file in the bin directory. Again this worked by adding an xml file within the root.

Code Changes:

var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
                        //var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".XML";
                        var commentsFileName = "Comments" + ".XML";
                        var commentsFile = Path.Combine(baseDirectory, commentsFileName);

                        c.IncludeXmlComments(commentsFile);

Upvotes: 5

Related Questions