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.
Related
I am working on mobilefirst 7.1 application which is deployed on websphere application server - network deployment.Earlier version this application is working on worklight 6.1 and everything is working fine.
As per code, we are setting an attribute in session within adapter and try to access it from java class (servlet) which is part of the application and exposed as servlet using configuration in web.xml file.
My worklight properties configuration :
mfp.session.independent=false
mfp.attrStore.type=HttpSession
My adapter code :
function myProcedure(XXX){
WL.Server.getClientRequest().getSession().setAttribute("myAtrrib", XXX);
return { result :"Success"};
}
Java Servlet Code :
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String crdAcc = (String) request.getSession(true).getAttribute("myAtrrib");
}
So Problem here is when I try to access this attribute it giving me null.
As I check the session detail and I found is that session is new session.
I don't know why server is creating new session for this servlet call instead of using same one which is used by mobilefirst adapter. Similar code is working with worklight 6.1.
In a previous question you've mentioned you're on a cluster, so could it be that in your server and/or load balancer, you did not enable the sticky session configuration? This may explain "new connections" happening and values not available.
When my WebAPI controller is called from a client, I run into the following errors:
ServiceLocatorImplBase.cs not found error
An exception of type 'Microsoft.Practices.ServiceLocation.ActivationException' occurred in Microsoft.Practices.ServiceLocation.dll but was not handled in user code
The WebAPI controllers use constructor injection to inject a repository dependency which should be resolved by StructureMap IoC. Interestingly, the same code runs fine on my another development machine. Here is my stack trace. Thanks for your help.
System.ArgumentNullException was unhandled by user code
HResult=-2147467261
Message=Value cannot be null.
Parameter name: httpContext
Source=System.Web
ParamName=httpContext
StackTrace:
at System.Web.HttpContextWrapper..ctor(HttpContext httpContext)
at WebApi2.DependencyResolution.StructureMapDependencyScope.get_HttpContext() in c:.........\WebApi2\DependencyResolution\StructureMapDependencyScope.cs:line 69
at WebApi2.DependencyResolution.StructureMapDependencyScope.get_CurrentNestedContainer() in c:.........\WebApi2\DependencyResolution\StructureMapDependencyScope.cs:line 55
at WebApi2.DependencyResolution.StructureMapDependencyScope.DisposeNestedContainer() in c:.........\WebApi2\DependencyResolution\StructureMapDependencyScope.cs:line 90
at WebApi2.DependencyResolution.StructureMapDependencyScope.Dispose() in c:.........\WebApi2\DependencyResolution\StructureMapDependencyScope.cs:line 85
at WebApi2.App_Start.StructuremapMvc.End() in c:.........\WebApi2\App_Start\StructuremapMvc.cs:line 44
Thanks for your reply. Both machines are running integrated mode. The error is really misleading and threw me off to a wrong track. I spent hours trying to find where this ServiceLocatorImplBase.cs resides. I happened to look into the deeply nested inner exceptions, and found that the inner most exception (5th level) complains some entities generated by POCO generator have no identity key. This is because I manually added the foreign key relationship among some entities with
public virtual RelatedEntity1 {get;set;}
public virtual RelatedEntity2 {get;set;}
without setting [key] attributes in the related entities. I am not sure if this can be fixed but the exception message should not lead people to the wrong track.
The problem you are running into is because you are attempting to resolve HttpContext at the point in time that the application is composed (typically done in the Application_Start event of Global.asax). HttpContext is part of the application's runtime state. It is null at the point in time when the application is being composed.
The reason why it seems to work in your development environment is likely because your development environment's application pool is running in classic mode. Most likely the other environments are (correctly) running in integrated mode. So, this is a design issue, not a problem with deployment as you might expect.
The solution is to use an Abstract Factory so you can defer instantiating of the HttpContextWrapper until runtime. Then you can inject the abstract factory rather than HttpContextWrapper into your services.
public interface IHttpContextFactory
{
HttpContextBase Create();
}
public class HttpContextFactory
: IHttpContextFactory
{
public HttpContextBase Create()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
See this answer and this answer for a complete examples including usage.
I am writing a service layer which uses Entity framework to get/set data from the database, and then pass it to an MVC web application. I am not able to decide what is the bext way to return database errors to the web application.
Should I throw an exception and the web application can handle it accordingly, or should I return a string/bool to convey that the database action has worked or not?
Any suggestion on what is the best practice?
Thanks
You can either not handle them in your service layer, or you can normalize them using an exception class that you will create. For example:
public class DatabaseException: Exception
{
public string TableName { get; private set; }
public DatabaseException(string tableName, Exception innerException)
:base("There a database error occured.", innerException)
{
TableName = tableName;
}
}
Simply add whatever information you require to the exception class as properties and initialize them in the constructor.
It's really not the best practice to inform the higher levels about exceptions with return values, since most of the methods are already returning some data.
You should not handle exception thrown out from web application, let exception thrown naturally, even from data access layer. With this way, it is easy for you for troubleshooting, esp in production stage. So, how to handle:
Use custom error page for exceptions thrown out.
Use HttpModule to log exception for troubleshooting. ELMAH, loggin module, works perfectly with ASP.NET MVC and alows you to view logs on web.
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.
this question Ninject Dependency Injection in MVC3 - Outside of a Controller is close to what I'm experiencing, but not quite.
I have an ASP.NET MVC3 site using Ninject 3 and it works wonderfully with constructor injection. All my dependencies are resolved, including those that pass in HttpContext.Current.
My issue is that in global.asax, I kick off a TaskManager class that periodically performs some tasks on a timer. Inside the TaskManager class, I don't have controllers, so if I need access to one of my dependencies (like my error logging service), I use a static wrapper class that has access to the kernel object:
var logger = MyContainer.Get<ILoggingService>();
logger.Error("error doing something...", ex);
The .Get method simply performs a kernel.Get call resolve my dependency. Works great every time I use this method on my other dependencies. However, ILoggingService has a dependency called MyWebHelper that is injected via it's constructor and includes HttpContext in it's constructor.
public class DefaultLogger : ILoggingService
{
public DefaultLogger(IRepository<Log> logRepository, IWebHelper webHelper)
{
_logRepository = logRepository;
_webHelper = webHelper;
}
}
public class MyWebHelper : IWebHelper
{
public MyWebHelper(HttpContext httpContext)
{
_httpContext = httpContext;
}
}
In the rest of my web site, this all works just fine because all the dependencies are injected into my MVC controllers. But what doesn't work is if I manually call my static wrapper class to get my dependencies that way. I get the error:
Error activating HttpContext using binding from HttpContext to method
Provider returned null.
So, it's not giving me an HttpContext like it does throughout the rest of my MVC application. I hope this makes sense, I'm not a ninject expert yet, but I'm trying...
My issue is that in global.asax, I kick off a TaskManager class that
periodically performs some tasks on a timer.
That's a bad idea as Phil Haack explains in details. Don't do this in your web application. Those recurring tasks should be done in a separate application (Windows Service or some console application which is scheduled to run at regular intervals).
Now the thing is that you are running background threads. Those background threads run outside of any user HTTP request and as a consequence HttpContext.Current is obviously null inside them. So even if you don't follow Phil Haack's advice and continue running background tasks in your ASP.NET application you will have to rearchitecture your method so that it no longer depends on any HttpContext because there's no such thing in those background threads.