Breeze.js WebApi 2 Startup Issue - asp.net-web-api

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.

Related

Elmah logger not working in Web API with Simple Injector

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.

"The type TraceWriter must derive from ITraceWriter" after upgrading to Web API 2

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.

Why am I getting this ActivationException when using Simple Injector with WebApi Self Hosted in OWIN?

I have a very simple Web Api v2.2 self hosted in OWIN
public class StartUp
{
public void Configuration(IAppBuilder appBuilder, IConfigReader configReader)
{
var container = new Container();
container.Register<IConfigReader, ConfigReader>();
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
appBuilder.UseWebApi(config);
}
}
When I then use on my Main() as:
WebApp.Start(baseAddress, appBuilder =>
new StartUp().Configuration(appBuilder, new ConfigReader()));
However when I try to execute the last line appBuilder.UseWebApi(config); I get the following exception:
A first chance exception of type 'SimpleInjector.ActivationException'
occurred in SimpleInjector.dll
Additional information: The given type IHostBufferPolicySelector is
not a concrete type. Please use one of the other overloads to register
this type.
Complete Stack:
SimpleInjector.ActivationException occurred _HResult=-2146233088
_message=The given type IHostBufferPolicySelector is not a concrete type. Please use one of the other overloads to register this type.
HResult=-2146233088 IsTransient=false Message=The given type
IHostBufferPolicySelector is not a concrete type. Please use one of
the other overloads to register this type. Source=SimpleInjector
StackTrace:
at SimpleInjector.Advanced.DefaultConstructorResolutionBehavior.VerifyTypeIsConcrete(Type
implementationType) InnerException:
The problem is not that single interface it looks like SimpleInjector is trying to find a binding for Every Single Interface; If I provide a dummy implementation for IHostBufferPolicySelector it throws for some other interface e.g. IExceptionHandler etc.
There is a related thread HERE but I am not sure how it relates to SimpleInjector?
The Self host is a Console App which has the following packages installed:
Simple Injector ASP.NET Web API Integration v2.61
Simple Injector Execution Context Scoping v2.61
Simple Injector v2.61
OWIN v1.0
Microsoft.Owin v2.0.2
Microsoft.Owin.Hosting v2.0.2
Microsoft ASP.NET Web API 2.2 OWIN v5.2.2
Microsoft ASP.NET Web API 2.2 OWIN Self Host v5.2.2
According to Simple Injector:
The exceptions you are showing are 'first chance exceptions'. These
exceptions are thrown by Simple Injector but they are caught and
processed by Simple Injector and they won't bubble up the call stack.
It is possible that you see them in some debugger output window, but
they are quite normal and nothing to worry about.
It turned out that the exception only bubbles up when I have the Common Language Runtime Exceptions checked to thrown
When I untick the checkbox everything behaves as normal! which is weird! also wrapping it in a Try-Catch (Exception) doesn't even catch it which makes it even more interesting/werid!

Structuremap 207 error after deploying on IIS

we are developing an application using ASP.Net MVC 3.0 framework. we are using structuremap for injecting the objects at runtime. for this purpose we are using constructor injection. we have written custom controller factory, where the creation of controllers are delegated to this factory through return (Controller)ObjectFactory.GetInstance(controllerType);. Defined definition using DSL by mapping interfaces with the concrete classes.
Everything is working fine when the application is running on visual studio development server. But when the same application is deployed on the IIS 7.0, it is throwing 207 error while creating the objects at runtime.
could anyone help whether we need to update any settings on IIS or help the steps to debug this issue? Please find the below stack trace for the issue
ExceptionStructureMap Exception Code:
207 Internal exception while creating Instance '83248ea8-b195-4166-8a7d-678e9a677c9f' of PluginType Payrs.Web.Controllers.PaymentRequestController.
Check the inner exception for more details.Stack Trace :
at StructureMap.Pipeline.ConstructorInstance.Build(Type pluginType, BuildSession session, IInstanceBuilder builder)
at StructureMap.Pipeline.ConstructorInstance.build(Type pluginType, BuildSession session)
at StructureMap.Pipeline.Instance.createRawObject(Type pluginType, BuildSession session)
at StructureMap.Pipeline.Instance.Build(Type pluginType, BuildSession session)
at StructureMap.Pipeline.ObjectBuilder.Resolve(Type pluginType, Instance instance, BuildSession session)
at StructureMap.BuildSession.CreateInstance(Type pluginType, Instance instance)
at StructureMap.BuildSession.<>c__DisplayClass3.<.ctor>b__1()
at StructureMap.BuildSession.CreateInstance(Type pluginType)
at Payrs.Web.Infrastructure.PayrsControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
**Inner Exception**
at Payrs.Web.Controllers.PaymentRequestController..ctor(IPaymentService paymentRequestService, IFundingService fundingService)
at lambda_method(Closure , IArguments )
at StructureMap.Construction.BuilderCompiler.FuncCompiler`1.<>c__DisplayClass2.<CreateBuilder>b__0(IArguments args)
at StructureMap.Construction.InstanceBuilder.BuildInstance(IArguments args)
at StructureMap.Pipeline.ConstructorInstance.Build(Type pluginType, BuildSession session, IInstanceBuilder builder)
I could able to figure out the issue after troubleshooting through the structuremap code and the web server monitoring.
In this case, there is an unhand-led exception occurring, which is collapsing the current app domain and creating new app domain to process the request. As the entire structuremap configuration is done at app domain level, the container definition is nullifying, which is the reason the structure map is not able to inject the objects in constructor.
Elmah helped me in identifying the unhand-led exception, which by correcting the issue and handling the exceptions avoided this error.

The request lifetime scope cannot be created because the HttpContext is not available

Having a hard time trying to setup AutoFac with some async non httprequest.
I have the following on App_Start
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<sfEntities>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterGeneric(typeof(sfRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerHttpRequest();
builder.RegisterType<EmailServices>().As<IEmailServices>().InstancePerHttpRequest();
builder.RegisterType<UserServices>().As<IUserServices>().InstancePerHttpRequest();
builder.RegisterType<ChatServices>().As<IChatServices>().InstancePerHttpRequest();
builder.RegisterType<DefaultFormsAuthentication>();
builder.RegisterType<WebSecurity>();
builder.RegisterType<Chat>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls.
p.s.: UnitOfWork pass the EF DbContext between services to ensure that the same instance is used and to dispose properly. If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
The following code throws the following exception:
Timer timer = new Timer(new TimerCallback(OnTimer), null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
private static void OnTimer(object o)
{
using (var timerScope = AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope())
{
var chatServices = timerScope.Resolve<IChatServices>();
chatServices.MarkInactiveUsers();
}
}
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
On SignalR, the following code throws the following exception:
SignalR.GlobalHost.DependencyResolver.Register(typeof(Chat), () => new Chat(DependencyResolver.Current.GetService<IUnitOfWork>(), DependencyResolver.Current.GetService<IChatServices>(), DependencyResolver.Current.GetService<IUserServices>()));
The request lifetime scope cannot be created because the HttpContext is not available
Thanks in advance!
Having a hard time trying to setup AutoFac with some async non httprequest.
For non-http requests, or more specifically, for non-ASP.NET pipeline requests (like WCF or ServiceStack), you should definitely change all InstancePerHttpRequest() code to InstancePerLifetimeScope(). You can and should do this because InstancePerLifetimeScope() will make it resolvable in both ASP.NET pipeline and non-ASP.NET pipeline contexts.
If I change to InstancePerLifetimeScope() I get problems with UnitofWork.SaveChanges(). Setup this way works fine except for async calls... If I change to InstancePerLifetimeScope I was getting identity conflicts when calling .SaveChanges(), probably because there should be more than one instance of UnitOfWork.
Yes, there should be more than one instance of UnitOfWork, but you can achieve that with a single registration that should be scoped to InstancePerLifetimeScope():
Example:
builder.RegisterType<NhUnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
The IChatServices service is registered as InstancePerHttpRequest and will therefore only be available within the http request lifetime scope. You are resolving from the application scope which have no "access" to the current request and therefore fail with the error you mention. So yes, to get the timer to work you must register the service in the application scope.
Basically, you can have request scoped services that access application scoped services, but not the other way around.
Question is: what is UnitOfWork.SaveChanges do and what "problems" do you get? Please elaborate.

Resources