Accessing HttpContext in a class library - ASP.NET MVC - asp.net

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

Related

Custom Session State Module - Use ASP State Service

EDIT (clarifying my question): Is there an API or method with which we can use the Out Of Process Asp.NET State Service from our own code or is that proprietary?
We are looking into implementing a custom session state module that re-uses the components of the module that comes stock with asp. Our main goal is to just prevent session locking (without changing the session state mode to ReadOnly). Is this possible?
One of the key pieces that we would like to make work is to be able to use the same Out of Proc Session storage provider (The ASP State service) that is used internally by .NET as we have a load-balanced environment that doesn't use sticky sessions.
I have dug into the code over in the reference source, and my findings are below. I am hoping somebody has a different utility that could potentially be used to integrate a custom session state module the ASP State Service.
The default session Module is System.Web.SessionState.SessionStateModule. This is a Sealed class. This class appears to be the only class that uses the SessionStateMode.StateServer enum value (which is specified in the web config).
When this flag is set, the module sets the _store variable to be a new System.Web.SessionState.OutOfProcSessionStateStore which is a Friend Sealed class.
I had initially had a few thoughts on how to do this, and because of the modifiers on the classes above I was unable to do these. Are there other approaches that could be taken?
Instantiate a new System.Web.SessionState.SessionStateModule and reference the _store variable. This did not work, obviously because the _store variable is private.
I tried creating a class which inherits from System.Web.SessionState.SessionStateModule but obviously since it is sealed that does not work.
Looked at copying the code from the .NET framework code. Realized that would be a very poor decision.
Are there any options I am missing?
I would recommend you reading this topic: I just discovered why all ASP.Net websites are slow, and I am trying to work out what to do about it.
It provides some starting points and info on the session topic, especially locking problem.
If you look for custom implementation of session module you can look here:
http://www.codeproject.com/Articles/11712/Custom-session-state-management-in-ASP-NET

static initialization of a class used by asp.net-- how long will the initialized values last?

We're writing a class we'll use in our asp.net site. This class will pull down some json using HttpClients and such, and use it to provide information to other clients.
Some of this information will change very infrequently and it doesn't make sense to query for it on each client request.
For that reason I'm thinking of making a static constructor in this new class for the slow-changing information and stashing the results in a few static member variables. That'll save us a few HttpRequests down the line-- I think.
My question is, how long can I expect that information to be there before the class is recycled by ASP.Net and a new one comes into play, with the static constructor called once more? Is what I'm trying to do worth it? Are there better ways in ASP.Net to go about this?
I'm no expert on ASP.Net thread pooling or how it works and what objects get recycled and when.
Typical use of the new class (MyComponent, let's call it) would be as below, if that helps any.
//from mywebpage.aspx.cs:
var myComponent = new MyComponent();
myComponent.doStuff(); //etc etc.
//Method calls like the above may rely on some
//of the data we stored from the static constructor call.
Static fields last as long as the AppDomain. It is a good strategy that you have in mind but consider that the asp runtime may recycle the app pool or someone may restart the web site/server.
As an extension to your idea, save the data locally (via a separate service dedicated to this or simply to the hard drive) and refresh this at specific intervals as required.
You will still use a static field in asp.net for storing the value, but you will aquire it from the above local service or disk ... here I recommend a System.Lazy with instantiation and publication options on thrread safe (see the constructor documentation).

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

asp.net serialization exception is thrown when implementing session in sql server

"serialization exception thrown in System.Web.Profile.DefaultProfile"
I'm using a lot of custom classes but have marked them all with serializable attribute. The website loads properly initially on the default page, but once a redirection happens to a different page, which inherits the custom "BasePage" class, instead of the default Page class, this exception is thrown :
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
one of the statements in the intellitrace says something like, "failed to serialize System.Web.Profile.DefaultProfile could not be serialized". Isn't it an inbuilt .NET object, and if so cannot I presume that it should be serializable in all cases???
I just ran into this same problem yesterday. The custom object isn't necessarily the problem, but objects inside of that. If you have things like System.Drawing.Image or Dictionary<> or anything else that isn't inherently serializable, its gonna blow up. So you're gonna have to do some digging. I had to do things like convert a List into a string[] to pass it to the web service (which receives a List but shows in intellisense as receiving a string[]).
So I'd rethink that. We also found out that once we got that working in the test server, we weren't done. As soon as we published the web service, other problems started popping up that were similar. Images were not serializable so we converted them to byte[] before sending them, Dictionaries were also not serializable.
I realize this isn't much of an answer, but hopefully of some help.
It is built into ASP.Net, but that doesn't mean it's serializable. There's lots of framework classes that are not serializable.
But also, the Default profile is made to work with the asp.net profile mechanism. Why are you attempting to store that in session? It already has it's own configurable storage mechanism. I think this may be a case where you're in a place where you're fighting the system.
For my particular case, I worked around the problem by creating a new custom class with a Serializable attribute, with a property that would return the HttpContext.Current.Profile object. And then whenever I needed to add the profile into session, I'm adding it through the property of this newly created class. Thanks to #swannee and #Sinaesthetic for their ideas.

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.

Resources