aspnet / AspNetWebStack

ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core)
Other
858 stars 354 forks source link

CORS OPTIONS support requires parameterless controller constructor? #289

Closed MihaMarkic closed 4 years ago

MihaMarkic commented 4 years ago

I have enabled OPTIONS verb for supporting preflight CORS checks, like this:

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

It seems working, but only if controller in question has a parameterless constructor (see the error message below). Shouldn't it work with DI as well?

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.",
    "ExceptionType": "System.InvalidOperationException",
    "StackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Cors.AttributeBasedPolicyProviderFactory.SelectAction(HttpRequestMessage request, IHttpRouteData routeData, HttpConfiguration config)\r\n   at System.Web.Http.Cors.AttributeBasedPolicyProviderFactory.GetCorsPolicyProvider(HttpRequestMessage request)\r\n   at System.Web.Http.Cors.CorsMessageHandler.<GetCorsPolicyAsync>d__8.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Cors.CorsMessageHandler.<HandleCorsPreflightRequestAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Cors.CorsMessageHandler.<SendAsync>d__4.MoveNext()",
    "InnerException": {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Type 'XMLServer.Controllers.Api.MyController' does not have a default constructor",
        "ExceptionType": "System.ArgumentException",
        "StackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
    }
}
dougbu commented 4 years ago

Shouldn't it work with DI as well?

MVC 5.2.7 controllers must have a parameterless constructor. This is by design.

dougbu commented 4 years ago

Thank you for your feedback. We're closing this issue as the behaviour discussed is by design.

MihaMarkic commented 4 years ago

@dougbu Why does it need to create a controller instance anyway? Can just reflect over it?