Archive for the ‘ASP.NET MVC’ category

On SRP and staying DRY

April 4, 2010

A couple of weeks ago Chad Myers posted a message on the Fubu group explaining the difference between Fubu and MS MVC. This was definitely an Eureka moment for me- suddenly SRP made sense to me and it all clicked into place. In his message, Chad says:

Front Controller is also
about composing the response. ย Sometimes the view needs more information
than what is relevant to the “meat” of the request (i.e. displaying the
login page may involve displaying advertisements or notifications, etc that
are not necessarily the responsibility of the Login action).

The first thing that popped into my mind was the parent controller Uber class we’ve got in the project I’m working on currently. In it we deal with security and authentication issues, we deal with requests for downloading help files for each and every page in the web site, we deal with maintenance scenarios when the site would need to be down and so on. Needless to say, the number of ifs we’ve got there is starting to get rather unhealthy and the thought of making any changes to any of these responsibilities/logics makes me shudder; with fubu, we could have had a Behaviour for each concern/responsibility. Although this might be a rather extreme example of the Single Responsibility Principle (1 method – 1 responsibility), it is usually clear cut examples that make you grasp the idea fully and understand what were you doing wrong all that time.

From what I’ve experienced up until now, the first sign that makes me look for SRP violations is a forced application of the DRY principle, attempting to mutualise code/logic that seems to be similar and treating the same sort of a scenario. A great example for that scenario was a little feature I had to add a week ago, in which I was supposed to allow the users to subscribe people, while creating their program. We already had a very similar feature that allows the users of the application to subscribe people on their program after the latter has been created. My colleague thought we could simply reuse the views and actions we already created. That was a good enough sign for me to get some more explanations about the process of subscribing someone to your program while creating it, and needless to say it turned out that “it would be exactly the same thing, only…” and this ‘but’ made changes to some data access logic we had and the way we use NHibernate to get this data. We ended up separating these two scenarios and the best thing is that we’ve gained a lot in doing so in terms of maintainability ๐Ÿ™‚

Advertisements

ASP.NET MVC CheckBoxList

January 26, 2010

This is a very simple implementation of a check box list that we use rather frequently and which hasn’t let us down (yet).

First thing to do is to write a class inheriting from Dictionary<T, bool> for our multiple choice select list, something like the following:

public class CheckedList<T> : Dictionary<T, bool>

The idea is quite simply having a boolean value per each entity we want our users to be able to select. The dictionary also allows us not to worry about duplications…

then we add an HtmlHelper extension method:

public static class HtmlHelperExtensions
 {
 public static string CheckBoxList<T, TModel, TValue, TText>(this HtmlHelper<TModel> helper, string listName, string valueProperty,
 string textProperty, CheckedList<T> checkedList, Func<T, TValue> value, Func<T, TText> text)
 {
 StringBuilder builder = new StringBuilder();
 for (int i = 0; i < checkedList.Count; i++)
 {
 T item = checkedList.Keys.ToList()[i];
 builder.AppendLine("<p>");
 builder.AppendLine(helper.Hidden(listName + "[" + i + "].Key." + valueProperty, value(item)).ToHtmlString());
 builder.AppendLine(helper.Hidden(listName + "[" + i + "].Key." + textProperty, text(item)).ToHtmlString());
 builder.AppendLine(helper.CheckBox(listName + "[" + i + "].Value", checkedList[item]).ToHtmlString());
 builder.AppendLine(text(item).ToString());
 builder.AppendLine("</p>");
 }
 return builder.ToString();
 }
 }

This extension method could be refactored so that it’ll take Expression<Func… , that way we could extract the names of the value and text properties.

What’s left now to do is simply call the extension method from our View like so:

<%= Html.CheckBoxList("MyCheckedList", "Id", "Name", Model.MyCheckedList, x=>x.Id, x=>x.Name) %> 

Needless to say, this is only a demo and serves just to show what a check box list can be achieved; for more features and more possibilities, you could implement your very own IDictionary<T, bool>, that way you could extend and add whatever you need.

noice ๐Ÿ™‚

09/03/2010

Seeing that the post seem to get quite a few hits and finds itself on the first page of a google search for the terms ‘mvc checkbox list’, I thought I should provide a sample project on github. Let me know if there are any problems.

JQuery id with unauthorised characters

December 31, 2009

Yesterday was the second time I’ve found myself staring at the screen trying to figure out what just went wrong there, which in my book is the best trigger for writing a post. The problem is very simple:

In ASP.NET MVC, in order to get a collection (list/array/dictionary etc’) property of your view-model out back to the controller, you need to have your TextBox (or whatever) id attribute looking like this:

<input ... id="MyList[0].Name" ... />

More about it can be found here. Now, all is working nice and tidy until you bring JQuery in, which will not let you select such an object by its id (or any id that contains selector characters such as ‘.’, ‘:’ and so on) , so that the following code will return null:

$("#MyList[0]_Name")

My almighty, kind and generous boss has came up with a bit of code that will override this behviour, which I took liberties to refactor in order to take care of the ‘.’ and ‘:’ cases (even though dots shouldn’t really be a part of the id since the HtmlHelper extension methods in MVC replace dots with an underscore)-

function $$(selector, context) {
 return jQuery(selector.replace(/(\[|\]|:|\.)/g, '\\$1'), context)
}

So that all you need to do is:

$$("#MyList[0]_Name")

tidy! ๐Ÿ™‚

Using ASP.NET MVC dynamic SiteMap to simplify User/Role authentication

December 25, 2009

On of the security requirements of the app I’m working on is to let the admin user decide who can access what page. This is a fairly straight forward and rather frequent requirement, which most developers confront.

Now, since we’re working on an ASP.NET MVC project I had to have a look for an MVC SiteMapProvider, and came across this great work by Maarten Balliauw.

What we’ve done was overriding his Provider with a SQL-based one, to make it dynamic and more configurable. First and foremost, we’ve based our security model on a Role (or UserGroup if you prefer) with N Permissions (which translates to a Roles-Permissions many-to-many table). As soon as you establish this relation, when writing your SqlSiteMapProvider, in your BuildSiteMap() method you simply load only the current user Role Permissions property:

IList<Permission> permissions = _authenticationService.GetCurrentUserPermissions(userId);

And then you build your SiteMap graph with all the actions/operations/views the current user is permitted to access. Each Permission object has an Action and a Controller properties, and Maarten’s MvcSiteMapNode takes care of the Url property, using the Action and Controller properties. The Permission would also have a ParentPermission and ChildPermissions (in which case you’d only have to load all orphan- first level- permissions of current user role and eagerly fetch the child permissions bag property). On top of that, the permission Id property could work for the SiteMapNode Key.

What you’ve got now is a dynamic site map constructed according to the current user role/permissions. How do you use it then to know if the user is authorised to access a certain View? Quite simply, in your CustomBaseController, overriding the OnActionExecuting method you add:

if (SiteMap.Provider.CurrentNode == null) throw new AuthenticationException();

That simple ๐Ÿ™‚