Thursday, December 2, 2010

Easy Ajax with ASP.NET MVC and Jquery

One of the reasons I love MVC and Jquery is it makes client side coding so easy.  Here is a good example.  Lets say I want to have a html select control that updates automatically when it’s changed
First we build a Controller that has an action to output our view and an action to accept posts
   1: [HandleError]
   2: public class HomeController : Controller
   3: {
   4:     public ActionResult Index()
   5:     {
   6:         UserModel userModel = new UserModel(){UserId = 1,Type = UserTypes.User};
   8:         return View(userModel);
   9:     }
  11:     [AcceptVerbs(WebRequestMethods.Http.Post)]
  12:     public ActionResult UpdateUserType(UpdateUser input)
  13:     {
  14:         var result = new {Succss = true, Message = "Updated"};
  15:         return Json(result);
  16:    }
  17: }
notice UpdateUserType() has the attribute “[AcceptVerbs(WebRequestMethods.Http.Post)]” this forces it to only allows posts, also it takes a complex type, in this case a class of type UpdateUser.
Here is a quick over view of the model objects we are going to be using
   1: public class UserModel
   2: {
   3:     public int UserId { get; set; }
   4:     public UserTypes Type { get; set; }
   5: }
   7: public enum UserTypes
   8: {
   9:     User = 1,
  10:     PowerUser = 2,
  11:     Admin = 3
  12: }
  14: public class UpdateUser
  15: {
  16:     public int UserId { get; set; }
  17:     public UserTypes Type { get; set; }
  18: }
one of the nice this is that MVC takes care of the mapping and casting for us as you’ll see in a second.
The view is a very simple and strongly typed for the UserModel, first build the select control
   1: <select name="SelectUserType" onchange="UpdateUserType(this,<%=Model.UserId%>)">
   2:     <%foreach (UserTypes item in Enum.GetValues(typeof(UserTypes)).Cast<UserTypes>())
   3:     {
   4:             if(item ==  Model.Type)
   5:             {
   6:                 %><option selected="selected" value="<%=((int)item).ToString() %>"><%=item.ToString() %></option><%
   7:             }
   8:             else
   9:             {
  10:                 %><option value="<%=((int)item).ToString() %>"><%=item.ToString() %></option><%
  11:             }
  12:     } %>
  13: </select>
this loops through the UserTypes Enum to populate the select control and selects the value that’s selected in the view Model and we add an onchange that points to a javascript function that we pass the control and the UserId from the model into.
Next we add the javascript function(fyi this requires Jquery)
   1: <script type="text/javascript">
   2:     function UpdateUserType(sender, userId) {
   3:         var model = { UserId: userId, Type: sender.value };
   4:         $.post("/home/UpdateUserType",
   5:             model,
   6:            function (data) {
   8:                alert("Was Successful: " + data.Succss);
   9:                alert("Message: " + data.Message);
  10:            });
  11:     }
  12: </script>
First we build a JSON object where the property names need to match the properly names in UpdateUser, MVC needs this for mapping, and then we use Jquery $.post passing in the action URL, the JSON object we just built, and a javascript function to handle the returned data and your done.

A quick and easy way to add Ajax to any control and as always here is a link to the demo project

Thursday, July 22, 2010

The evil of process over craftsmanship

If you had a choice between a well build home that cost more money but wasn’t going to cost very much to maintain or a house that didn’t cost very much, but was going to cost a lot more to maintain in the long run, which would you choose.  If you own a house and have had to deal with the upkeep of the home I can almost guarantee you would much rather have the first house, even if fixing the major problems is free (most new houses come with a one year guarantee from the builder), if you have ever had to deal with getting your builder to fixed things, free or not, the stress and aggravation almost makes it not worth it.  So why do so many software development teams almost insist on building software like how the second house was built.

By taking the time to build a quality product, it will cost more up front, talented people cost money, to do the job right takes time(time=money) but because it was done right the first time it costs a lot less in the long run. 
Unfortunately in the software development world it’s far to common to just get it out and worry about fixing known problems later.  This becomes even more painful when the schedule or process becomes the reason for poor craftsmanship.

Here are two problems, one is building a house the other is building software:

1) A builder starts working on a house and discovers that the property has a high water table and that every spring there would be flooding in the crawlspace.  The two ways to solve this problem are: bring in enough dirt to raise the house up so the crawlspace doesn't get flooded or add subpumps to pump the water out.  Both fix the problem, while the subpumps are going to be quicker to setup, it’s not going to get out all of the water and it will add to maintenance costs which in the long run will be much more expensive.

2) A pair of developers are tasked with writing a service for importing data into a database and half way though writing it they find out the data has duplicate records and some other garbage data.  There are two ways to solve this, build a validator to remove the garbage data or pass it off and have the DBAs create a job to remove the garbage from the database.

I’m fairly sure we would all much rather take the time to put in the fill dirt then have to deal with the maintenance of having sub pumps, and yet for some reason it’s very common for developers to be told “we don’t have time to add a filter” and to push the task of removing the garbage from the database onto the DBAs, or worse yet just live with the garbage data.

We know that when the process(schedule/tasking) trumps craftsmanship(using subpumps or having the DBAs remove bad data) you end up with a lower quality product with higher overall costs so why do we still do it?
The tools of the software craftsman: TDD, design patterns(command, strategy, observer, etc ), decoupled design, source control, continues integration, paired programming, etc.  and by using any of them you will end up with better software with lower overall costs and yet it feels like it’s a constant battle to get them into our development process.  We need to take a stand, we need to be craftsman and insist on building quality products.

Friday, May 28, 2010

Using the Observer Pattern

At work we are reading “Head First Design Patterns” and discussing the “Observer Pattern” and some people wanted to see a code example.
The first part is the the class that manages the observer classes
   1: public class EventManager<T>
   2: { 
   3:     private Dictionary<string, ISubscriber<T>> _subscribers = new Dictionary<string, ISubscriber<T>>();
   4:     public Dictionary<string,ISubscriber<T>> Subscribers
   5:     {
   6:         get { return _subscribers; }
   7:         set { _subscribers = value; }
   8:     }
  10:     public void Notify(T newState)
  11:     {
  12:         foreach (var observer in Subscribers.Values)
  13:         {
  14:             observer.State = newState;
  15:             observer.Update();
  16:         }
  17:     }
  18: }
In this example I created a generic class that has two basic parts a collection of subscribers or observers and a method that loops though and updates the state of the subscribers.  I used a Dictionary<string,ISubscriber<T>> to make it easy to manage my subscribers based on a key, and because ISubscriber<T> is also a generic its a very flexible and strongly typed way to work with the subscribers.

Next let’s take a look at ISubscriber<T> interface
   1: public interface ISubscriber<T>
   2: {
   3:     T State { get; set; }
   4:     void Update();
   5: }
it’s that simple, I use generics to determine the state and the input type for the update method, here is an example implementation
   1: public class TweetLocation : ISubscriber<Location>
   2: {
   3:     public ITwitter TwitterInterfacer = new FakeTwitterClient();
   4:     public Location State { get; set; }
   6:     public void Update()
   7:     {
   8:         TwitterInterfacer.TweetMessage(string.Format("currently at ({0},{1})",State.Lat,State.Lon));
   9:     }
  10: }
TweetLocation is observing Location information and calls a Twitter class to Tweet the new location when updated, for something a little more complex
   1: public class SaveLocation : ISubscriber<Location>
   2: {
   3:     public ILocationReposigtory LocationRepository = new FakeLocationRepository();
   4:     public static EventManager<string> ErrorHandler = new EventManager<string>();
   6:     public Location State{get;set;}
   8:     public SaveLocation()
   9:     {
  10:         ErrorHandler.Subscribers.Add("ErrorMailer",new ErrorMailer());
  11:     }
  13:     public void Update()
  14:     {
  15:         bool success = LocationRepository.SaveLocation(State);
  16:         if (!success)
  17:         {
  18:             ErrorHandler.Notify("Failed to save location");
  19:         }
  20:     }
  21: }
SaveLocation is basically the same as TweetLocation except it has it’s own EventManager to handle errors from failed attempts at saving the location.

Finally here is an example of actually using it
   1: class Program
   2: {
   3:     public static EventManager<Location> LocationHandler = new EventManager<Location>();
   5:     static void Main(string[] args)
   6:     {
   7:         LocationHandler.Subscribers.Add("Repository",new SaveLocation());
   8:         LocationHandler.Subscribers.Add("Twitter",new TweetLocation());
  10:         Location currentLocation = new Location(){Lat = 111,Lon = -121};
  12:         LocationHandler.Notify(currentLocation);
  14:         Console.ReadKey();
  16:         currentLocation.Lon = 1211;
  17:         LocationHandler.Subscribers.Remove("Twitter");
  18:         LocationHandler.Notify(currentLocation);
  20:         Console.ReadKey();
  23:     }
  24: }
This is a simple console app that demonstrates adding subscribers, updating state, and removing a subscriber. 

A real world example of using “Observer Pattern” is a service bus like NServiceBus or MassTransit, where an event driven application needs to send messages to one or more subscribers.

As always here is a link to the project source.

Wednesday, May 12, 2010

Another walk in the cloud with Amazon Web Services

Talking a look at some of the offering that Amazon Cloud Services has I decided to take a look at Amazon Simple Storage Service or simply Amazon S3. 

Like I wrote in “A walk in the Cloud” the Amazon cloud can be accessed though a web service so you have the option of rolling your own tools or using their API lib.  The has SDK has defiantly improved and the install process is a lot easier now.  Before you had to download the source, build the project, etc, now all you have to do is download AWSSDKForNET and install it.  This adds the Clint to your GAC, and add templates into Visual Studio, if you still want to see what they are doing under the hood you can still download the source. 

Amazon may not provide you with any tools but there are a few free ones that work fairly well.  CloudBerry Explorer is a fairly solid tool for managing your S3 storage, it looks kind of like an ftp client and it lets you manage multiple accounts, create buckets, upload/download content, generate web URLs(http and https), search, etc. Another client is the Firefox plug-in S3Fox, basically the same as CloudBerry but it runs in Firefox.

Pulling data from S3 is relatively simple, this is a code sample for pulling your list of buckets, then building a list of links to the images in each bucket
   1: AmazonS3 s3Client = AWSClientFactory.CreateAmazonS3Client(
   2:     ConfigurationManager.AppSettings["AWSAccessKey"],
   3:     ConfigurationManager.AppSettings["AWSSecretKey"]);
   5: ListBucketsResponse response = s3Client.ListBuckets();
   7: foreach (S3Bucket bucket in response.Buckets)
   8: {
   9:     HtmlGenericControl header = new HtmlGenericControl("div")
  10:     {
  11:         InnerText = bucket.BucketName
  12:     };
  14:     DivlistOfImages.Controls.Add(header);
  16:     ListObjectsRequest request = new ListObjectsRequest
  17:      {
  18:          BucketName = bucket.BucketName
  19:      };
  20:     ListObjectsResponse imageList = s3Client.ListObjects(request);
  22:     foreach (S3Object s3Object in imageList.S3Objects)
  23:     {
  24:         HtmlAnchor imageLink = new HtmlAnchor
  25:        {
  26:            InnerText = s3Object.Key
  27:        };
  28:         string bucketName = bucket.BucketName;
  29:         string objectKey = s3Object.Key;
  30:         GetPreSignedUrlRequest preSignedUrlRequest = new GetPreSignedUrlRequest
  31:          {
  32:              BucketName = bucketName,
  33:              Key = objectKey,
  34:              Protocol = Protocol.HTTP,
  35:              Expires = DateTime.Now.AddDays(7)
  36:          };
  39:         imageLink.HRef = s3Client.GetPreSignedURL(preSignedUrlRequest);
  40:         DivlistOfImages.Controls.Add(imageLink);
  41:     }
  42: }
it’s that simple.

With this you can have your content be managed by another department with a tool like CloudBerry and remove the work of updating images and other forms of content. 

As always here is a link to the sample code project