Refactoring session variables - asp.net

I'm visiting an app that's been in use for the past 2+ years and it is in desperate need of refactoring. It is of my own work, but you know what it's like when you visit old code again.
Anyway I've been using the excellent advice at sourcemaking to refactor and the code is already looking much better.
The problem now is there are loads of Session["variable"] sprinkled throughout the code, so what's the most accepted way to refactor these out? I found this article at code project but apparently it can be quite dangerous.

The best way to refactor random session usage like this is to create a static SessionWrapper with static properties that encapsulate the ASP.NET session store:
static class SessionWrapper
{
public static string Variable
{
get { return Session["variable"]; }
set { Session["variable"] = value; }
}
}
This will also allow you to put some logic around the getting and setting of these values and keep them in a centralized place.
I would also strongly recommend that you have some integration tests in place before you start this process so that you can be sure you haven't missed anything.

Related

Custom Assetic Filter Development - Constantly Cached?

I'm having an issue with my development of a custom assetic filter. I loosely followed the steps in the blog article found here and got things working for the most part. The thing that's causing me hang up is the fact that if I make a change to the filterLoad or filterDump methods it usually shows up the first time but additional changes won't. It seems like things are getting cached but not in the usual Symfony2 cache directory. This is pretty vague so far so let me know if there's any additional information I can provide.
Example of change:
public function filterLoad(AssetInterface $asset)
{
$asset->setContent('this');
}
public function filterDump(AssetInterface $asset)
{
$asset->setContent('that');
}

Using view model organizes code, but does it have impact on performance?

Part I
I am working on a web application that instead of using a viewmodel class to organize data and be used in View, uses a database table model. So for example in my view, model declaration looks like this: #model aa.webobjects.object - object is automatically generated by dbml. The question here is what is the benefit of using a viewmodel other than organizing data? I have another class, under dbml, that for example does this:
public Product GetProductsByPrice
{
get
{
return WebDataContext.Get().Products.Where(x => x.Price > 10);
}
}
And basically this is used to organize data, and pull data from database as needed. The return statement brings us to question two.
Part II
My application has a memory leak. The memory keeps growing and growing and after a while the server dies. As I read through some articles it seems like I should wrap my WebDataContext in using statement so that it'll recycle properly. My question here is: is not using Viemodel causing the memory leak, ir if I used viewmodels to organize data, and reorganize usage of WebDataContext so that it's wrapped in using statement would help?
I am not sure if this is explaining the problem correctly. Any help will be greatly appreciated.
For sure you have to dispose your DataContexts instances (that's basically what using does). My suggestion is to add this in your Global.asax:
public void Request_End(object sender, EventArgs e)
{
WebDataContext.Get().Dispose();
}
and make WebDatacontext.Get() to return it from HttpContext.Current.Items.
In this way, your datacontext will be available for the whole request and it will be disposed when you don't need it anymore.
Hope it helps.
What is the benefit of using a View model?
You can use data annotations and model binding when you post back to the server. This allows the creation of forms with validation checking much easier.
The objects coming out of your DB are being tracked for changes and carry some baggage with them. A view model (being a POCO) contains only the data you need with out all the other tracking tied to it. Passing a view model around is considered a better practice than passing entities around.

Override the Default ViewEngine to Look in Different Directories

I created an area in Visual Studio which automatically adds the appropriate bits in the "Areas" directory. I renamed this to "Modules" but now when i navigate to /{area}/{controller/{action} it still looks for the view within the /Areas/{area}/Views/{controller/{action} directory and not the /Modules/{area}/Views/{controller/{action} directory. I would also like to be able to override the view for specific themes. Therefore i was wondering how i could customise the default view engine to look for the view in the following locations aswell:
/Themes/Default/Views/{area}/{controller}/{action}.cshtml
/Modules/{area}/Views/{controller}/{action}.cshtml
I'd really appreciate it if someone could help.
Thanks
As ASP.NET MVC source code is available, it is easy to answer these kinds of questions by looking at the source. If you look at the WebFormViewEngine class you can see the locations listed and it will be easy for you to inherit from this and customise them.
However, not going with the code by convention approach is just going to make your life harder so I'd advise living with the default locations.
Here's the code incase anyone is interested:
public class CustomRazorViewEngine : RazorViewEngine {
public CustomRazorViewEngine()
: this(null) {
}
public CustomRazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator) {
AreaViewLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
AreaMasterLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
AreaPartialViewLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
}
}
Now just place the following in the Application_Start event in the Global.asax.cs file:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
Hope this helps.
The code you posted is very similar to what I wound up doing a few months ago.
I also have a preprocessing step (run on-demand or at compile time) which finds all of the .cshtml files in the site folder hierarchy and adds their relative paths to a table in the database. The site caches that data on startup. The custom view engine then searches that list for views, and only checks the disk when it finds a match.
This performs very, very well. Avoiding disk access will probably only help if you're running a very busy site. Even though disk access is very slow, it's typically not a performance bottleneck and ASP.NET performs its own intelligent caching.

How to unit test for turning off request validation?

I'm new at this TDD thing but making a serious effort, so I'm hoping to get some feedback here.
I created a little web service to minify JavaScript, and everything was nice, with all my tests passing. Then I noticed a bug: if I tried to minify alert('<script>');, it would throw a HttpRequestValidationException.
So that's easy enough to fix. I'll just add [AllowHtml] to my controller. But what would be a good way to unit test that this doesn't happen in the future?
The following was my first thought:
[TestMethod]
public void Minify_DoesntChokeOnHtml()
{
try
{
using (var controller = ServiceLocator.Current.GetInstance<MinifyController>())
{
return controller.Minify("alert('<script></script>');");
}
}
catch (HttpRequestValidationException)
{
Assert.Fail("Request validation prevented HTML from existing inside the JavaScript.");
}
}
However, this doesn't work since I am just getting a controller instance and running methods on it, instead of firing up the whole ASP.NET pipeline.
What would be a good unit test for this? Maybe reflector on the controller method to see if the [AllowHtml] attribute is present? That seems very structural, and unlikely to survive a refactoring; something functional might make more sense. Any ideas?
You have only two options:
First
Write integration test that hosts MVC in-proc or runs using browser (using Watin for instance) that will cover you scenario.
Second
Write unit test that will check that method is marked with needed attribute.
I would go with the first option.

ASP.NET Localized web site -- updating on the fly

I think I have a solution to this, but is there a better way, or is this going to break on me?
I am constructing a localized web site using global/local resx files. It is a requirement that non-technical users can edit the strings and add new languages through the web app.
This seems easy enough -- I have a form to display strings and the changes are saved with code like this snippet:
string filename = MapPath("App_GlobalResources/strings.hu.resx");
XmlDocument xDoc = new XmlDocument();
XmlNode xNode;
xDoc.Load(filename);
xNode = xDoc.SelectSingleNode("//root/data[#name='PageTitle']/value");
xNode.InnerText = txtNewTitle.Text;
xDoc.Save(filename);
Is this going to cause problems on a busy site? If it causes a momentary delay for recompilation, that's no big deal. And realistically, this form won't see constant, heavy use. What does the community think?
I've used a similar method before for a very basic "CMS". The site wasn't massively used but it didn't cause me any problems.
I don't think changing a resx will cause a recycle.
We did something similar, but used a database to store the user modified values. We then provided a fallback mechanism to serve the overridden value of a localized key.
That said, I think your method should work fine.
Have you considered creating a Resource object? You would need to wrap your settings into a single object that all the client code would use. Something like:
public class GuiResources
{
public string PageTitle
{
get return _pageTitle;
}
// Fired once when the class is first created.
void LoadConfiguration()
{
// Load settings from config section
_pageTitle = // Value from config
}
}
You could make it a singleton or a provider, that way the object is loaded only one time. Also you could make it smart to look at the current thread to get the culture info so you know what language to return.
Then in your web.config file you can create a custom section and set restartOnExternalChanges="true". That way, your app will get the changed when they are made.

Resources