I've just been adding some more automation sprinkles to our website deployment strategy. I now have 12 white-labelled sites that need publishing at least once a day. Now, I know there'll be some fully automated solutions out there but, hey, this works for us.
I was building a little batch file to deploy the extracted files once cited on the server. OK, so let's re-acquaint myself with XCopy's parameters.
"Note: Xcopy is now deprecated, please use Robocopy."
WTF. What's Robocopy!?
Seems as though I've missed a few of the Microsoft emails about this 'new' feature of Windows. It used to be available as a Resource download but is a standard component from Windows XP onwards.
So, what can it do? Well, after a cursory glance, pretty much anything. There's a glut of parameters covering the following sections: Copy, File Selection, Retry, Logging, Job. Here's a couple that stood out as extremely useful...
/E :: copy subdirectories, including Empty ones.
/LEV:n :: only copy the top n LEVels of the source directory tree.
/Z :: copy files in restartable mode (if the connection is interrupted it will continue when next available!).
/PURGE :: delete dest files/dirs that no longer exist in the source.
/MIR :: MIRror a directory tree (equivalent to /E plus /PURGE
I'm well aware that I may very well be the only guy on this sphere who isn't aware of this command line tool; but I think this was worth noting anyway.
It was pointed out to me by a colleague that the Html.RadioButton(...) extension methods produce invalid XHTML. The output is invalid because, by default, the method will duplicate html "id" attributes. For example, let's say I have a Colours View Model...
public enum Colours
{
Red,
Blue,
Green
}
public class ColoursViewModel
{
public Colours ChosenColour
{
get;
set;
}
}
Then I could create a simple action like this ...
public class TestController
{
public ActionResult SelectColour()
{
return View(new ColoursViewModel());
}
}
The MVC framework will automatically bind my view model's "ChosenColour" property to the radio button collection so that I can post the results back like this...
public class TestController
{
[AcceptVerbs(HttpVerbs.Post)]
public string SelectColour(ColoursViewModel viewModel)
{
return "You chose " + viewModel.ChosenColour.ToString();
}
}
The problem here is that the generated html looks like this (notice the duplicate id attributes)...
This means that we cannot use the "for" attribute on any labels associated with the individual radio buttons nor can we use javascript to select the radio button when that associated label is clicked.
This is how you fix the problem...
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ColoursViewModel>" %>
<%= Html.RadioButton("ChosenColour", "Red", new { id = "chooseRed" }); %>
<%= Html.RadioButton("ChosenColour", "Green", new { id = "chooseGreen" }); %>
<%= Html.RadioButton("ChosenColour", "Blue", new { id = "chooseBlue" }); %>
... which will generate this html fragment...
The point I'm trying to make here is that the id attribute should be a first class parameter of the RadioButton extension method. I shouldn't have to override it using the htmlAttributes parameter. This is what the official extension methods look like...
OK, quite an obtuse question there so let me explain...
In our ASP.NET MVC application we have a custom Membership Provider and a custom Role Provider. Here's a (vastly simplified) example of the membership provider...
So, pretty straight forward. Nothing wrong with that, is there?
Well, actually, yes. The problem is that you may write this class with the expectation that it will be treated as a POIO (Plain Old Instance Object) but ASP.NET has other ideas. One, and only one, of these objects is instantiated (during the first request to you site). The big issue here is that we now have private fields on a singleton class - not good.
We ran into problems with SqlDataReaders because the runtime complained about multiple readers on the same connection. We could have implemented MARS, but that still didn't deal with the underlying problem. Worse still is the possibility of an unauthorised user actually being authorised! You only need user1's time-slice to end and user2's to begin midway through that ValidateUser method and you've got serious problems.
This is a summarised suggestion of how we solved this problem...
public class CustomMembershipProvider : MembershipProvider
{
public CustomMembershipProvider()
{
}
public override bool ValidateUser(string username, string password)
{
bool success = false;
using (var cn = OpenConnection())
{
var validater = new UserValidater(cn, username, password);
success = validater.IsValid();
}
return success;
}
private class UserValidater
{
private SqlConnection _connection;
private string _userName;
private string _password;
public UserValidater(SqlConnection cn, string userName, string password)
{
_connection = connection;
_userName = username;
_password = password;
}
public bool IsValid()
{
// Logic removed for brevity...
}
}
}
Our main website application used to have a structure that would allow the user to land on an http page and then login to a secure area. This has now changed so that the entire site has to be under SSL. The result of this is that we can no longer 'code' for this redirect. JPPinto has written a great blog entry that describes how to do it outside of your application, just using IIS.
I've just spent some time banging my head against a virtual brick wall built by my Build Server. It has, for some time now, been successfully building and deploying 2 versions (v1 and v2) of the same 'White Labelled' website to an internal testing web server. Recently I edited the definition so that it deleted all v2 files on the testing server before deploying. I did this because MVC Views that the developers had deleted, moved or renamed were remaining in the deployment and causing problems.
So, both versions were absolutely identical except for their web.config files that targeted different databases.
Both sites would allow me to hit the landing and login; but v2 failed to render any view that was strongly typed against a ViewModel. For instance, a view that inherited this would be fine...
System.Web.Mvc.ViewPage
... however, a view that inherited this, would fail...
Turns out that it was because I wasn't deploying that innocuous little web.config file that resides in the root View directory. One very important part of this file is to deny direct browsing to the aspx & ascx files - you want any requests to go via your routing model and controllers. The second purpose is to define the base types for your views and how to parse them.
I've been taking a look at Google Analytics for a couple of weeks and, quite frankly, how can you not be impressed? With the addition of a single block of javascript (2 scripts) GA will track all the activity on your site. Wow.
It captures hits, countries, browsers, referers and will show you a page overlay indicating where most of you visitors click to next. A web developer's dream "Look what I did, boss...".
However, here's the problem...
It's a script and they want me to put it on my site. That's fine for this blog, but I simply cannot use it on any commercial site that requires a user to login. Now, I'm not saying that GA would ever do anything untoward with that script but, technically, they could; and that's enough. If it felt so inclined, that script could access any DOM element on that page and even redirect POSTs to another endpoint. Login details, passwords and, in my case, financial data could all be collected and associated with the clients' IP address.
A crying shame - guess I'll just have to write my own server-side solution.
This is a pattern introduced (to me at least) by Michael Feathers in his book "Working Effectively with Legacy Code". It deals with occasions where you have a Singleton pattern that it consumed by a large number of classes. This impedes these classes being Unit Tested as they all have a hidden dependency.
The first solution to this is to add a constructor overload to every class. You will also need to extract an interface for the Singleton. For instance...
public class MyClass
{
public MyClass()
{
}
public void DoWork()
{
MySingleton.Instance.DoWork();
}
}
... would become ...
public class MyClass
{
private IMySingleton _worker;
public MyClass()
: this (MySingleton.Instance)
{
}
public MyClass(IMySingleton worker)
{
_worker = worker;
}
public void DoWork()
{
_worker.DoWork();
}
}
You won't have to change any other code once the above it implemented. What this achieves is that your Unit Tests have the opportunity to use a Dependency Inversion pattern by using the non-default constructor. Simple, and nothing new.
However, this can be an awful lot of work - directly proportional to the number of classes that consume your singleton. This is where the Supercede Instance Pattern comes in.
This is probably a fair representation of the Singleton Pattern...
public class MySingleton : IMySingleton
{
private MySingleton()
{
}
private static IMySingleton _instance;
public static IMySingleton Instance
{
get
{
// Double locking mechanism omitted for brevity...
if (_instance == null)
_instance = new MySingleton();
}
}
}
All we need to do is add a new method to the above class...
public class MySingleton : IMySingleton
{
// All previous members omitted for brevity
public static void SupercedeInstance(IMySingleton newInstance)
{
_instance = newInstance;
}
}
Et voila. Your unit tests can call this new method and inject their own, chosen object into the Singleton. You've now broken the dependency of masses of classes in one hit. Nice.
Final point, if your language allows you could conditionally remove this method. That would keep your singleton 'safe' in the wild. For example...
public class MySingleton : IMySingleton
{
#if RUNNING_UNIT_TESTS
public static void SupercedeInstance(IMySingleton newInstance)
{
_instance = instance;
}
#endif
}