Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Misleading MissingMethodException message for incorrect routes #4991

Closed
mafshin opened this issue Jul 9, 2016 · 2 comments
Closed

Misleading MissingMethodException message for incorrect routes #4991

mafshin opened this issue Jul 9, 2016 · 2 comments
Assignees

Comments

@mafshin
Copy link

mafshin commented Jul 9, 2016

Having an incorrect route for action methods will throw misleading exception message.

Steps to reproduce:

  • Create a new ASP.NET Core web project with WebAPI template
  • Run the app the and ValuesController will work as excpected
  • Add a regex(\\d+)' constraint to theidparameter of theValuesController.Get` method
  • Run the app and it works just as expected
  • Mistakenly add an incorrect route config like the below one (consider the extra double colon after regex)
        [HttpGet("{id:regex:(\\d+)}")]
        public string Get(int id)
        {
            return $"The content for document #{id}";
        }
  • Run the app again and you will see the following misleading exception:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 DEBUG http://localhost:13367/  0
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:13367/api/values  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 93.9806ms 200 
Microsoft.AspNetCore.Server.Kestrel:Error: Connection id "0HKT7OA7R93TP": An unhandled exception was thrown by the application.

System.MissingMethodException: No parameterless constructor defined for this object.
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at Microsoft.AspNetCore.Routing.DefaultInlineConstraintResolver.CreateConstraint(Type constraintType, String argumentString)
   at Microsoft.AspNetCore.Routing.DefaultInlineConstraintResolver.ResolveConstraint(String inlineConstraint)
   at Microsoft.AspNetCore.Routing.RouteConstraintBuilder.AddResolvedConstraint(String key, String constraintText)
   at Microsoft.AspNetCore.Routing.Tree.TreeRouteBuilder.MapOutbound(IRouter handler, RouteTemplate routeTemplate, RouteValueDictionary requiredLinkValues, String routeName, Int32 order)
   at Microsoft.AspNetCore.Mvc.Internal.AttributeRoute.AddEntries(TreeRouteBuilder builder, ActionDescriptorCollection actions)
   at Microsoft.AspNetCore.Mvc.Internal.AttributeRoute.GetTreeRouter()
   at Microsoft.AspNetCore.Mvc.Internal.AttributeRoute.RouteAsync(RouteContext context)
   at Microsoft.AspNetCore.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.<Invoke>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.<RequestProcessingAsync>d__2.MoveNext()
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 295.4269ms 200 

project.json

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "Areas/**/Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Expected Behavior

  • Ideal: To have a design time route config checking
  • Normal: To have an exception message like this:
    An unhandled exception was thrown while constructing the route config for ValuesController.Get method. No parameterless constructor defined for regex:

At first I thought the problem was with my models so I commented here in DI repo.

@rynowak
Copy link
Member

rynowak commented Jul 10, 2016

I'm not really sure what's up with the RegexRouteConstraint that's causing this issue.

In general though we should try to surface this error in a better way. We did a lot of work to collect most of the errors that can be thrown from attribute routing into a single group so that you can see all of the errors at once and not just the first one. It looks like we missed the case where a constraint throws.

@danroth27
Copy link
Member

We should throw an exception with a better error message.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants