TwitterFacebookGoogle

Interview Question : Following DRY

I’ll be posting potential interview questions that I come up with from time to time on my blog – so that I can refer to it later and also to share them with others. Here is one I came up with today:

Re-write the following code-snippet so that it complies with the DRY principle:

 
if(!_autoenroll)
{
     if(displayEnrollPage == true)
     {
        ltlView1.Text = "Enroll Online - Page 1 of 4";
        ltlView2.Text = "Enroll Online - Page 2 of 4";
        ltlView3.Text = "Enroll Online - Page 3 of 4";
        ltlView4.Text = "Enroll Online - Page 4 of 4";
     }
     else
     {
        ltlView1.Text = "Enroll Online - Page 1 of 3";
        ltlView2.Text = "Enroll Online - Page 2 of 3";
        ltlView3.Text = "Enroll Online - Page 3 of 3";
 
        // don't set header for the 4th page because it wont be visible.  
    }
}
else 
{ 
     if(displayEnrollPage == true)
     {
        ltlView1.Text = "Enroll Online - Page 1 of 3";
        ltlView2.Text = "Enroll Online - Page 2 of 3";
        ltlView4.Text = "Enroll Online - Page 3 of 3";
     }
     else
     {
        ltlView1.Text = "Enroll Online - Page 1 of 2";
        ltlView2.Text = "Enroll Online - Page 2 of 2";
 
       // don't set header for 4th page because it wont be visible.       
    }
}

No, I won’t be posting the answers. But feel free to suggest one inside the comments section!

Twitter Email Linkedin Digg Stumbleupon Subscribe

Rendering Icons as links in ASP .NET MVC

Modifying the behaviors of HTML helper methods such as ActionLink is a pain and requires quite a bit of code. Sometimes, however, you get lucky and are able to avoid it. What follows is once such case.

Here is one quick way that you can use to render an icon as a link in ASP .NET MVC.

First, create a CSS style for the icon:

 .print-icon {
    background: url("/assets/print-icon.png");
 }

Next, use it when generating the link:

  @Html.ActionLink(" ", "Action", new { id = /* blah */ }, new { @class = "print-icon" }

And, that does it!

Cheers!

Twitter Email Linkedin Digg Stumbleupon Subscribe

Integrating TypeMock with ASP .NET Unit tests

When it comes to writing unit tests for your ASP .NET pages, there isn’t much help out there. I experimented with a few open source testing tools and found some major limitations.

Both NUnitAsp and WaitN, for instance, are “client-side” tools. In other words, you have to write your tests against the actual HTML output. For example, to get the value of a textbox, you have to specify the actual HTML id of the textbox. That’s painful! Especially, since ASP .NET ends up assigning long and complicated ID’s to your controls. Plus NUnitAsp is no longer being maintained or supported.

Unlike NUnitAsp and WaitN, VS Studio ASP .NET Unit testing let’s you examine the actual HttpRequest object. What this means is that you can call methods on your Page and get access to the controls within the page. VS Studio ASP .NET is a pretty decent tool and maybe the answer for you. IF you don’t need to use TypeMock that is. But if you do, then tough luck because VS Studio ASP .NET unit tests don’t work with TypeMock. If you give it try, you’ll get the following exception:

Test method AzAsh.WebApp.Tests.DefaultTest.LoginNotRequiredTest threw exception:  TypeMock.TypeMockException: 
*** Typemock Isolator is not currently enabled. 
To enable do one of the following:

* To run Typemock Isolator as part of an automated process you can:
   - run tests via TMockRunner.exe command line tool
   - use 'TypeMockStart' tasks for MSBuild or NAnt

* To work with Typemock Isolator inside Visual Studio.NET:
        set Tools->Enable Typemock Isolator from within Visual Studio

For more information consult the documentation (see 'Running' topic).

Check the enable property as they have suggested and you’ll notice that Typemock is enabled! So, what gives? I have no idea. But I do know that Ivonna – a ASP .NET testing tool that is being developed in partnership with TypeMock WILL let you work in conjunction with TypeMock. Like VS Studio, it allows you to examine the intrinsic objects, such as the Page object. In addition, it’s got another neat feature that let’s you inject setup code and assertions into your page’s lifecycle event handlers – very handy especially during type mocking. The only drawback is that it’s a little slow. The unit tests take a while to run.

So if you’ve been scratching your head trying to figure how to develop ASP .NET tests that can work with TypeMock, Ivonna is probably the tool you’ve been waiting for!

Twitter Email Linkedin Digg Stumbleupon Subscribe

Update Panels dont play well with Validators in Chrome

If your page uses ASP .NET custom validators and an UpdatePanel, you will notice that your UpdatePanels will not work in Chrome. In order to fix this, you will have disable client script on the custom validators by setting EnableClientScript=false.

Hopefully this tip will save others the headache that I went through!

Happy Coding!

Twitter Email Linkedin Digg Stumbleupon Subscribe

Making ASP .NET Gridview a little less painful

Isn’t it pain in the neck when you have to write the following for every input control whose value you want to extract from a Gridview:

public static void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
   string firstname = ((TextBox)myGridview.Rows[e.RowIndex].
                                            FindControl("txtFirstname")).Text;
   string lastname = ((TextBox)myGridview.Rows[e.RowIndex].
                                            FindControl("txtLastname")).Text;
 
   //....and so on.. 
}

Well, you can make it a little easier by implementing the following method either in a class that extends GridView or by writing a extension method. In this example, I’ve written it as an extension method.

public static T FindControl<T>(this GridView gridView, string cntrlName, 
                                          int rowIndex)
      where T : Control
{
   return (T)(gridView.Rows[rowIndex].FindControl(cntrlName));
}

Now the code inside my page is little cleaner and easier to write:

public static void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
   string firstname = gridView.FindControl<TextBox>("txtFirstname", e.RowIndex).Text;
   string lastname = gridView.FindControl<TextBox>("txtLastname", e.RowIndex).Text;
 
     //....and so on.. 
}

I admit it’s not something huge but it definitely is a big help when you have to type in that statement for every single control in your Gridview!

I hope that helps some!

Twitter Email Linkedin Digg Stumbleupon Subscribe

An easier way to write HTML input forms

Consider the block of code below:

<table cellpadding="3">
  <tr>
    <td valign="top">
      <b>First Name</b>
    </td>
    <td>
      <asp:TextBox ID="txtFirstName" runat="server" />
      <div>
        Please enter your first name.</div>
    </td>
  </tr>
  <tr>
    <td valign="top">
      <b>Last name</b>
    </td>
    <td>
      <asp:TextBox ID="txtLastName" runat="server" />
      <div>
        Please enter your last name.</div>
    </td>
  </tr>
</table>

The rendered output looks something like this:
HTML Input Form
You will notice that we have to repeat the
and the tags, along with any style information that these contain, for every row of our input form. Ouch! That's a lot of typing. Furthermore, if, in the future, we have make layout and/or style related changes, we'd have to modify all the pages in our application that contain these HTML input forms! Fortunately, there is an easier way.

By implementing a couple of simple ASP .NET server controls, we will save ourselves the trouble of typing the above shown HTML and will be able to simply type the following:

<cc:Form runat="server">
  <cc:FormField runat="server" Name="First Name" 
                      Description="Please enter the first name.">
    <asp:TextBox ID="txtFirstName" runat="server" />
  </cc:FormField>
  <cc:FormField runat="server" Name="Last Name" 
                     Description="Please enter the last name.">
    <asp:TextBox ID="txtLastName" runat="server" />
  </cc:FormField>
</cc:Form>

Now isn't that soo much more pleasant to the eyes and easier on your fingers? So how is this accomplished? As follows:

First, create a ASP .NET Server Control name Form.cs. This simple control will simply render the

tags. Below is the code for it:

public class Form : WebControl
{
  public override void RenderBeginTag(HtmlTextWriter writer)
  {
    writer.Write("<table cellpadding='3'>");
  }
  public override void RenderEndTag(HtmlTextWriter writer)
  {
    writer.Write("</table>");
  }
}

Notice the use of [ParseChildren(false)] attribute. This attributes ensures that 1) we will be able to nest additional controls inside this control and 2) The nested control won't actually become a child control this control. The second point is important and will explained in greater detail shortly.

Now we move on to the more interesting control: the FormField.cs control. This control renders the

's, tag
  • The column that contains the input field label. For example:
    <td><b>First Name</b></td>
  • The opening
  • tag for the column that contains the actual input field.

  • The
    tag containing the input field description. For example:

    <div>Please enter the first name</div>
  • The closing
  • tag

    Well, that all sounds well and good. But wait! Where is the FormField control rendering the actual input field (the asp:TextBox)? The answer is that it isn’t. The use of the [ParseChildren(false)] attribute prevents the parsing of any embedded controls that FormField may have. Thus, in our example, when the Form and the FormField control's rendering has finished, the page control tree looks something like this:

    
    - Page
      - Form
      - FormField
      - LiteralControl("
    's, the input field label, and the input field description. Below is the code for it:

    [ToolboxData("<{0}:FormField runat=server></{0}:FormField>"), ParseChildren(false)]
    public class FormField : WebControl
    {
      public string Name
      {
        get { return ViewState.GetAsString("Name"); }
        set { ViewState["Name"] = value; }
      }
      public string Description
      {
        get { return ViewState.GetAsString("Description"); }
        set { ViewState["Description"] = value; }
      }
      public string NameAlign
      {
        get { return ViewState.GetAsString("NameAlign"); }
        set { ViewState["NameAlign"] = value; }
      }
      public string ControlAlign
      {
        get { return ViewState.GetAsString("ControlAlign"); }
        set { ViewState["ControlAlign"] = value; }
      }
      public override void RenderBeginTag(HtmlTextWriter writer)
      {
        string beginHtml = @"<tr><td align={0}><b>{1}</b></td><td align={2}>";
        writer.Write(string.Format(beginHtml, NameAlign, Name, ControlAlign));
      }
      public override void RenderEndTag(HtmlTextWriter writer)
      {
        string endHtml = @"<div>{0}</div></td></tr>";
        writer.Write(endHtml, Description);
      }
    }

    The interesting parts of the class are the RenderBeginTag() and the RenderEndTag() methods. If you inspect these methods, you’ll see that the RenderBeginTag() is responsible for rendering:

    • The opening
    tag for the column that contains the actual input field (like the , for example)

    And the RenderEndTag() method is responsible for rendering:

    • The closing
    ") - LiteralControl("
    ") - TextBox - LiteralControl("
    Please enter first name
    ") .....

    Notice that the TextBox (txtFirstName) is a child of the Page instead of being a child of the FormField control. What this means is that instead of having to type something convoluted like:

    string firstName = ((TextBox)this.formField1.FindControl("txtFirstName")).Text;

    your page can directly reference the TextBox like so:

    string firstName = txtFirstname.Text

    I hope you’ve found this post helpful and informative. Please take some time to leave your feedback and/or comments to help me improve.

    Twitter Email Linkedin Digg Stumbleupon Subscribe
    CyberChimps