My Resume | Contact Me | RSS Feed | Follow Me on Twitter

Code Capers

The Ninja Coding Dojo
RSS Feed Twitter Email

ASP.NET WebForms vs. MVC

clock June 30, 2009 by author Michael Ceranski

At my first programming job, I remember sending an application to a customer via FTP. In order to make the process easier, I downloaded a feature-rich FTP client and started uploading files. I remember my boss, Cliff, came into my office and took one look at my monitor and said "You kids and your fancy GUIs". This was Cliff's way of saying that I really did not need to download a fancy program in order to upload a single file.

On a similar note, when it comes to ASP.NET I often feel that Webforms masks developers from the real truth about real web development. If Cliff was here, he would probably say something like "You Kids and Your Fancy Webforms!".

I remember the classic ASP days when I would develop custom scripts to create a data grid. I spent hours adding features like sorting and paging. There was quite a bit of code involved and I took the painstaking steps to try to reduce the amount of roundtrips to the server and to optimize the HTML that was generated. Nowadays, with Webforms you can drop a DataGridView control onto a form, enter a select statement and you are done. I really like the way that Rob Conery describes Webform development on his blog:

WebForms is a lie. It's abstraction wrapped in deception covered in lie sauce presented on a plate full of diversion and sleight of hand. Nothing you do with Webforms has anything to do with the web - you let it do the work for you.

Now don't get me wrong here. I really appreciate tools that allow me to focus on the business logic rather than all the non-value added issues. However, my fear is that we are going to end up with a generation of developers who do not understand basic things like binary code or hex. With tools like Visual Studio we are developing at such a high level that we lose sight of the fact of how things really work under the covers.

One of the things that I really like about ASP.NET MVC is that we have gotten away from the PostBack and "Magic State" paradigm. There is a clear line between what causes a post back and what does not. Furthermore, If you want to maintain state for a page then you explicitly need to do it in your code. For these reasons, I feel like MVC has once again given me back full control over my HTML.

Let me end this post by stating that these are only my opinions. I am not saying that Webforms is better than MVC or vice-versa. After all, there is nothing stopping you from adding a Webform to a MVC project. In some cases it may be required (such as adding a SSRS Report Viewer to a web application which requires Postback). I guess when it comes to coding I am a control freak. There are times when it is nice for a tool to do the work for you as long as you have a true understanding of what really is happening behind the scenes.



Generating Code with Visual Studio's T4

clock June 29, 2009 by author Michael Ceranski

visualstudioHave you ever wanted to generate some html, C# or other code on the fly? Most of us have done this by either appending strings in code or writing content to a text file. If you need more advanced capabilities in your code generation then maybe you even resorted to a third party library like StringTemplate. Well these techniques are no longer needed due to the powerful T4 Text Template engine that is available with Visual Studio 2005 and above.

T4 was originally intended to be used as a mechanism for DSLs (Domain Specific Languages) to programmatically generate code. However T4 is flexible enough that it can be used for anything. For example, if you have been experimenting with ASP.NET MVC, then perhaps you are a little unsatisfied with the markup generated by Visual Studio for Views. Well, T4 is a perfect tool for you to generate your own custom markup. Here is a quick example on how to use T4:

If you are using Visual Studio 2005 then you will need to install the DSL Tools first. The tools are not needed if you are using Visual Studio 2008

Steps

1. Launch Visual Studio and create a new C# console project.
2. Create a new text file and name in HelloT4.tt. The extension is important because Visual Studio will recognize the extension and use a tool named TextTemplateFileGenerator to generate an empty cs file named HelloT4.cs.
3. Modify HelloT4.tt so it contains the following text

<#@ template language="C#">
using System;   

public class <#= this.ClassName #>
{
   public static void HelloT4()
   {
      Console.WriteLine("T4 can write code!");
   }
}
<#+ string ClassName = "MyT4Class"; #>

Visual Studio will automatically regenerate the HelloT4.cs file whenever you make changes to the template file (HelloT4.tt). Alternatively, you can right click on the template file in Solution Explorer and select the "Run Custom Tool" option. Here is the code that was generated from our sample script:

using System; 

public class MyT4Class
{
    public static void HelloT4()
    {
        Console.WriteLine("T4 can write code!");
    }
}

T4 can be used directly within a project as I demonstrated above or you can use the command line tool.

Other Resources:
GenerationBestKeptVisualStudioSecret.aspx" target="_blank">T4 (Text Template Transformation Toolkit) Code Generation - Best Kept Visual Studio SecretT4, Visual Studio 2008's Best Kept Secret
Visual T4 - Editor used to make T4 scripts
T4: Text Template Transformation Toolkit
T4 Toolbox - T4 Template Library



ASP.NET - Creating a Custom Tag Cloud

clock June 26, 2009 by author Michael Ceranski

I recently wrote a web application and I wanted to create my own tag cloud. Since I was writing an MVC application I decided to use the HtmlHelper class. In case you are not familiar with it, here is a small description from MSDN:

The HtmlHelper class provides a set of helper methods whose purpose is to help you create HTML controls programmatically. All HtmlHelper methods generate plain HTML and return the result as a string.

Extensions to the HtmlHelper class are located in the System.Web.Mvc.Html namespace. These extensions add helper methods for creating forms, rendering HTML controls, rendering partial views, input validation, and more.

All helper methods and extensions are called using the Html property of the view, which is an instance of the HtmlHelper class. For example, to generate a check box in your form, you would call the Html.CheckBox method.

In order to store the data for my tag cloud I decided to use XML. Yes, I could have used a database for my tag cloud but I wanted this component to be independent enough where I could easily plop it into another web app without having to require a database. To make the process of loading and saving the data to XML easier I used the System.Data.DataSet class. Simply because the DataSet class already has methods for dealing with XML (ReadXml and WriteXml). The first time the tag cloud is rendered I load the XML file from disk into a DataSet which in turn, creates a single DataTable containing all of my "tag" data. Here is the code for creating the dataset, and reading and writing the XML:

   1:     private static DataSet CreateDataSet() {      
   2:        DataSet dataSet = new DataSet();
   3:        DataTable table = new DataTable( "TagCloud" );         
   4:        table.Columns.Add("key", typeof(string));
   5:        table.Columns.Add("value", typeof(int));
   6:        dataSet.Tables.Add(table);
   7:        return dataSet;      
   8:     }
   9:   
  10:      private static void SaveToXML() {
  11:          try {
  12:              DataSet dataSet = CreateDataSet();
  13:              var qry = from x in Cloud
  14:                           orderby
  15:                              x.Key,
  16:                              x.Value
  17:                           select x;
  18:              DataTable table = dataSet.Tables["TagCloud"];
  19:   
  20:              foreach (var item in Cloud.Take(CLOUD_SIZE)) {
  21:                  DataRow row = table.NewRow();
  22:                  row["key"] = item.Key;
  23:                  row["value"] = item.Value;
  24:                  table.Rows.Add(row);
  25:              }
  26:              dataSet.AcceptChanges();
  27:              dataSet.WriteXml(XMLFile, XmlWriteMode.WriteSchema);
  28:          }
  29:          catch {
  30:              //
  31:          }
  32:      }
  33:   
  34:     private static void LoadFromXML() {
  35:        if(System.IO.File.Exists(XMLFile) == false)
  36:           return;
  37:   
  38:          _cloud = new Dictionary<string, int>();
  39:        _cloud.Clear();
  40:   
  41:          DataSet dataSet = CreateDataSet();
  42:          dataSet.ReadXml(XMLFile, XmlReadMode.ReadSchema);
  43:        DataTable table = dataSet.Tables["TagCloud"];
  44:        foreach(DataRow row in table.Rows) {
  45:           _cloud.Add(row["key"].ToString(), (int)row["value"]);
  46:        }
  47:     }

To add a tag to the cloud you call the AddTag method. This just adds a row to the static variable used to store the tag information. In my case, I immediately flush the updates to the XML file but you could do occasional updates or rely on the Application_End method of the Global.asax file to persist the data to disk. Here is the code:

   1:      public static void AddTag(string tag) {
   2:          tag = tag.ToLower();
   3:   
   4:          if (Cloud.ContainsKey(tag) == false)
   5:              Cloud.Add(tag, 1);
   6:          else {
   7:              int value;
   8:              if (Cloud.TryGetValue(tag, out value) == true) {
   9:                  Cloud[tag] = value + 1;
  10:              }
  11:          }
  12:   
  13:          SaveToXML();
  14:      }
 

To render the HTML for the tag cloud I use the code below. This is simply an extension method which utilizes the HtmlHelper class. You will notice that I hardcoded the CSS class names. You could optionally pass these in as variables or explicitly set the style in the markup. Since you are rendering the HTML you can do whatever you want.

   1:      public static string TagCloud(this HtmlHelper htmlHelper, bool showFrequency ) {        
   2:   
   3:          StringBuilder sb = new StringBuilder();        
   4:          var qry = from x in Cloud                      
   5:                       orderby                        
   6:                          x.Key,
   7:                    x.Value
   8:                       select x;        
   9:          
  10:          sb.Append("<ul id='tagCloud'>");
  11:   
  12:          var results = qry.Take(CLOUD_SIZE);
  13:          
  14:          if (results.Count() == 0) return String.Empty;
  15:   
  16:          double largest = results.Max(x => x.Value);                
  17:          
  18:          foreach (var item in qry.Take(CLOUD_SIZE)) {
  19:              double val = Convert.ToDouble(item.Value);
  20:              sb.Append("<li>");
  21:              if (val.Between(0.0, largest * .25))
  22:                  sb.Append("<a class='small' ");
  23:              else if (val.Between(largest * .25, largest * .50))
  24:                  sb.Append("<a class='medium' ");
  25:              else if (val.Between(largest * .50, largest * .75))
  26:                  sb.Append("<a class='large' ");
  27:              else
  28:                  sb.Append("<a class='xlarge' ");
  29:   
  30:              sb.Append(" title='" + item.Value + " hit(s)' href='/Search/" + item.Key.UrlEncode() + "'>" + item.Key + "</a></li>");
  31:              sb.Append( "<li><a class='freq'>(" + item.Value + ")</a></li>");            
  32:          }
  33:          sb.Append("</ul>");
  34:   
  35:          return sb.ToString();
  36:      }

Finally, on the page I want to display the tag cloud I need to add this line of code:

<%= Html.TagCloud() %>

Here is the result:

 

References:

ASP.NET MVC: Using the MVC UI Helpers
ASP.NET Application variables or Static Members?
.NET Static Variables : Better than Application!



Goodbye Wii, Hello Project Natal

clock June 25, 2009 by author Michael Ceranski

The Nintendo Wii has revolutioned video gaming by giving users the ability to physically interact with games via the Wiimote. The wiimote has motion sensing capability, which allows you to manipulate items on the screen via the use of the accelerometer and optical sensor technology. One of the best games that demonstrates the wiimotes capabilities would have to be Wii Sports. The bowling, golfing, boxing, baseball and tennis game bundled in the Wii Sports package make you feel like you are actually playing a real game. Of course, it was only a matter of time before someone else took the idea to the next level. That someone else, is Johnny Lee.

Johnny recently graduated with a PhD from Carnegie Mellon in Human-Computer Interaction. You probably already know Johnny from his popular Wiimote experiments which he documented on his website. In any case, Johnny really got the attention of Microsoft where he now works as a researcher in the Applied Sciences group. Since he started at Microsoft he has been working on Project Natal. Project Natal allows you to have the Wii user experience without any controllers (So that means they will have to charge more for the console). The video below speaks for itself.



Debugging with Different Browsers in Visual Studio 2008

clock June 24, 2009 by author Michael Ceranski

Most of the time when I am developing web applications I like to test things out in Firefox first. Since Firefox has a better history with being compliant to standards I generally find that if my CSS and HTML work in Firefox then it will work in IE. Getting Visual Studio to debug with Firefox or any other browser in Visual Studio 2008 is extremely simple.

In the Solution Explorer, right click on an aspx page (I chose the startup page Default.aspx) and select Browse With. You will be presented with the following dialog:

browse_with

Select the browser you want to load up when you debug the application and click the Set as Default button. That's it, we are done! When you debug you should now get a FireFox window instead. If you want to revert back to IE later on then just follow the same steps but choose Internet Explorer as the default.



About the author

MikeMy name is Michael Ceranski. I am a software developer from Buffalo NY. I have been writing code for over 10 years starting with Borland Delphi and later migrating to the .NET stack. I enjoy blogging about .NET, MVC and jQuery and I hope to spread my enthusiasm for technology by sharing my thoughts and ideas with you.

View my resume

Cumulus

This will be shown to users with no Flash or Javascript.

Sign in