Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSwag not working with ASP.NET Web API 2 and OWIN. Just getting 404

I am trying to get NSwag setup on a new Web API project using OWIN with no luck. I am wondering if the docs aren't mentioning something or I've missed a step. I'm following the instructions from the Middlewares Wiki, but when I load the default swagger endpoint I just get a 404.

Is there something I need to do to generate the content that should be at that location? I've been assuming the middleware handles that.

Does NSwag require MVC to be a part of your project? Will it work in an app that is just Web API?

I've checked out the sample projects but neither of them use OWIN with ASP.NET Web API 2. There is only a global.asax example, and a .Net Core example.

You can easily reproduce my issue if you like. Simply create a new ASP.NET Web Application using the OWIN Web API Starter Template and then perform the setup from the Middlewares Wiki. (When you create a new project there's a link near the bottom of the Add New Project wizard: Click here to go online and find templates.. Click that and search for "OWIN Web API Starter Template".

Please let me know if I should provide more detail. Other than posting a bunch of code, that starter project should allow you to reproduce my issue in 5-10 minutes.

Thanks!

like image 850
mikesigs Avatar asked Dec 13 '16 21:12

mikesigs


1 Answers

Hope this helps, works for me:

  1. clone https://github.com/NSwag/Samples

  2. open solution, I used VS2015 update 3

  3. create a new Owin MVC project add new "ASP.Net web applation (.Net Framework)" project to solution; I called it: SampleOwinWebApiWithSwaggerUi ... use the default MVC project template (MVC checkbox is checked), also check the "Web API" checkbox. Change authentication, select no authentication, click OK. Right click the new project and select "Set as Startup Project"

  4. add nuget package ... right click the new SampleOwinWebApiWithSwaggerUi project, click Manage NuGet packages. Add this package: Microsoft.AspNet.WebApi.Owin (adds other dependencies including Owin + Microsoft.Owin + Microsoft.AspNet.WebApi.Owin for you too)

  5. add a web api controller ... I re-used the PersonController.cs and it's associated model Persons.cs from the SampleWebApiWithSwaggerUi project, added controller to a new folder ./api under ./Controllers and just updated namespaces and using statements from 'SampleWebApiWithSwaggerUi' to 'SampleOwinWebApiWithSwaggerUi'

  6. Added an Owin startup.cs file, right-click SampleOwinWebApiWithSwaggerUi project, add new, enter 'owin' in the search box, select OWIN Startup class, change the default name from Startup1.cs to Startup.cs, click Add

  7. Add 'NSwag.AspNet.Owin' NuGet package ... again this adds other packages and updates, as required.

  8. Add 'Microsoft.Owin.Host.SystemWeb' NuGet package

  9. update Startup.cs, adding the following lines:

    // from https://github.com/NSwag/NSwag/wiki/Middlewares
    var config = new HttpConfiguration(); app.UseSwaggerUi(typeof(Startup).Assembly, new SwaggerUiOwinSettings()); app.UseWebApi(config); config.MapHttpAttributeRoutes(); config.EnsureInitialized();

as you add these, you will need to add the following dependencies to usings:

using System.Web.Http;
using NSwag.AspNet.Owin;
  1. update web.config, section

I changed from

<system.webServer>
    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

to:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
        <clear />
        <add name="Owin" verb="" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        <add name="SwaggerIndex" path="swagger/index.html" verb="*" type="NSwag.AspNet.Owin.SwaggerUiIndexMiddleware" />
        <add name="SwaggerGenerator" path="swagger/v1/swagger.json" verb="*" type="NSwag.AspNet.Owin.SwaggerMiddleware" />
        <add name="SwaggerRedirect" path="swagger" verb="*" type="NSwag.AspNet.Owin.RedirectMiddleware" />
    </handlers>
</system.webServer>

NOTE: I did not follow advice here https://github.com/NSwag/NSwag/wiki/OwinGlobalAsax as this failed for me:

<appSettings>
    <add key="owin:AutomaticAppStartup" value="false" />
</appSettings>

since we do want the Owin startup.cs to load.

  1. At this point you should be able to use /swagger, web api data ok, however static files such as bootstrap.css are not served for MVC pages. To fix this I followed advice here: https://stackoverflow.com/a/36297940/445927 though I changed the physicalFileSystem root, as below. This additional code should be added to the end of startup.cs, after swagger additions noted above.

// to serve static files, see: https://stackoverflow.com/a/36297940/445927

string root = AppDomain.CurrentDomain.BaseDirectory;
//var physicalFileSystem = new PhysicalFileSystem(Path.Combine(root, "wwwroot"));
var physicalFileSystem = new PhysicalFileSystem(root));
var options = new FileServerOptions
{
    RequestPath = PathString.Empty,
    EnableDefaultFiles = true,
    FileSystem = physicalFileSystem
};
options.StaticFileOptions.FileSystem = physicalFileSystem;
options.StaticFileOptions.ServeUnknownFileTypes = false;
app.UseFileServer(options);

Finally you should have ASP.Net MVC (with static files), Web API and Swagger all working.

Update: Rico has now merged into main repo: https://github.com/NSwag/Samples

like image 78
Robert Dyball Avatar answered Sep 21 '22 12:09

Robert Dyball