How does the Ihttphandler interface expose the httpcontext object - httpcontext

Hello I see on msnd that anything that inherits from the Ihttphandler interface has access to a httpcontext object (under the remarks section of the page in below link)
msdn HTTPContext
My question is how does the interface expose this object...I don't see any property of type httpcontext in the interface. I do see the "ProcessRequest" method that is taking in an httpcontext object. But i'm not seeing how that is resulting in the httpcontext object being exsposed directly from the interface as the msnd page says.
Forgive me if i'm missing a key concept here, fairly new to this. Thanks

No, it is passed into the ProcessContext method only. The handler then interacts with that HttpContext instance as it's the context for the request. You can pass around the context instance to various other methods and such as much as you would like.
Why it is done this way becomes more clear if you look at the documentation about the IsReusable property. When that property is true, multiple requests can be served by the same handler instance, and thus they must be supplied a separate HttpContext to work.
Now, if you specify IsReusable as false, you can then store the HttpContext instance from ProcessRequest in a property on the instance. Not sharing the handler can cause performance issues under some scenarios, but you likely won't need to worry about that.

Related

User scoped dependencies in a custom ASP.NET Core Action Filter?

According to the official documentation here:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#authorization-filters
To implement a custom ActionFilter in ASP.NET Core I have three choices:
SeviceFilterAttribute
TypeFilterAttribute
IFilterFactory
But for all three it is stated that:
Shouldn't be used with a filter that depends on services with a lifetime other than singleton.
So how can I inject scoped services in my custom ActionFilter? I can easily get a scoped service from the current HttpContext like this:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
ISubscriptionHelper subscriptionHelper =
actionContext.HttpContext.RequestServices
.GetRequiredService<ISubscriptionHelper>();
}
But then I am wondering if I am doing something wrong? What is the correct way to depend on scoped services in a custom ActionFilterAttribute?
Resolving services from the HttpContext.RequestServices will correctly resolve scoped and transient instances without causing any problems such as Captive Dependencies. In case resolved components implement IDisposable, they will be disposed of when the request ends. ASP.NET Core passes on the current HttpContext object to filter's OnActionExecuting method and that HttpContext gives access to the DI Container.
This is completely different from injecting those services into the constructor, because the action filter will be cached for the lifetime of the application. Any dependencies stored in private fields will, therefore, live as long as that filter. This leads to the so called Captive Dependency problem.
Code that accesses the DI Container (the HttpContext.RequestServices is your gateway into the DI Container) should be centralized in the infrastructure code of the startup path of the application—the so called Composition Root. Accessing your DI Container outside the Composition Root inevitably leads to the Service Locator anti-pattern—this should not be taken lightly.
To prevent this, it is advised to keep the amount of code inside the action filter as small as possible and implement the filter as a Humble Object. This means that preferably, the only line of code inside the filter is the following:
actionContext.HttpContext.RequestServices
.GetRequiredService<ISomeService>() // resolve service
.DoSomeOperation(); // delegate work to service
This means all (application) logic is moved to the ISomeService implementation, allowing the action filter to become a Humble Object.

Transient Lifestyle requires HttpContext?

I am registering my component like this:
public static void Register(IWindsorContainer container)
{
container.Register(Classes.FromAssembly(Assembly.GetAssembly(typeof(GenericBaseRepository)))
.InSameNamespaceAs<GenericBaseRepository>()
.WithService.DefaultInterfaces()
.LifestyleTransient());
}
I am then resolving it in a piece of code that has no HttpContext:
var baseRepository = ContainerManager.Container.Resolve<IBaseRepository>();
(IBaseRepository being an interface implemented by GenericBaseRepository). This fails with the following message:
"HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net"
Which confuses me, because the lifestyle I choose is Transient, not PerWebRequest.
Of course, HttpContext doesn't exist during a scheduled task - but I don't really need it, I just want an instance of my Repository which will not interact with any web request.
So, why does Castle Windsor insist in requiring an HttpContext when resolving my component?
Have a look at the full exception message. Your root component may be transient but the exception indicates one of its dependencies uses per web request lifestyle.
Have a look at Windsor's diagnostics debugger view, that may help you pinpoint it.

How to set a boolean property in NServiceBus MessageHandler through EndPointConfig

I want to set a value to a public boolean property in my NServicebus message handler through EndPoint config.
One way which I know is by creating
An interface with that boolean property.
A concrete class inherited from the interface.
Initializing / Setting the value in that concrete class.
Injecting the concrete class through End-point config.
Is there any other way to achieve this.
Configure.Instance.Configurer
.ConfigureProperty<YourHandlerType>(h => h.BoolProperty,
Bool.Parse(ConfigurationManager.AppSettings["YourSetting"]));
In future versions, this will be even easier.
Edit:
You can try registering late with IWantToRunBeforeConfigurationIsFinalized, as suggested by David.
You can also register the component early. Since NServiceBus registers handlers as DependencyLifecycle.InstancePerUnitOfWork, your code should be doing the same
Configure.Component<YourHandlerType>(DependencyLifecycle.InstancePerUnitOfWork)
.ConfigureProperty(h => h.BoolProperty,
Bool.Parse(ConfigurationManager.AppSettings["YourSetting"]));

Ninject, Web API and MVC 4 Filter Binding disposing datacontext

I have an issue with my datacontext getting disposed every once in a while in one of my filters attached to my web api controllers. Is this the correct way to setup a filter for my Web API controllers and why does my datacontext get disposed sometimes?
The operation cannot be completed because the DbContext has been disposed.
Global.asax
GlobalConfiguration.Configuration.Filters
.Add(new ApiValidationFilter(kernel.Get<IApiAuthenticationService>()));
kernel.Bind<IDatabaseFactory>()
.To<DatabaseFactory>()
.InScope(q => HttpContext.Current ?? StandardScopeCallbacks.Thread(q));
ApiValidationFilter.cs
public class ApiValidationFilter : System.Web.Http.Filters.IActionFilter
{
private readonly IApiAuthenticationService _apiAuthenticationService;
public ApiValidationFilter(
IApiAuthenticationService apiAuthenticationService)
{
_apiAuthenticationService = apiAuthenticationService;
}
You should be using the Filter binding syntax, then Ninject will handle the the filter lifetime, and it will also handle the constructor injection of the filter.
https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations
I would also let Ninject handle managing the lifetime of the data conext as well, instead of using a factory.
kernel.Bind<MyContext>().ToSelf().InRequestScope();
Alternatively, if you want better testability you can derive your context from an interface and bind to that. The InRequestScope makes sure the context lives for the entire web request, and it will automatically get disposed when the request is done. You don't have to remember to do so, and there won't be any memory leaks by holding onto a request longer than a single request.
You can see an example here:
ASP.NET MVC 3 and Global Filter Injection
I eventually had to resort to the following, nothing worked.
var apiRepository = new ApiRepository(new DatabaseFactory());
var apiAuthenticationService = new ApiAuthenticationService(apiRepository, new UnitOfWork(new DatabaseFactory()), new ValidationProvider(null));

Can a custom UserNamePasswordValidator add things to the WCF session?

Related to this question, I'm instantiating a connection to our internal API inside my custom UserNamePasswordValidator. Can I stash this somewhere so that I can use it in future calls in that user's session?
This is similar to this question, but I'm not using IIS, so I can't use HttpContext.Current (or can I?).
Update: Some context: our internal API is exposed via a COM object, which exposes a Login method. Rather than have a Login method in my service interface, I've got a custom UserNamePasswordValidator, which calls the Login method on the COM object.
Because instantiating the COM object and logging in is expensive, I'd like to re-use the now-logged-in COM object in my service methods.
Yes, it can. You'll need:
a custom ServiceCredentials implementation that returns a custom SecurityTokenManager.
a custom SecurityTokenManager implementation that returns a custom CustomUserNameSecurityTokenAuthenticator.
your custom CustomUserNameSecurityTokenAuthenticator needs to override ValidateUserNamePasswordCore, and should add a custom implementation of IAuthorizationPolicy.
your implementation of IAuthorizationPolicy should implement Evaluate, at which point it can start putting things in the WCF context.
replace the evaluationContext["PrimaryIdentity"] value with a PasswordIdentity or a custom IIdentity.
replace the evaluationContext["Principal"] value with a PasswordPrincipal or a custom IPrincipal.
update the evaluationContext["Identities"] collection to replace the GenericIdentity instance with your custom instance.
By doing this, you can have a custom IPrincipal implementation with some extra information in it.
For more details, see this.
UserNamePasswordValidator is absolutely out of all WCF contexts. It is only used to validate user name and password. Can you futher explain your problem?
Edit:
I guess COM object is instantiated for each session, isn't it? Otherwise wrapping COM into singleton should solve your problem. If you need to have per session COM object shared between validator and service instance you will need some cache or registry - something which is outside both validator and service and can be called from both of them.