Friday, July 24, 2009

Registering Custom HttpModule in IIS7 Web.config

I’ve been writing an Error Hander HttpModule for a current ASP.NET WebForm project and things were going well until my last merge with TFS. All of a sudden, my HttpModule wouldn’t register anymore.

For the life of me I couldn't’ figure out what had changed. I spent half the day trying to figure out what in the world was going on.

Here is the chain of events that I tried before finding the actual solution. If you want, you can just skip to the end to find the answer :)

First, I decided to strongly sign the assembly with the HttpModule (even thought it wasn’t necessary previously)…

So, I created a new Strong Name Key from the properties window of my HttpModule project from Visual Studio 2008

CreateKey

Then, in order for me to get the Public Key Token to decorate the HttpModule entry in the web.config, I used the following command line tool
sn –T ErrorFramework.dll

Note: You might consider integrating this command into a Get Public Key Token External Tool in Visual Studio 2008.

Here is what my original web.config entry looked like before:

<add name="ExceptionModule" type="ErrorFramework.ExceptionModule, ErrorFramework" /> 

and after all of the above steps I was able to update my web.config to the following:

<add name="ExceptionModule" type="ErrorFramework.ExceptionModule, ErrorFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7125b1d9a03db888" />      

However, to my dismay the HttpModule still did not register!

Secondly, I tried dynamically registering my HttpModule in the Global.asax instead of relying upon the web.config.

namespace ErrorFramework
{
    public class Global : System.Web.HttpApplication
    {
        public static ExceptionModule errorModule = new ExceptionModule();

        public override void Init()
        {
            base.Init();
            exceptionModule.Init(this);
        }
    }
}

This thankfully worked fine, but I really wanted the web.config option to work so that I could add or remove the HttpModule at will without having to change and recompile code.

Thirdly, I decided to use Visual Studio’s internal webserver (Cassini).

To my surprise the HttpModule started to work again! Although, I was excited that it worked… I was also very confused because I thought it should work through IIS7 as well. So, back to the drawing board.

Fourthly, I finally found the answer I was looking for.

Apparently, IIS7 looks in the system.webSever/modules section of the web.config and not in the system.web/httpModules section like IIS5 & IIS6. It turns out that the web.config that our project has both sections defined in the config file!

So, instead of this…

<system.web>
    <!-- Misc XML -->
    <httpModules>
        <add name="ExceptionModule" type="ErrorFramework.ExceptionModule, SG.SSP.Darwin.WebPortalFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7125b1d9a03db888" />      
    </httpModules>
    <!-- Misc XML -->
</system.web>

I needed to do this…

<system.webServer>
    <!-- Misc XML --> 
    <modules> 
        <add name="ExceptionModule" type="ErrorFramework.ExceptionModule, SG.SSP.Darwin.WebPortalFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7125b1d9a03db888" /> 
    </modules>
    <!-- Misc XML --> 
</system.webServer>

Note: If you want it to work both on IIS7 and through Cassini, then you’ll need to define it in both places ;)

Thursday, July 23, 2009

Telerik RadControls for ASP.NET AJAX Giveaway

In case you haven’t noticed, I’ve recently switched from using Blogger to using dasBlog hosted on ORCS Web and in an effort to help the transition I thought it would be fun to have a giveaway.

telerikLogo-web-1124x449px Telerik has graciously accepted to offer a Developer’s License (with Subscription and Priority Support) to their RadControls for ASP.NET AJAX valued at $999.

The contest will start today and last 7 days concluding on July 31st, 2009 11:59PM. At that point I will pick the winner and announce the results on August 1st, 2009.

So, what do you need to do to sign-up? I’m glad you asked :)

In order to signup for the giveaway you need to do 3 things…

  1. Follow @elijahmanor on Twitter
  2. Tweet the following…
  3. Add a comment to this blog including your Twitter username

At the end of the contest I will pick a random comment from this blog entry and then make sure the comment author tweeted the above RT. At that point I will Direct Message the winner (which is why you need to follow @elijahmanor) with further instructions to receive the Telerik RadControls.

So, what are you waiting for… start tweeting now :)

Note: You may only add one comment per Twitter account in order to qualify.

Winner Announced…

Congratulations to Jason Farrell (comment # 36) for winning the Telerik RadControls for ASP.NET AJAX giveaway! Someone from Telerik will be contacting you shortly with instructions.

Thanks to everyone for participating. It looks as if I will be getting some other prizes to giveaway in the near future. So stayed tuned ;)

Thursday, July 16, 2009

Easily Share Code with these 8 Online Tools

I got the following tweet yesterday…

twitterED_normal  damanlovett: @elijahmanor You seem like a #jquery guru. ? 4 U, is it possible to use a dialog box to submit form data

And as it turned out, I had just had issues with submitting form data with the jQuery BlockUI Plugin the previous day & was able to find a work around (as I blogged hours after he asked me).

Although I blogged about a workaround hours later, I thought he might need a quicker answer so I went on the lookout for an online code sharing website to post and share the code with him.

I’ve used one or two of these services in the past, but at the time I was drawing a blank so I tweeted the question…

DSCN8389_normal  elijahmanor: I'm having a brain freeze... what is that service where you can post a snippet of code online & get a URL to share w/ others?

Moments later I was flooded with lots of different online options to share code.

Here are 8 online services that I received via twitter replies or that I found separately…

Note: Click the image to redirect to the actual hosted code snippet

Snipt.org

SniptOrg 

HTML pastebin

PastebinCom

Friendpaste

FriendPasteCom

Snipt

Note: You have to either create an account or use an OpenId

SniptNet

CodePaste.NET

CodePasteNet

Pastie

PastieOrg

Snipplr

SnipplrCom

textsnip

TextSnipCom

Which of the above services do you like best? Did I miss your favorite online code sharing service? If so, leave a comment with your favorite or suggestion.

Wednesday, July 15, 2009

Using jQuery BlockUI Plugin with ASP.NET Input Form

I was recently working on an ASP.NET WebForm project where it made sense to use a modal dialog to confirm choices, to ask for additional information, etc…

I’ve used the jQuery BlockUI Plugin before and I’ve always thought it provided a good mix of nice features as well as extreme customization.

Ii went ahead an implemented BlockUI across the application and was satisfied on how it looked & felt, but I noticed some weird behavior on one of the modal screens. I had a screen that had numerous input controls (textboxes, dropdownlists, etc…) and when I posted back my results all of the input controls were blank!

Ahh, what do I do? Where are my updated input values?

Debugging Steps

  1. Check to make sure I wasn’t re-initializing the input controls on PostBack
  2. Investigate that I didn’t turn off viewstate by accident & make sure I wasn’t using dynamic controls

After those steps I was still confused and frankly wasting a lot of time with something I thought would be very quick.

To make a long story short, it was BlockUI that was clearing the input controls on PostBack!

So, I created a fresh demo application to replicate the issue and started investigating.

The following code shows how to recreate the issue and how to resolve the issue.

    <div>
        <asp:Panel ID="pnlMessage" runat="server" Visible="false">
            <asp:Label ID="lblMessage" runat="server" /><br />
        </asp:Panel>
        <asp:Button id="ctlAddContact" runat="server" Text="Add Contact" />
    </div>
    
    <div id="ctlAddContactModal" style="display: none;" class="modal">
        <h3>Add Contact</h3>
        <dl>
            <dt><asp:Label ID="lblFirstNameCaption" runat="server" AssociatedControlID="txtFirstName" Text="First Name" /></dt>
            <dd><asp:TextBox ID="txtFirstName" runat="server" /></dd>
            <dt><asp:Label ID="lblLastNameCaption" runat="server" AssociatedControlID="txtLastName" Text="Last Name" /></dt>
            <dd><asp:TextBox ID="txtLastName" runat="server" /></dd>
        </dl>
        <div class="buttons">
            <asp:Button ID="btnCancel" runat="server" Text="Cancel" />
            <asp:LinkButton ID="btnFailureLink" runat="server" Text="Failure Save" CssClass="action" OnClick="btnFailureLink_Click" />
            <asp:LinkButton ID="btnSuccessLink" runat="server" Text="Success Save" CssClass="action" onclick="btnSuccessLink_Click" />
        </div>
    </div>
     
 
    <script type="text/javascript">
        $(function() {
            $('#<%= ctlAddContact.ClientID %>').click(function(e) {
                e.preventDefault();
                $.blockUI({
                    message: $('#ctlAddContactModal'),
                    css: {
                        cursor: 'auto'
                    }    
                });
            });

            $('#<%= btnCancel.ClientID %>').click(function(e) {
                $.unblockUI();
            });

            var btnSuccessLinkId = '<%= btnSuccessLink.ClientID %>';
            $('#' + btnSuccessLinkId).click(function(e) {
                e.preventDefault();
                $.unblockUI({
                    onUnblock: function() {
                        eval($('#' + btnSuccessLinkId).attr('href'));
                    }
                });
            }); 
        });
    </script> 

The issue is more obvious if you had used an <asp:Button /> in the above code snippet instead of an <asp:LinkButton /> as was the standard in my project. When using a <asp:Button /> the modal input form doesn’t submit at all! The BlockUI prevents the modal from from posting. I tried manipulating some of the plugin settings such as setting bindEvents = false and others, but nothing seemed to help.

So, the solution that works is…

  1. Attach a jQuery click event to your LinkButton
  2. Prevent the default click behavior of the LinkButton
  3. Unblock the modal window to restore default behavior of input form
  4. Add an onUnblock event to the modal window and evaluate the LinkButton’s href

Wednesday, July 08, 2009

ASP.NET MVC & jQuery Part 3: MvcContrib Grid & jQuery Plugins

This is the 3rd blog post in a series taken from a recent ASP.NET MVC & jQuery presentation I gave at CodeStock. The previous blog posts are available here...

  1. Part 1: Adding jQuery Intellisense to VS 2008
  2. Part 2: Zebra Striping

MVC Contrib Grid Component

The ASP.NET MVC 1.0 Release has a lot of great things included in it, but there is another open source project called MVC Contrib that fills many gaps and compliments the core functionality.

In this blog post I want to demonstrate how you can use the MVC Contrib Grid Component in conjunction with two different jQuery plugins to provide rich functionality inside a simple and clean View.

First lets review why you might want to use the MVC Contrib Grid Component.

  • Provides a Fluent Interface
  • Discourages Logic in your View
  • Provides Reusable Grid Models
  • Customizes Grid Rendering
  • Includes a Separate Pagination Component

If the above bullet items interest you, then check out the 5 part blog series on the MVC Contrib Grid Html Helper by Jeremy Skinner.

Enough of describing the component, lets start using the MVC Contrib Grid. After adding a reference to the MvcContrib assembly to your project you can proceed adding the Grid to your View…

<% Html.Grid(Model).Columns( column => {   
   column.For(x => Html.ActionLink("ID", "Details", new { id = x.Id })).Named("View").DoNotEncode();   
   column.For(x => x.Name).Named("Pet Name");   
   column.For(x => x.Description).Named("Description");   
   column.For(x => x.Price).Format("{0:C}"); 
})
.Attributes(style => "width: 75%;")
.Empty("There are no pets.")
.Render(); %>

As you can see in the code above, the syntax is easy to ready and it utilizes the tightly bound model passed to the View. The output of the Grid isn’t anything spectacular (see the following grid).

  <table id="dataTable">
        <thead>
            <tr>
                <th>View</th>
                <th>Pet Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
        </thead>
        <tr class="gridrow">
            <td><a href="/MvcContrib/Details/1">ID</a></td>
            <td>Ralph Fits</td>
            <td>A lonely ragged pup that licks himself and isn't house trained</td>
            <td>$12.99</td>
        </tr>
        <tr class="gridrow_alternate">
            <td><a href="/MvcContrib/Details/2">ID</a></td>
            <td>Fluffy Florentine</td>
            <td>A sweet little kitten that is ready to have a home</td>
            <td>$277.00</td>
        </tr>
        <!-- Additional Rows -->
        <tr class="gridrow_alternate">
            <td><a href="/MvcContrib/Details/14">ID</a></td>
            <td>Alien Abbott</td>
            <td>You never hear this dog bark because it only barks in the future.</td>
            <td>$777.99</td>
        </tr>
        <tr class="gridrow">
            <td><a href="/MvcContrib/Details/15">ID</a></td>
            <td>Crazy Calico</td>
            <td>If you like cats, don't get this one because it's pure crazy on a stick!</td>
            <td>$2.99</td>
        </tr>
    </tab

We can now transform the output of the MVC Contrib Grid into a rich featured table with the help of a little jQuery.

jQuery TableSorter Plugin

First, lets use the jQuery TableSorter Plugin to add some simple inline sorting capabilities to the Grid. Only the following one line of jQuery is necessary to transform this Grid. See the follow table for the results.

Note: TableSorter has additional widgets you can add for extra functionality. I am using the zebra widget to provide the alternate row coloring.

$("table").addClass('tableSorter').tablesorter({ sortList: [[1, 0]], widgets: ['zebra'] });  

ViewPet NameDescriptionPrice
IDRalph FitsA lonely ragged pup that licks himself and isn't house trained$12.99
IDFluffy FlorentineA sweet little kitten that is ready to have a home$277.00
IDBubba GumpA very stupid dog that can't even find his way to his dog house$999.99
IDCharlie StrangoThis weird looking puppy scares most adults, but has a strange interest to children$23.44
IDBlacky the BeautifulThis beautiful cat is as kind as can be. Who says that a dog is man's best friend?$45.65
IDSnot Nose NellyIf you want to get wet, then this is the pet for you. Talk about snot everywhere!$44.78
IDDarcy ScoopA wonderful black lab with human-like intelligence; however, it does poop a lot.$234.55
IDSupsrirooantsumA very rare cat straight from it's homeland of India.$432.67
IDClark KentA self-employed kitten making and selling fur balls for all to enjoy.$44.66
IDRed Headed BullThis dog is unlike any other that you have seen. You can even braid it's flowing red hair.$78.99
IDRex the TerribleA half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish.$346.99
IDSkittish SteveYou will never see this dog once you buy it. It'll be like you never had a pet to begin with.$33.00
IDDart MouthA dart gun was surgically grafted into this dog's mouth. He is great for parties.$55.00
IDAlien AbbottYou never hear this dog bark because it only barks in the future.$777.99
IDCrazy CalicoIf you like cats, don't get this one because it's pure crazy on a stick!$2.99

jQuery DataTable Plugin

Now, lets try adding a s lightly more feature rich jQuery Plugin to our Grid. The jQuery DataTable Plugin allows not only sorting of columns, but provides an elegant searching mechanism and also paging functionality. Yet again, with only one jQuery statement we can transform this table into something much more usable.

$('dataTable').addClass('dataTable').dataTable({
   "iDisplayLength": 10,
   "aaSorting": [[1, "asc"]],
   "aoColumns": [{ "bSortable": false }, null, null, null]
}); 

ViewPet NameDescriptionPrice
IDRalph FitsA lonely ragged pup that licks himself and isn't house trained$12.99
IDFluffy FlorentineA sweet little kitten that is ready to have a home$277.00
IDBubba GumpA very stupid dog that can't even find his way to his dog house$999.99
IDCharlie StrangoThis weird looking puppy scares most adults, but has a strange interest to children$23.44
IDBlacky the BeautifulThis beautiful cat is as kind as can be. Who says that a dog is man's best friend?$45.65
IDSnot Nose NellyIf you want to get wet, then this is the pet for you. Talk about snot everywhere!$44.78
IDDarcy ScoopA wonderful black lab with human-like intelligence; however, it does poop a lot.$234.55
IDSupsrirooantsumA very rare cat straight from it's homeland of India.$432.67
IDClark KentA self-employed kitten making and selling fur balls for all to enjoy.$44.66
IDRed Headed BullThis dog is unlike any other that you have seen. You can even braid it's flowing red hair.$78.99
IDRex the TerribleA half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish.$346.99
IDSkittish SteveYou will never see this dog once you buy it. It'll be like you never had a pet to begin with.$33.00
IDDart MouthA dart gun was surgically grafted into this dog's mouth. He is great for parties.$55.00
IDAlien AbbottYou never hear this dog bark because it only barks in the future.$777.99
IDCrazy CalicoIf you like cats, don't get this one because it's pure crazy on a stick!$2.99



Now, there are definitely some pros and cons in using the above two jQuery plugins.

Pros

  • The TableSorter Plugin & DataTable Plugin are very easy to implement. Only one jQuery statement is needed.
  • The user is presented with a richer interface providing sorting, paging, and simple searching.

Cons

  • Despite the pros listed above, the biggest con is that the jQuery Plugins are not scalable. All the records are returned in the View and the plugins hide and show the necessary data depending upon the user’s actions.

In light of the cons, I personally wouldn’t use any of the above jQuery plugins for my tables unless it was for a trivial non-production web page with a known number of static records.

Normally, I lead towards using either the Flexigrid Plugin or jqGrid Plugin that I will be reviewing in the next blog post in this series.