I'm creating a WebApi application using MVC 4 which needs to support oData.
I installed the package Microsoft.AspNet.WebApi.OData (Install-Package Microsoft.AspNet.WebApi.OData -Pre) as recommended but when filtering [for example: /api/cars?$filter=startswith(Name,'F')] I'm getting the exception:
{"Message":"An error has occurred.","ExceptionMessage":"Method not found: 'Int32 Microsoft.Data.OData.Query.SemanticAst.QueryNode.get_Kind()'.","ExceptionType":"System.MissingMethodException","StackTrace":" at System.Web.Http.OData.Query.Validators.FilterQueryValidator.ValidateSingleValueNode(SingleValueNode node, ODataValidationSettings settings)\r\n at System.Web.Http.OData.Query.Validators.FilterQueryValidator.ValidateQueryNode(QueryNode node, ODataValidationSettings settings)\r\n at System.Web.Http.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\r\n at System.Web.Http.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\r\n at System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at System.Web.Http.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n at System.Web.Http.QueryableAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at System.Web.Http.QueryableAttribute.ExecuteQuery(IEnumerable query, HttpRequestMessage request, HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)\r\n at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)\r\n at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"}
What I'm missing?
There was a binary incompatibility with a version of the underlying OData library that caused this issue. I'd strongly recommend using our nightly builds. Just use this command instead in your package manager console:
Install-Package Microsoft.AspNet.WebApi.OData -Source http://www.myget.org/F/aspnetwebstacknightly/ -Pre
This will also get you a version of Web API OData support that's much closer to the final release bits.
Related
In an ASP.NET Web API project, if you are using Simple Injector for dependency injection, it will register all controllers with this line of code:
container.RegisterWebApiControllers(
System.Web.Http.GlobalConfiguration.Configuration);
If you have Elmah logger in the same project, to access the logger you just use http://yourapp.com/elmah as shown here.
The problem is that Simple Injector thinks elmah is a controller and produces this error:
No registration for type ElmahController could be found.
I thought to configure Simple Injector to avoid construction if the type has elmah but I cannot figure out how.
What do I need to do to fix this?
Here is the full error:
No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd.
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: SimpleInjector.ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd.
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:
[ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd. ]
SimpleInjector.Container.ThrowNotConstructableException(Type concreteType) +138
SimpleInjector.Container.ThrowMissingInstanceProducerException(Type type) +88
SimpleInjector.Container.GetInstanceForRootType(Type serviceType) +186
SimpleInjector.Container.GetInstance(Type serviceType) +82
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +64
[InvalidOperationException: An error occurred when trying to create a controller of type 'Elmah.Mvc.ElmahController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +245
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +267
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +77
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +970
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +75
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +158
Ok I think I figured it out.
Some Notes
Since I have configured the container's lifestyle like this:
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
I cannot use LifeStyle.Scoped when registering the ElmahController. The 2 other options are LifeStyle.Singleton and LifeStyle.Transient. We don't want LifeStyle.Singleton because numerous instances are needed, thus we have one option left which is LifeStyle.Transcient.
Solution
You need to register it with Simple Injector:
container.Register<Elmah.Mvc.ElmahController>(Lifestyle.Transient);
The line above will result in a different error:
The configuration is invalid. The following diagnostic warnings were reported:
-[Disposable Transient Component] ElmahController is registered as transient, but implements IDisposable.
To get rid of that error, I first checked to see if the Dispose method for ElmahController has anything useful. It turns out it simply derives from System.Web.Mvc.Controller and here is the Dispose method:
public void Dispose()
{
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
}
Since it does nothing useful, it is fine if it is not called. Thus the following code is enough:
container.GetRegistration(typeof(Elmah.Mvc.ElmahController)).Registration
.SuppressDiagnosticWarning(
DiagnosticType.DisposableTransientComponent,
"No need to call dispose because it does nothing useful.");
The RegisterWebApiControllers extension method uses ASP.NET Web API's IAssembliesResolver abstraction to get the list of assemblies to look for Controller instances.
Apparently the ElmahController lives in an assembly that is not returned by IAssembliesResolver.GetAssemblies(). To fix this you can do two things:
Call the RegisterWebApiControllers overload that accepts a list of Assembly instances and pass in the application assemblies that contain your controllers + the ELMAH assembly that contains your assembly
Customize Web API's controller discovery mechanism as described here
Especially the first solution is simpler compared to manually registering the controller, because under the covers RegisterWebApiControllers ensures the false-positive diagnostic warning for disposable components is suppressed.
We have a custom Web API ITraceWriter implementation named TraceWriter, registered as a service in the usual way in Application_Start.
After upgrading the Web API project to Web API 2, an HttpException is thrown in Application_Start:
The type TraceWriter must derive from ITraceWriter.
Parameter name: service
at System.Web.Http.Controllers.ServicesContainer.Replace(Type serviceType, Object service)
Of course, the TraceWriter actually is deriving from ITraceWriter, so what is the problem?
The TraceWriter implementation was located in a different project, which still referenced System.Web.Http, Version=4.0.0.0. Installing the latest Microsoft.AspNet.WebApi.Core package in this project solved the problem.
I'm trying to do basic setup with breeze.js server-side asp.net web api 2. I have the breeze route setup and the breeze-annotated web api controller. Calling into the Metadata action (or any action for that matter) is throwing this error below. It's nothing to do with lazy loading of navigational properties on my entity as far as I can tell.
This error seems to be a lazy type perhaps internal to the breeze data structure? I'm referencing Breeze.WebApi2 and Breeze.ContextProvider v1.4, along with Breeze.ContextProvider.EF6
I have disabled lazy loading explicitly on my db context per the breeze documentation.
dbContext.Configuration.LazyLoadingEnabled = false;
dbContext.Configuration.ProxyCreationEnabled = false;
Thanks.
ValueFactory attempted to access the Value property of this instance.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Lazy`1.get_Value()
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.GetControllerMapping() at System.Web.Http.Routing.AttributeRoutingMapper.AddRouteEntries(SubRouteCollection collector, HttpConfiguration configuration, IInlineConstraintResolver constraintResolver, IDirectRouteProvider directRouteProvider)
at System.Web.Http.Routing.AttributeRoutingMapper.<>c__DisplayClass2.<>c__DisplayClass4.<MapAttributeRoutes>b__1()
at System.Web.Http.Routing.RouteCollectionRoute.EnsureInitialized(Func`1 initializer)\r\n at System.Web.Http.Routing.AttributeRoutingMapper.<>c__DisplayClass2.<MapAttributeRoutes>b__0(HttpConfiguration config)
at System.Web.Http.HttpConfiguration.ApplyControllerSettings(HttpControllerSettings settings, HttpConfiguration configuration)
at System.Web.Http.Controllers.HttpControllerDescriptor.InvokeAttributesOnControllerType(HttpControllerDescriptor controllerDescriptor, Type type)
at System.Web.Http.Controllers.HttpControllerDescriptor.Initialize()
at System.Web.Http.Controllers.HttpControllerDescriptor..ctor(HttpConfiguration configuration, String controllerName, Type controllerType)
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.InitializeControllerInfoCache()\r\n at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Lazy`1.get_Value()
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}
It turned out to be something with the order in which the routes were being registered. I removed the webactivor.PreApplicationStartMethod() assembly directive added by the Breeze nuget install and manually called into the Breeze route configuration in Global.asax AFTER the standard web api routes where configured and it started working. Setting it before appears to cause the problem.
I am looking into resolviong Asp.net Webapi CORS issue with Thinktecture.Identitymodel as described in this URL
http://brockallen.com/2012/06/28/cors-support-in-webapi-mvc-and-iis-with-thinktecture-identitymodel/
I am using VS2012 with .Net 4.5
I am coming across a couple of problems here:
1) This is the error I am coming across when i make a request
Attempted to access an element as a type incompatible with the array
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.
System.ArrayTypeMismatchException: Attempted to access an element as a
type incompatible with the array.
[ArrayTypeMismatchException: Attempted to access an element as a type
incompatible with the array.]
System.Collections.Generic.List`1.Insert(Int32 index, T item) +62
Galaxy.CorsConfig.RegisterCors(HttpConfiguration config) +99
Galaxy.WebApiApplication.Application_Start() +377
[HttpException (0x80004005): Attempted to access an element as a type
incompatible with the array.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext
context, HttpApplication app) +12864673
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr
appContext, HttpContext context, MethodInfo[] handlers) +175
System.Web.HttpApplication.InitSpecial(HttpApplicationState state,
MethodInfo[] handlers, IntPtr appContext, HttpContext context) +304
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr
appContext, HttpContext context) +404
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr
appContext) +475
[HttpException (0x80004005): Attempted to access an element as a type
incompatible with the array.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +12881540
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)
+159 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest
wr, HttpContext context) +12722601
My application pool is pointing to Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929
2)My second question is after doing things as mentioned in WebApi. Do i still need to add HTTPmodule for IIS?
Its should be very easy to get going with this. I don't know what I am missing here.
Any pointers are highly appreciated.
Thanks.
I had a very similar issue because Thinktecture.IdentityModel.Web 1.4 pulled in HttpClient 0.6, which references System.Net.Http* v2.0 assemblies, but the HttpHanders list in MVC needs 4.0. Once I removed the Web pkg and its dependencies, things went back to working.
I figured out that I had a version mismatch of assemblies . My actual project was in .Net 4.0 and Thinktecture was in .Net 4.5 .
Once i fixed that it worked.
Similar to Ben's solution above, this problem occurred for me with v3.5.0 of Thinktecture.IdentityModel because of an old version of System.Net.Http (2.2.13.0) referenced in my web.config and installed in the bin folder.
Removing the dependentAssembly binding from my web.config and deleting the old System.Net.Http .dll solved the problem.
This was for a .NET 4.5 project.
I'm currently trying to deploy a MVC 3 application I've been working on to our test web server, and am running into a major problem with loading everything correctly. To try and give as much info about this as possible, I'm doing a bin deploy (I've sent all references to copy locally), and am doing a basic Publish on the web project via file system to the application directory on the server. The components I'm using are:
Entity Framework 4.3.1
Oracle ODAC 11.2.0 (version 4.112.3.0)
This application has 2 Entity Framework objects, one going to a SQL Server database and the other going to an Oracle 10g database. I believe the issue is with the Entity Framework object going to the Oracle database. This is my first MVC 3 project and my first deployment (there's a lot of "new" variables here), so I'm not sure if I'm missing anything or not. How do I fix this issue? Everything works perfectly fine on my local machine, it's only when I deploy the project to the server, that I have problems.
Things I've tried so far:
All of my controllers inherit from a base controller (BaseController), where the instances of the entity framework objects live. I cannot get to the Index view of any controller that inherits from the BaseController, but the HomeController inherits from Controller. This page works correctly. I've tried inheriting from Controller in the others, and that allows me to get to the Index view, but going back to BaseController causes the errors in the stack trace again. The error appears to happen on the line where I'm declaring my entity framework object going to the oracle database:
protected internal RadixWebDataPRDX dbRadixData = new RadixWebDataPRDX();
I have the Oracle.DataAccess.dll being copied over, and this still causes an issue.
My stack trace for this error is below, thanks:
Server Error in '/RadixMVC' Application.
Unable to find the requested .Net Framework Data Provider. It may not be installed.
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.ArgumentException: Unable to find the requested .Net Framework Data Provider. It may not be installed.
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:
[ArgumentException: Unable to find the requested .Net Framework Data Provider. It may not be installed.]
System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) +1420503
System.Data.EntityClient.EntityConnection.GetFactory(String providerString) +34
[ArgumentException: The specified store provider cannot be found in the configuration, or is not valid.]
System.Data.EntityClient.EntityConnection.GetFactory(String providerString) +63
System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString) +483
System.Data.EntityClient.EntityConnection..ctor(String connectionString) +77
System.Data.Objects.ObjectContext.CreateEntityConnection(String connectionString) +40
System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName) +17
RadixMVC.Models.Data.RadixWebDataPRDX..ctor() in C:\Users\862599\Documents\Visual Studio 2010\Projects\RadixMVC\RadixMVC\RadixMVC.Models.Data\RadixDataPRDX.Designer.cs:34
RadixMVC.Controllers.BaseController..ctor() in C:\Users\862599\Documents\Visual Studio 2010\Projects\RadixMVC\RadixMVC\RadixMVC\Controllers\BaseController.cs:17
RadixMVC.Controllers.AccountsPayableController..ctor() +29
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: An error occurred when trying to create a controller of type 'RadixMVC.Controllers.AccountsPayableController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +181
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +77
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +66
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +209
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +50
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +23
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8970356
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
The solution to this was what Bob said. The ODAC components had to be installed on the server as well (something I was unaware of). Thanks Bob!