domaindrivendev / Swashbuckle.WebApi

Seamlessly adds a swagger to WebApi projects!
BSD 3-Clause "New" or "Revised" License
3.07k stars 677 forks source link

Swashbuckle.Core - Method MapHttpRoute not found #784

Open markus-bergendahl opened 8 years ago

markus-bergendahl commented 8 years ago

I've installed Swashbuckle 5.3.2. in my ASP .NET Web API 5.3.2. project. When trying to enable Swagger using the following code

GlobalConfiguration.Configuration.EnableSwagger(c => { c.OperationFilter<ExamplesOperationFilter>(); }).EnableSwaggerUi();

I get the following MissingMethodException

"An exception of type 'System.MissingMethodException' occurred in Swashbuckle.Core.dll but was not handled in user code

Additional information: Method not found: 'System.Web.Http.Routing.IHttpRoute System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute(System.Web.Http.HttpRouteCollection, System.String, System.String, System.Object, System.Object, System.Net.Http.HttpMessageHandler)'."

I'm not able to find a solution to this specific problem. Any ideas?

markshiffer commented 8 years ago

Same issue here. I upgraded an existing project and I am getting the same error. Have to think there is a dll version mismatch happening, but yet to identify it.

markus-bergendahl commented 8 years ago

I got it working by uninstalling Swashbuckle 5.3.2 and installing Swashbuckle.Net45 (version 5.2.1) instead. You might also have to clean your solution and delete your Debug and Release folders to make sure you get rid of all the Swashbuckle 5.3.2 stuff before installing Swashbuckle.Net45.

PoulNielsen commented 8 years ago

@markus-bergendahl & @markshiffer , Same issue here, Swashbuckle 5.4.0 and AspNet.WebApi 5.2.3. Seems like @markshiffer is right, seems like dll version issue. I fixed it, by added following to my web.config under /configuration/runtime/assemblyBinding/ :

    <dependentAssembly>
        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
    </dependentAssembly>
rudyscoggins commented 6 years ago

Thanks PoulNielsen! That did the trick for me.

SergeySagan commented 6 years ago

This is still an issue with apps deployed to Azure. We are using Swashbuckle.Core 5.6.0, System.Net.Http 4.3.3, Microsoft.AspNet.WebApi.Client 5.2.6, ASP.NET 4.7.2:

  <system.web>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2" />
    <httpModules />
  </system.web>

We have this binding:

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.4.0" newVersion="5.2.4.0" />
      </dependentAssembly>
    </assemblyBinding>

The strange thing is that it IS working when running locally, just not when deployed to Azure as an App Service.

The error is pointing to our Swagger Config as the source of the problem:

    public class SwaggerConfig
    {
        public static void Register()
        {
            var thisAssembly = typeof(SwaggerConfig).Assembly;

            GlobalConfiguration.Configuration
                .EnableSwagger(c =>
                    {
                        c.ApplyFiltersToAllSchemas();
                        c.SchemaFilter<GroupedSchemaFilter>();
                        c.OperationFilter<RoutePropertyNameOperationFilter>();
                        c.OperationFilter<SwashbuckleOperationFilter>();
                        c.SchemaId(type =>
                        {
                            string name = $"{type.Name}DTO";
                            if (type.GetTypeInfo().IsInterface && name.StartsWith("I"))
                                name = name.Substring(1);
                            return name;
                        });
                        c.SingleApiVersion("v1", "My.Service");
                    })
                .EnableSwaggerUi();
        }
    }

Exception in Full:

Method not found: 'System.Web.Http.Routing.IHttpRoute System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute(System.Web.Http.HttpRouteCollection, System.String, System.String, System.Object, System.Object, System.Net.Http.HttpMessageHandler)'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: Method not found: 'System.Web.Http.Routing.IHttpRoute System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute(System.Web.Http.HttpRouteCollection, System.String, System.String, System.Object, System.Object, System.Net.Http.HttpMessageHandler)'.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 

[MissingMethodException: Method not found: 'System.Web.Http.Routing.IHttpRoute System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute(System.Web.Http.HttpRouteCollection, System.String, System.String, System.Object, System.Object, System.Net.Http.HttpMessageHandler)'.]
   Swashbuckle.Application.HttpConfigurationExtensions.EnableSwagger(HttpConfiguration httpConfig, String routeTemplate, Action`1 configure) +0
   Swashbuckle.Application.HttpConfigurationExtensions.EnableSwagger(HttpConfiguration httpConfig, Action`1 configure) +17
   My.Service.SwaggerConfig.Register() in D:\a\1\s\src\My.Service\App_Start\SwaggerConfig.cs:23

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +92
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +190
   WebActivatorEx.BaseActivationMethodAttribute.InvokeMethod() +73
   WebActivatorEx.ActivationManager.RunActivationMethods(Boolean designerMode) +639
   WebActivatorEx.ActivationManager.Run() +84

[InvalidOperationException: The pre-application start initialization method Run on type WebActivatorEx.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
   System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 methods, Func`1 setHostingEnvironmentCultures) +617
   System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) +138
   System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded) +163
   System.Web.Compilation.BuildManager.ExecutePreAppStart() +156
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +695

[HttpException (0x80004005): The pre-application start initialization method Run on type WebActivatorEx.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +660
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +90
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +189
ccrego commented 6 years ago

Same problem here

ccrego commented 6 years ago

In order to sort out the issue, was necessary to replace the following binding redirect:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.2.0.0" />
      </dependentAssembly>
</assemblyBinding>

By the next one:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
      </dependentAssembly>
</assemblyBinding>