Accessing Session Directly vs Other ways - asp.net-mvc

I've been working with MVC 3 for a little while at work and have been reviewing my code quite a bit. I'm using the session to store data I need across all actions/views.
I feel this is a bad idea, though I'm not entirely understanding of why. So I started reading around and found this post: Session variables in ASP.NET MVC
I'm currently accessing the session in my controller in this manner,
private SelectedReport Report
{
get
{
return Session["Report"] as SelectedReport;
}
set
{
Session["Report"] = value;
}
}
then Accessing it with this.Report
I've read that the way above is not optimal/good but I'm not certain why.
Why is my way not good/optimal? Why is the way in the link provided better?
(This might be better posed as a conceptual question but i'm not sure how to ask it that way, there are a few web/mvc concepts I think I'm missing. I was kind of just thrown into MVC/Web with no prior knowledge and was never sure where to start).

For error handling there are several libraries that can simplify things for you.
But beyond that, storing things on the session should only be done where you need the object In several places
Ideally if you need to expose one object from one view to the other, you could use a common base model that includes what the views need, or add stuff to the ViewData object instead of the session object.
And for error handling, fatal errors should be trapped in global.asax, and for warnings, I in particular use a base model class for all views that includes a warnings collection that is shown via master page.

Related

Is it wrong to create an HttpContextProvider for use in IHttpModules?

I have this legacy ASP.NET webapp that's mostly been transitioned to MVC. Code testability is generally bad, as it happens a lot to legacy apps: responsibilities are in a jumble, tight coupling prevails, that sort of thing.
I've been refactoring the app for a couple weeks to improve testability, doing my best to abide by SOLID, and I've come to this point where I need to pass HttpContext or HttpResponse and the like to a method in the HttpModule. Now, obviously the HttpModules can grab a copy of the HttpApplication and just pass that everywhere - which is how it is atm - but I would rather not grant access to such a large root object to a dependency.
Because some of our IHttpModules are initialized before the MVC even comes into play, I've had problems with using an IoC container to inject HttpContextBase or HttpResponseBase into constructors of various helpers that the modules use. I thus have to either pass the HttpContextBase to methods of said helpers - which is taxing to use and feels somewhat wrong - or create something like this:
public class HttpContextProvider : IHttpContextProvider {
// ... ctor
public HttpContextBase GetContext() { return HttpContext.Current; }
}
I would then inject an instance implementing IHttpContextProvider into a helper and call .GetContext() on it later as needed.
Intuitively, I feel like I might be doing something wrong, but cannot really get a handle on what it could be. This whole refactoring is complex enough - and the bus factor in the team is low enough - that I'm hesitant to request too much of the lead dev's time for this issue, which could almost be seen as academic from a practical standpoint.
I can suggest different options
try to register this objects in IoC, but to fix the problem (that class is initialized before it's dependences can be resolved) just use Lazy< T>, most IoC support them, check if yours is
Introducing providers as in your example, but I'll suggest it to return not HttpContext (or HttpResponse), but exactly what you need from this classes, it would be easier in tests to mock this behaviour (you maybe even don't need to construct context there at all) and also it will hide all complex stuff of HttpContext that isn't used
The second option will work only if you use this objects in similar way each time - so that you can replace it with 2-3 methods of ISmthProvider. If you use objects always differently maybe it will be better to combine both approaches and extract the most popular usages into some service and in other places path Lazy< HttpContextBase> to constructor
In my opinion it's better not to pass HttpContext/HttpResponse directly as it giving access for too much stuff and later people can make a mess of it (using it without thinking as it's already there) as a result it would be difficult to test and to make refactoring later.

ASP.NET MVC ActionMethodSelector dependency injection/replacement

I wish to replace the implementation of System.Web.Mvc.ActionMethodSelector as used by the FindAction method of ReflectedControllerDescriptor, but would like to take advantage of the existing implementation, ideally by deriving from ActionMethodSelector. However, because the class is marked as internal the only way I can see to do this 'properly' is to derive from ReflectedControllerDescriptor and implement FindAction by copying the code from ActionMethodSelector. I wish to avoid this however due to the quantity of code, and potential issues trying to keep it up to date with the framework.
I'm considering the following approaches:
Biting the bullet and copying the code
Using reflection so as to take advantage of the existing implementation
Are there any other approaches that I'm missing, better or otherwise?
I know it is a bit late to answer still I am giving it a try.... :)
I believe that you somehow want to tweak action method selection process in ASP.NET MVC. If my understanding is correct you can make use of custom ActionMethodSelectorAttribute by deriving from System.Web.Mvc.ActionMethodSelectorAttribute. Write your own custom logic in the custom selector and apply it on the top of the action methods. I believe in this way the action method selection process can be tweaked without disturbing the natural process.
If you wish you can visit these links: http://programersnotebook.blogspot.in/2014/02/aspnet-mvc-actionnameselector-and.html, http://programersnotebook.blogspot.in/2014/02/aspnet-mvc-actionnameselector-and_2.html

Ninject binding/unbind issue

I have a bit of a dilemma, which to be honest is a fringe case but still poses an issue.
Currently I am using Ninject MVC and bind all my controllers like so:
Kernel.Bind<SomeController>.ToSelf();
Which works a treat for 99% of things that I have needed to do, however at the moment I am doing some wacky stuff around dynamic routing and dynamic controllers which require me to manually write a method to get the type of a controller from ninject. Now initially I thought it would be easy, but its not... I was expecting that I could get the controller based on its name, but that didnt work.
Kernel.Get<IController>("SomeController");
That got me thinking that its probably because it only knows about a binding to SomeController, not IController. So I thought, I can just write all my bindings like so:
Kernel.Bind<IController>.To<SomeController>().Named("SomeController");
This way it should be easy to get the type of the controller from the name doing the previous code, however if I were to bind this way, I would have a problem when I come to unbind the controllers (as plugins can be loaded and unloaded at runtime). So the normal:
Kernel.Unbind<SomeController>()
Which was great, will no longer work, and I would have to do:
Kernel.Unbind<IController>();
However then I realised that I need to give it some constraint to tell it which binding for this type I want to unbind, and there seems to be no overloads or DSL available to do this...
So I am trapped between a rock and a hard place, as I need to satisfy the ControllerLookup method, but also need to keep it so I can add and remove bindings easily at runtime.
protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
//... find and return type from ninject
}
Anyone have any ideas?
(Just incase anyone questions why I am doing this, its because of the way I am loading plugins, Ninject knows about the types and the namespaces, but within the context of creating a controller it doesn't know the namespace just the controller name, so I do this to satisfy the isolation of the plugin, and the location of the dynamic controller, it is a roundabout way of doing it, but it is what people have done with AutoFac before Example of similar thing with AutoFac)
In my opinion the bindings should be created once at application startup and not change anymore after the first resolve. Everything else can lead to strange issues. Unless you have proper isolation using an AppDomain for each plugin you can not really unload them anyway. Instead of unloading bindings you can make them conditional and disable them using some configuration.
If you really want to unload bindings then I suggest not to do it for single bindings but take advantage of modules. Load all bindings belonging to one plugin together in one or several modules and unload those modules instead of the single bindings.

Entity Framework context

I have an application using the Entity Framework code first. My setup is that I have a core service which all other services inherit from. The core service contains the following code:
public static DatabaseContext db = new DatabaseContext();
public CoreService()
{
db.Database.Initialize(force: false);
}
Then, another class will inherit from CoreService and when it needs to query the database will just run some code such as:
db.Products.Where(blah => blah.IsEnabled);
However, I seem to be getting conflicting stories as to which is best.
Some people advise NOT to do what I'm doing.
Other people say that you should define the context for each class (rather than use a base class to instantiate it)
Others say that for EVERY database call, I should wrap it in a using block. I've never seen this in any of the examples from Microsoft.
Can anyone clarify?
I'm currently at a point where refactoring is possible and quite quick, so I'd like some general advice if possible.
You should wrap one context per web request. Hold it open for as long as you need it, then get rid of it when you are finished. That's what the using is for.
Do NOT wrap up your context in a Singleton. That is not a good idea.
If you are working with clients like WinForms then I think you would wrap the context around each form but that's not my area.
Also, make sure you know when you are going to be actually executing against your datasource so you don't end up enumerating multiple times when you might only need to do so once to work with the results.
Lastly, you have seen this practice from MS as lots of the ADO stuff supports being wrapped in a using but hardly anyone realises this.
I suggest to use design principle "prefer composition over inheritance".
You can have the reference of the database context in your base class.
Implement a singleton for getting the DataContext and assign the datacontext to this reference.
The conflicts you get are not related to sharing the context between classes but are caused by the static declaration of your context. If you make the context an instance field of your service class, so that every service instance gets its own context, there should be no issues.
The using pattern you mention is not required but instead you should make sure that context.Dispose() is called at the service disposal.

What things can I put inside a BaseController to make my MVC life simpler

My base controller has:
[Authorize(Roles = "sys_admin")]
I want to have one action in a controller that's different and is available to "user" and "sys_admin". Can I override and how do I do that?
Also any suggestions on what else I could put in a base controller that might make my coding simpler. For example what's in your base controllers?
Anything that you use in every controller - attributes, methods, properties, etc. The same stuff you would put in any base class.
Just to add to the discussion, I have a few extra utility methods in my shared controller. I write a bunch of little apps for corporate use, so I try to repeat code as little as possible here.
getContext(): Puts together an object containing user info like IP, hostname, id, etc. for logging purposes.
Shared Views/Partials such as Error, Default, and Redirect (used for redirecting ajax requests).
RedirectToError(): I created this to use similar to RedirectToAction. I load up an ErrorObject with info, throw it in session, and return a Redirect to my Error page.
General logging and tracing methods so I can quickly spit out information to a file.
I override OnActionExecuting and check if my session is still valid and redirect to login if its not. Probably better with attributes...went with quick and dirty. Also trace Url.PathAndQuery for debugging here.
Any data access actions that I would use across views with ajax, like loading up a list of departments.
OnException is overridden, as well.
That's what I got in mine so far.
In my base controllers I actually put some utility method ([NonAction]) collected over time. I prefer to add functionalities to Controllers by decorating with Attributes if possible.
Lately my base controller has:
some Properties for retrieving information about the current user (my app
specific informations, not the User.Identity stuffs)
A simple protected override void OnException(ExceptionContext
filterContext); override for at least logging unhandled exception and have
some sort of automatic notifications
A bunch of Cookies related methods (WebForms auth cookies management
for example)
A bunch of usefull standard attributes (usually [Authorize], [HandleError], [OutputCache]) in its declaration.
some standard method for preparing widely used json data types on the fly (when possible I prefer to have a standard json object with ErrorCode, ErrorMessage and a UserData).
With time you'll find more and more utilities to keep with your controllers, try to keep an assembly with the simpler ones (avoiding heavy dependencies), will come handy with your next MVC projects. (the same goes for Helpers and to some degree also for EditorTemplates).
For the Authorize Attribute part, well, I think the cleanest way is to write your own AuthorizeAttribute class, specifically a NonAuthorizeAttribute. I think I've also seen it somewhere on SO.
You can also play with the Order Property of the default AuthorizeAttribute - put different Order in BaseController and in Action, in order to have Action's one executed first, but I cannot recall if you can actually break the Attributes processing chain.
Regards,
M.
We cant tell you what you need in your base controller, you have to reveal these kind of thing as you implement your controllers and see repeating code.. Dont hesitate to refactor these things to your BaseController, and keep in mind, that maybe you should have 2 or more BaseControllers, or 2-layer hierarchy of BaseControllers.
I give you two tips, what i always have in my BaseController :
super-useful helper method for interface-based model binding :
protected T Bind<T, U>()
where T : U, new()
where U : class
{
T model = new T();
TryUpdateModel<U>(model);
return model;
}
You can then have multiple "sets" of properties you want to bind in different scenarios implemented as interfaces, and simple model bind your object (even existing object, from DB) with incoming values.
2.If you use custom AcionResults (maybe your specific Json builders etc.), make your "shortcuts" methods in BaseController. Same thing as View() method is shortcut for return new ViewResult(...)
To add more to the good responses already here -
caching caching caching caching
See
Disable browser cache for entire ASP.NET website

Resources