IE9 (Internet Explorer 9) Changes Developers Should Know About

   Posted by: Rich Franzmeier

Intro

The ASP.NET project I am on currently has spanned 5 years and has undergone many upgrades.  The latest upgrade was made necessary by the Internet Explorer 9 (IE9) push by Microsoft in Windows Update.  Our users started getting it and things that used to work started breaking.  I was given the task to find and repair these issues.  This post details my findings.  I am posting the two that I felt would be most relevant to developers.  Note that one of the issues (the second one) is related to ASP.NET alone but the first one is important for all web developers.

Content (or custom) Attribute Changes

Before IE9, content attributes could be get or set using JavaScript object DOM ‘expando’ properties.  With the introduction of IE9, that is no longer the case.  A content attribute is an attribute that is specified in the HTML source or, with ASP.NET, in the server side Control.Attributes collection.  There are pre-defined HTML content attributes like ‘value’ or ‘id’.  There are also user-defined content attributes (I call them ‘custom’ attributes), and that’s what I’ll be talking about in this post.  Expando properties are defined from MSDN as follows:  All objects in JavaScript support "expando" properties, or properties that can be added and removed dynamically at run time. (See http://msdn.microsoft.com/en-us/library/89t1khd2(v=vs.94).aspx)

Before IE9 the custom attributes were implied with the same name expando properties (i.e. javaObject.customAttr was valid in JavaScript.)  With IE9, that is no longer the case.  Note that the pre-defined content attributes will still be available as expando properties.

FIX -- The fix is to use the getAttribute and setAttribute functions of the JavaScript object instead of the expando properties.

See the MSDN explanation of this IE9 change here:  http://msdn.microsoft.com/en-us/library/ie/gg622931(v=vs.85).aspx

Example 1  – Content Attribute As HTML Source

This example will show what happens in IE9 and compatibility mode when we set a custom attribute in the HTML source.

Here is the ASP.NET code:

<asp:Button ID="ContentAttrBtn" runat="server" Text="Get Custom Content Attribute" 
    OnClientClick="attrAsContentAttribute(); return false;" />
<asp:TextBox ID="TextBox2" runat="server" helloWorld="content attribute!" />
If you aren’t familiar with ASP.NET, this is the HTML that is generated:
<input type="submit" name="ctl00$MainContent$ContentAttrBtn" 
  value="Get Custom Content Attribute" onclick="attrAsContentAttribute(); return false;"
  id="MainContent_ContentAttrBtn" />
<input name="ctl00$MainContent$TextBox2" type="text" id="MainContent_TextBox2" 
  helloWorld="content attribute!" />

Here is the JavaScript:

function attrAsContentAttribute() {
    var txt = document.getElementById('<%= TextBox2.ClientID %>');
    alert('TextBox2 helloWorld attribute (expando) = ' + txt.helloWorld);
    alert('TextBox2 value attribute (expando) = ' + txt.value);
    alert('TextBox2 helloWorld attribute (getAttribute) = ' + txt.getAttribute("helloWorld"));
}

When this is run in IE9, we get the following alert boxes:

image …Note that this is undefined in IE9 now.

image …I entered “textbox value” into the textbox.

image …works with getAttribute.

When this is run in IE9 Compatibility Mode, the following alert box changes (the 1st one):

image …works in compatibility mode.

Example 2 – Content Attribute Added in ASP.NET Code Behind (on server)

This example will show what happens in IE9 and compatibility mode when we set a custom attribute in the ASP.NET code behind.

Here is the ASP.NET code:

<asp:Button ID="ServerAttrBtn" runat="server" Text="Get Custom Server Attribute" 
    OnClientClick="attrSetOnServer(); return false;" />
<asp:TextBox ID="TextBox1" runat="server" />
If you aren’t familiar with ASP.NET, this is the HTML that is generated:
<input type="submit" name="ctl00$MainContent$ServerAttrBtn" 
  value="Get Custom Server Attribute" onclick="attrSetOnServer(); return false;" 
  id="MainContent_ServerAttrBtn" />
<input name="ctl00$MainContent$TextBox1" type="text" id="MainContent_TextBox1" 
  helloWorld="hello from server!" />

This is the code-behind to the page where I am setting the helloWorld attribute:

TextBox1.Attributes.Add("helloWorld", "hello from server!");

Here is the JavaScript:

function attrSetOnServer() {
    var txt = document.getElementById('<%= TextBox1.ClientID %>');
    alert('TextBox1 helloWorld attribute (expando) = ' + txt.helloWorld);
    alert('TextBox1 id attribute (expando) = ' + txt.id);
    alert('TextBox1 helloWorld attribute (getAttribute) = ' + txt.getAttribute("helloWorld"));
}

When this is run in IE9, we get the following alert boxes:

image …Note that this is undefined in IE9 now.

image …id of the TextBox or input element.

image …works with getAttribute.

When this is run in IE9 Compatibility Mode, the following alert box changes (the 1st one):

image …works in compatibility mode.

AjaxControlToolkit CalendarExtender

This issue is more specific to ASP.NET applications that are using the AjaxControlToolkit (November 2011 Release).  I noticed in my app that when I selected a date using the calendar extender (the calendar image that allows you to choose a date from a visual calendar), and the date had one digit in the month and/or day, it was formatted in the TextBox as follows:  4/9/2012

It should have formatted it this way:  04/09/2012

Note that I never set the CalendarExtender.Format value.  I just took the default.

Why do I care, you may ask?  Because the validation in the control doesn’t work correctly when it is formatted without leading zeroes.  What I noticed in my app was that I would get a “Date required” error message when a date was already in the TextBox control.

FIX -- The fix is to set the CalendarExtender.Format explicitly to "MM/dd/yyyy".

I logged this bug as an issue on CodePlex and you can follow it if you are interested here:  http://ajaxcontroltoolkit.codeplex.com/workitem/27137

Windows Workflow 4.0–Cache Those Activities

   Posted by: Rich Franzmeier

Earlier this year (2011), our project upgraded its 4 workflow activities from Workflow 3.0 to Workflow 4.0 with the promise of increased speed.  However, when we deployed we noticed how slow things got and we were in panic mode.  Thanks to Ron Jacobs timely blog post (http://blogs.msdn.com/b/rjacobs/archive/2011/02/12/wf4-performance-tip-cache-activities.aspx), we were able to solve the problem.  All of our workflow was being instantiated within a WCF web service on each call to a web method.  As Ron mentions in his article, there is a steep price to pay for this.  We ended up creating static variables for the 4 activities and used those to instantiate the WorkflowApplication object in the workflow helper class we wrote.

Here is the declaration in the helper class:

private static Activity _citationDiagram = new WF_Citation();
private static Activity _complaintDiagram = new WF_Complaint();
private static Activity _dwiFormDiagram = new WF_DWIForm();
private static Activity _incidentDiagram = new WF_IncidentReport();

This is how the WorkflowApplication was instantiated:

switch (_workflowType)
{
    case WorkflowType.Complaint:
        _wfDiagram = _complaintDiagram;
        break;
    case WorkflowType.Citation:
        _wfDiagram = _citationDiagram;
        break;
    case WorkflowType.DWIForm:
        _wfDiagram = _dwiFormDiagram;
        break;
    case WorkflowType.IncidentReport:
        _wfDiagram = _incidentDiagram;
        break;
    default:
        throw new Exception("Workflow type not defined.");
}
 
_wfApplication = new WorkflowApplication(_wfDiagram);

The code for this previous to the change was instantiating the Activity each time and since there was a lot of VB compiling to do in our diagrams (among other things), it was expensive.  Creating static variables for the Activity objects saved our project and my neck.

Quick and Easy Code Timing: The .NET Stopwatch Class

   Posted by: Rich Franzmeier

Introduction

The .NET Stopwatch class is nothing new to .NET (it’s been around since version 2.0) but it may be one of those classes you weren’t aware of (I wasn’t aware of it and I’ve been programming .NET since 1.1!)  It is very useful when you want to do some performance testing in your code or to get timings for whatever reason.

The Stopwatch Class

Quick facts:

Examples

The classic example simply creates an instance of the Stopwatch class, calls the Start() method, does the work and finally calls the Stop() method.

Stopwatch sw = new Stopwatch();
sw.Start();

// Do some work...
Thread.Sleep(2155);

sw.Stop();

Console.WriteLine("Elapsed time to do some work: {0}", sw.Elapsed.ToString());

 

Here is the output:

Stopwatch1

You can also instantiate a Stopwatch class using the StartNew() static method of the Stopwatch class.  This method creates a new Stopwatch instance, sets the elapsed time property to zero and starts the watch.

Stopwatch sw = Stopwatch.StartNew();

// Do some work...
Thread.Sleep(2155);

sw.Stop();

Console.WriteLine("Elapsed time to do some work: {0}", sw.Elapsed.ToString());

The output of course is the same as the previous example.

If you need to know if the stopwatch is ticking, use the IsRunning property.

Conclusion

The Stopwatch class is a useful tool to have when you want to do some simple performance testing in your code.  It’s easy to understand and code.

3 Visual Studio Debugging Tips That Save the Day

   Posted by: Rich Franzmeier

Intro

I've been in this business a long time now and know that I wouldn't have made it very far without a good debugging tool.  Visual Studio has a great debugger that has saved the day for me as a developer many times over the years.  The tips in this article are a few I've discovered and learned over the years and I hope you find them helpful as well.

Tip 1 - Turn on 'Break when an exception is thrown'

Sometimes an exception occurs and breaks in the debugger but it's not the location from which the exception was initially thrown.  The debugger breaks at the first place the code handles it (in the catch block.)  But if the exception was thrown in a method that the try block calls, you may not be able to determine what the problem is.  In this scenario, it is helpful to turn on 'break when an exception is thrown' for  "Common Language Runtime Exceptions".

-    Menu: Debug > Exceptions (Must be using C# profile to see this menu option)
-    Shortcut:  Ctrl+D, E
-    Check the ‘Thrown’ checkbox for Common Language Runtime Exceptions

 

Debug1

Tip 2 - Use two instances of Visual Studio to debug

Most of the time, using the Visual Studio debugger will do the job.  But there are some special scenarios worth mentioning where it is required to use another instance of Visual Studio to debug an issue.  I've used it in the following scenarios (I'm sure there are more):
-    Debugging a custom control when it is dropped on the designer - if there is an exception in your custom control that
     surfaces only when it is dropped on the designer, this is invaluable.
-    Debugging the ASPNET worker process (e.g. web services)
-    Debugging any assembly from another project that isn’t in your solution

Steps to do this:


1.    Open project/solution that has the code to debug
2.    Attach to the process you’d like to debug
       a.    Devenv.exe for another instance of visual studio (this would be the one that initiates the exception)
       b.    ASPNET_WP.EXE for worker process
       c.    Menu: “Debug > Attach to Process” or “Tools > Attach to Process”
       d.    Shortcut:  Ctrl+Alt+P
3.    Set breakpoints
4.    Turn on “Break when an exception is thrown” (see Tip 1)
5.    Do the thing that causes the exception (e.g. drop control on designer)
       a.    Hopefully, the debugger will break in your second instance at this point

Tip 3 - The DebuggerDisplay attribute

This tip may not save the day like the previous two, however, it will save a lot of time in debugging things like lists and arrays of objects that are alike but have different values.


Let's say you are trying to debug a list of phone numbers and know the one it is failing on but don't know where in the list it is.  This can be a challenge when the list gets long and looks like the following:

Debug2

In the past, I've overridden the ToString() method to print out the phone number (or pick your properties for your class).  This may not be an option if the code actually uses the ToString() method for your class.  Thankfully, starting in .NET Framework 2.0, you can use the DebuggerDisplay attribute on the class.  It is used to display whatever you would like when inspecting something in the debugger.  The attribute can be applied to the following:  class, structure, delegate, enumeration, field, property, assembly.

Decorate the Phone class as follows:

[DebuggerDisplay("({AreaCode, nq}) {Prefix, nq}-{LineNumber, nq}")]
public class Phone
{
    public string AreaCode { get; set; }
    public string Prefix { get; set; }
    public string LineNumber { get; set; }

The 'nq' stands for 'no quotes' since by default the properties that are evaluated within the brackets are surrounded by double-quotes.

Now, the debugger looks better when we inspect this list:

Debug3

Conclusion

It is good to have debugging tools in your toolbox.  Especially when time is critical and the problem must be fixed.  For more in depth coverage of debugging in Visual Studio, see the Intertech class “Introduction to Programming Training” at the following link:   http://www.intertech.com/Courses/Course.aspx?CourseID=99440

Using Lambda Expressions for Predicate, Func and Action Arguments in Generic List Methods

   Posted by: Rich Franzmeier

Intro

In the projects I’ve been working on since .NET generics came out, I’ve done a lot of work with generic Lists.  They are a great way to store, retrieve and generally work with objects.  Most of the methods in the generic List class take as arguments either a Predicate, a Func or an Action.  That can be confusing at first.  This article looks to dispel that confusion and make your code more elegant by using lambda expressions for all three of these types of arguments.

For a primer on lambda expressions, see this Microsoft post:
http://msdn.microsoft.com/en-us/library/bb397687.aspx

These are quick definitions of the three classes that are covered in the article:

  • Predicate - delegate that takes parameter(s), runs code using the parameter(s) and always returns a Boolean
  • Func - delegate that takes parameter(s), runs code using the parameter(s) and returns the type that you specify
  • Action - delegate that takes parameter(s), runs code using the parameter(s) and doesn’t return anything

So for the generic List, these arguments allow the coder to execute a method for each of the items in the generic List.

Common Code

The examples in this article will use the same common code.  The following is the business entity:

public class InventoryItem
{
    public int ID { get; set; }
    public int NumberInStock { get; set; }
    public double UnitCost { get; set; }
}

This is the list member variable that is used:

private List<InventoryItem> _inventoryList = new List<InventoryItem>();

This is what’s in the _inventoryList:

Contents

List Methods With a Predicate Argument

The generic List class Find method is an example of a method that takes a Predicate as an argument.  To build up to the Predicate class, let’s first look at how finds have been typically done.  For me, the foreach method was my best friend whether I used a generic List, ArrayList or whatever other data structure.  Here is an example:

public InventoryItem FindInventoryForeach(int inventoryID)
{
    foreach (InventoryItem item in _inventoryList)
    {
        if (item.ID == inventoryID)
            return item;
    }

    return null;
}

Now, there is a better way to do this common task.  The generic List class has this built in with the Find method.  The argument to the Find method is the Predicate class.  Remember the quick definition of a Predicate: “a delegate that takes parameter(s), runs code using the parameter(s) and always returns a Boolean”.  In C#, an inline delegate creates an anonymous method and it can be assigned to a Predicate variable.  This Predicate variable can then be passed into the Find method as follows:

public InventoryItem FindInventoryPredicateDelegate(int inventoryID)
{
    Predicate<InventoryItem> pred = delegate(InventoryItem item)
    {
        return item.ID == inventoryID;
    };

    return _inventoryList.Find(pred);
}
This can be useful if you want to store the delegate for reuse.  Of course the delegate can simply be passed into the Find method as follows:
public InventoryItem FindInventoryDelegate(int inventoryID)
{
    return _inventoryList.Find(delegate(InventoryItem item)
    {
        return item.ID == inventoryID;
    });
}

Lambda expressions simplify the preceding code.  First, here is the Predicate example with a lambda expression on the right side of the ‘=’:

public InventoryItem FindInventoryPredicateLambda(int inventoryID)
{
    Predicate<InventoryItem> pred = item => item.ID == inventoryID;

    return _inventoryList.Find(pred);
}

The lambda expression can be read “item goes to Item.ID == inventoryID”.  In other words, item is the parameter to what’s on the right of the “=>”.  Again the Predicate variable can be stored for reuse.  Using lambda expressions looks cleaner in my opinion.  To further simplify, the Predicate variable can be bypassed in favor of using the lambda expression directly in the Find method as follows:

public InventoryItem FindInventory(int inventoryID)
{
    return _inventoryList.Find(item => item.ID == inventoryID);
}

Notes about the lambda expression:

  • The left side represents the parameters into the function to be evaluated, in this case, of type InventoryItem
  • The right side is a boolean expression which will evaluate to true when the Find method finds the item with ‘inventoryID’
  • If the item is not found, the FindInventory method will return null
  • Some claim this is more difficult to learn and therefore harder for maintenance but I believe it’s cleaner (if maintenance is a concern, comment these sections of code to help the other developers learn)

The preceding Find examples all output the same with an inventoryID of 5 as shown:

FindOutput

The following generic List methods that have a Predicate argument are also useful:

  • FindAll - returns a List of objects that meet the condition
  • RemoveAll - removes the objects that meet the condition
  • Exists - does the object exist that meets the condition?
  • FindLast - returns the last object that meets the condition
  • For the full list, see http://msdn.microsoft.com/en-us/library/s6hkc2c4.aspx 

List Methods With a Func Argument

There are many List methods that take a Func type as an argument.  Remember the quick definition of a Func:  “a delegate that takes parameter(s), runs code using the parameter(s) and returns the type that you specify”.  Func is more flexible than Predicate as it can return any type, not just bool.  It depends on the List method as to the signature of the Func.  Some take one argument, others more.

One of the more useful List methods is actually an extension method on Enumerable called Where.  Think of the SQL WHERE clause when using this method.  It allows you to get a subset of the List given the Where Func that is specified.  The following is an example of this using delegates:

public List<InventoryItem> FindItemsWhereLessThanCostFuncDelegate(double unitCost)
{
    Func<InventoryItem, bool> whereFunc = delegate(InventoryItem item)
    {
        return item.UnitCost < unitCost;
    };

    return _inventoryList.Where(whereFunc).ToList<InventoryItem>();
}

Note that to return a List of InventoryItem’s, you must call ToList since Where returns an IEnumerable and the query isn’t executed until the result is enumerated.

The preceding example can be simplified by using a Lambda expression:

public List<InventoryItem> FindItemsWhereLessThanCostFuncLambda(double unitCost)
{
    Func<InventoryItem, bool> whereFunc = item => item.UnitCost < unitCost;

    return _inventoryList.Where(whereFunc).ToList<InventoryItem>();
}

Again this would be done mainly for reusing the Func in other places of the code.

The best simplification is done by simply passing a lambda expression directly into the Where method as follows:

public List<InventoryItem> FindItemsWhereLessThanCost(double unitCost)
{
    return _inventoryList.Where(item => item.UnitCost < unitCost)
        .ToList<InventoryItem>();
}

The preceding Where examples all output the same with a unitCost parameter value of 2.0:

WhereOutput

The following generic List methods that have a Func argument are also useful:

  • FirstOrDefault - returns the first item that meets the condition or a default value (for an object, the default value is null)
  • LastOrDefault - returns the last item that meets the condition or a default value (for an object, the default value is null)
  • First - returns the first item that meets the condition
  • For the full list see http://msdn.microsoft.com/en-us/library/s6hkc2c4.aspx 

List Methods With an Action Argument

Remember the quick definition of an Action:  “a delegate that takes parameter(s), runs code using the parameter(s) and doesn’t return anything”.  There is one method in the generic List class that takes an Action argument, it is the ForEach method.  All it does is run the code you specify for each of the items in the List.

In the following example, the unit cost is set to the same value for each inventory item (a separate Action variable can also be created using a delegate or lambda expression and then passed into the ForEach method):

public void UnifyUnitCost(double unitCost)
{
    _inventoryList.ForEach(item => item.UnitCost = unitCost);
}

This produces the following results:

ForEachOutput

Of course I generated the output using the ForEach command as well:

helper.InventoryList.ForEach(item => Console.WriteLine(
    "item ID={0}, unit cost = {1}",
    item.ID.ToString(), item.UnitCost.ToString("C")));

Conclusion

The generic List class and it’s extensions have some very powerful methods to help you do common tasks.  Many of them take either a Predicate, Func or Action argument.  The most compact and elegant way to use methods of this type is to pass in lambda expressions, an important part of LINQ.

For a much more thorough understanding of all that LINQ has to offer, check out the Intertech class “Complete LINQ for .NET 4.0 Training”.

Find Us
Contact Us 651-288-7000 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | Microsoft Web Development Training | Prism / MVVM / MEF Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2012 Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C / C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.