Accessing Current Context in a PersistentConnection - signalr

From how I've understood it HTTPContext.Current is not always available for a SignalR Hub to access, so we should look to use Context.* or Context.Request.GetHttpContext().
However when I use a PersistentConnection, I don't believe I can use a HubCallerContext and HTTPContext.Current is still not something that is reliable; so what should I be using?
Unified static class between HttpContext and SignalR HubCallerContext

Dax is correct, it is possible to call GetHttpContext directly from the request parameter of the PersistentConnection.

Related

HttpClient, seems so hard to use it correctly

just another question about the correct usage of HttpClient, because unless i am missing something, I find contradicting information about HttpClient in Microsoft Docs. These two links are the source of my confusion:
https://learn.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#typed-clients
First one states that the best approach is a shared singleton HttpClient instance, the second that the AddHttpClient<TypedClient>() registers the service as transient, and more specifically (copied from that URL):
The typed client is registered as transient with DI. In the preceding
code, AddHttpClient registers GitHubService as a transient service.
This registration uses a factory method to:
Create an instance of HttpClient.
Create an instance of GitHubService, passing in the instance of HttpClient to its constructor.
I was always using AddHttpClient<TypedClient>() and feeling safe, but now i am puzzled again... And making things worse, I found this github issue comment by #rynowak which states:
If you are building a library that you plan to distribute, I would
strongly suggest that you don't take a dependency on
IHttpClientFactory at all, and have your consumers pass in an
HttpClient instance.
Why this is important to me? Because, I am in a process of creating a library that mainly does two things:
Retrieve an access token from a token service (IdentityServer4)
Use that token to access a protected resource
And I am following the typed clients approach described in the link 2 above:
//from https://github.com/georgekosmidis/IdentityServer4.Contrib.HttpClientService/blob/master/src/IdentityServer4.Contrib.HttpClientService/Extensions/ServiceCollectionExtensions.cs
services.AddHttpClient<IIdentityServerHttpClient, IdentityServerHttpClient>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
Any advises or examples of how a concrete implementation based on HttpClient looks like, will be very welcome.
Thank you!

Using InjectionFactory to inject DbContext, lifetime of created instance

I have an ASP.NET MVC5 project with Unity as DI framework.
Consider the following code:
container.RegisterType<ApplicationDbContext>(
new InjectionFactory(c => new ApplicationDbContext()));
As my repositories are using the same DbContext, it would be practical to pass the same instance to all of them. However, every visitor of the site should have a separate instance of the context, not work on one big "site-wide" instance. I guess this reduces the possibilites to have an instance lifetime only for the current request.
As UnityConfig.RegisterComponents() is in the Application_Start() method, I guess it would only create one instance for the entire application.
What is the best practice in this case? I have thought about the following:
Create my own factory for the DbContext which returns a singleton, and inject this factory into my repositories
Move UnityConfig.RegisterComponents() to Application_BeginRequest()
I tried to search for InjectionFactory on Microsoft's site, not much luck (http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.injectionfactory%28v=pandp.51%29.aspx)
What best practice should I follow in this case? I don't want to overengineer it, what is the simplest working solution?
I'm not a web developer but reading through the book Dependency Injection With Unity they did mention a special lifetime manager that you can use for a single HTTP request - PerRequestLifetimeManager
Perhaps that would work for your needs?
Remove the factory and replace with:
container.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager());
This will result in an ApplicationDbContext instance per request and also take call of disposing of the context at the end of the request.
I think what you're after is the unit of work pattern.
Take a look at the following link
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

Accessing HttpContext in a class library - ASP.NET MVC

I am populating an instance of a class that represents the session variable and exists in a class library. I need to populate one property that requires me to get access to the Request object. I understand that I can use the System.Web.HttpContext.Current.Request to get the request object?
Is this a good practice. Something tells me that I should be doing this in the controller (or the base controller) that has the System.Web namespace.
Its not a bad practice - the object is available - if you design dictates to access it there - then by all means do it. One option is to pass in an instance of the request to the class's constructor if it makes you feel cleaner : )
According to Teemu Keiski on the ASP.NET forums:
You could use System.Web.HttpContext.Current but that's bad practise
since it makes your class library totally unusable outside web
applications (and if you access Sessions via that, it also gets
unusable for web services in most scenarios).
Anything you pass by getting straight HttpContext could be passed as
parameters into the class that needs it. And if you need to access
Response object directly, you could pass Response.OutputStream into
the class (which would take it as general Stream object)
Source: http://forums.asp.net/post/1311405.aspx
Fundamentally there's nothing wrong with this as long as you take a dependency on System.Web.Abstractions and pass into your class a reference to HttpRequestBase. The classes in this assembly are not sealed and all members are virtual which means your class will still be testable.
More info in the answers to the following SO question

Mocking HttpRequest in ASP.NET 4.0

I've seen a lot of similar threads but none that actually address my particular situation.
I'm writing unit tests in ASP.NET 4.0 web application (ASP.NET Forms, not MVC). There are several spots in the code where I call the ServerVariables collection to call variables like REMOTE_ADDR. Since my unit tests do not actually initiate HttpRequests when executing my code, things like ServerVariables are Null and therefore error when I try to call HttpContext.Current.Request.ServerVariables("REMOTE_ADDR")
All the solutions I've found to address this issue refer to MVC and so they assume that HttpRequest derives from HttpRequestBase, which it does in MVC but not in ASP.NET Forms.
I tried using Moq but you can't mock a sealed class, and HttpRequest is unfortunately sealed with no interface.
The HttpRequestBase and HttpRequestWrapper classes can be used with a bit of work.
Wherever you currently access HttpContext.Current.Request -- or just plain Page.Request -- you'll need to use an injectable instance of HttpRequestBase instead. Then you'll need to inject a different subclass of HttpRequestBase depending on whether you're testing or live.
For live code, you'd probably inject an HttpRequestWrapper instance that wraps HttpContext.Current.Request:
var liveRequest = new HttpRequestWrapper(HttpContext.Current.Request);
For test code, you'd need to create and inject your own mock subclass of HttpRequestBase. Presumably Moq can do that for you on-the-fly.

How do I retrieve the HttpContext properties when it returns null?

I am doing some asynchronous work on a separate thread using:
ThreadPool.QueueUserWorkItem()
and in this separate thread, I need to call HttpContext.Current so that I can access:
HttpContext.Current.Cache
HttpContext.Current.Server
HttpContext.Current.Request
However, HttpContext.Current is null when I create this separate thread.
Question
How do I create a new thread so that HttpContext.Current is not null? Or is there another way I can access the Cache, Server, and Request objects?
You can access the ASP.NET cache with HttpRuntime.Cache even when you don't have a HttpContext, but unfortunately you cannot access Server or Request.
If you think about it, this make sense - you are not serving any page so you don't have a request.
I'd try not to hold a reference to an object that depends on the ASP.NET stack like the HttpContext. If you need to do some work in a different thread, it's because you don't want to wait in the ASP.NET one till your task is finished. And maybe the Request/Context/Session is terminated while your thread is not.
You should pass an object with the data needed for your thread.
1- Add bottom code in <system.serviceModel> in Web.config file:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
2- Add bottom code after NameSpace in web service file:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3- Rebuild web part project.
Done!
reference
For HttpContext.Server services you can use HttpServerUtility class.
For the Cache you can use HttpRuntime.Cache, as it has been said above.
For the request object you can pass the data from the Request to the thread when it is created. Things like Request.QueryString or Request.Form... or whatever.
There is a thread pool implementation here that provides propagation of the calling thread's HTTP context. I haven't used it yet but I plan to.
If the separate thread is trying to access those objects, then yes they will be null. Those objects are scoped at the thread level. If you want to use them in a new thread you will have to pass them into the method/class where you need them.
Typically ASP.Net doesn't allow you to spawn new threads... Here is a post on the subject.
Here is a nice write up on threading in ASP.NET from MSDN.

Resources