Blog Archives

Never worry about ASP.NET AJAX’s .d again

When I recently received this message from a frustrated reader:

After hours and hours of slamming my head into the desk it turns out it was the darn "d" in the response. My home computer is on .NET 2.0 and my work computer is on 3.5. Jimminie Christmas!

I realized that the “.d” introduced in ASP.NET AJAX 3.5’s JSON responses is still all too common a stumbling block when calling ASP.NET AJAX services through a library such as jQuery. In fact, with jQuery’s popularity among ASP.NET developers on the rise, this appears to have become an even more frequent problem.

Since a lot of people are having trouble with it, I want to share one method you can use to completely isolate your code from the problem. If you bake this into an $.ajax() code snippet or otherwise use it as a template for calling ASP.NET AJAX services in jQuery, you should never have to think or worry about the “.d” again.

In this post, I will show you how to detect the “.d” and how you can completely isolate your $.ajax success handler from it.

“.d” what?

If you aren’t familiar with the “.d” I’m referring to, it is simply a security feature that Microsoft added in ASP.NET 3.5’s version of ASP.NET AJAX. By encapsulating the JSON response within a parent object, the framework helps protect against a particularly nasty XSS vulnerability.

Before ASP.NET 3.5, “ScriptServices” and page methods returned their data at the top level of the JSON response, like this:

2.0 JSON Response in Firebug

In ASP.NET 3.5 and later, the same server-side code returns this:

3.5 JSON Response in Firebug

For more information about the change and why the change is a good one, be sure to see my earlier post: A breaking change between versions of ASP.NET AJAX.

However, what my previous post lacks is a solution for mitigating the inconsistency entirely. Using different client-side code against 2.0 and 3.5 based services is workable, but far from ideal. Wouldn’t it be nicer to not have to worry about it?

Determining whether or not the “.d” is there

In order to isolate ourselves from the “.d”, we first need a reliable way to test for its presence. Though JavaScript provides several methods for determining this, I suggest hasOwnProperty, as recommended by Douglas Crockford.

By using hasOwnProperty, your code is protected against unexpected changes to an object’s prototype chain. Though it is an unlikely problem to encounter, it’s always best to code defensively in JavaScript. The browser is a hostile environment!

Using hasOwnProperty to test for “.d”, you might end up with something like this:

$.ajax({
  type: "POST",
  url: "WebService.asmx/MethodName",
  data: "{}",
  contentType: "application/json; charset=utf-8",
  dataType:"json",
  success: function(msg) {
    if (msg.hasOwnProperty("d"))
      // Leave the .d behind and pass the rest of 
      //  the JSON object forward.
      DoSomething(msg.d);
    else
      // No .d; no transformation necessary.
      DoSomething(msg);
  }
});
 
function DoSomething(msg) {
  // Do something with the response data here.
  //  Expect it to consistently have no .d.
}

This code will perform identically against any version of ASP.NET AJAX.

Unfortunately, this might still get in your way. You may not always want to use the response in a call to another function, and you’ll have to remember the conditional every time you write a success handler.

Don’t make me think

I prefer a solution that doesn’t touch the success handler at all. Then, you’re free to integrate the “.d” handling into a generic $.ajax code snippet in Visual Studio and/or easily copy-paste it between files without modification.

Luckily, jQuery provides a mechanism that allows us to do just that: dataFilter.

The dataFilter parameter to $.ajax allows you to arbitrarily transform a response just before the success handler fires. Specifically tailored to this sort of situation, it passes response data into a callback function, captures the return value of that callback, and then passes the modified data into your success handler.

Hence, you can forever stop worrying about that pesky “.d” like this:

$.ajax({
  type: "POST",
  url: "WebService.asmx/MethodName",
  data: "{}",
  contentType: "application/json; charset=utf-8",
  dataFilter: function(data) {
    // This boils the response string down 
    //  into a proper JavaScirpt Object().
    var msg = eval('(' + data + ')');
 
    // If the response has a ".d" top-level property,
    //  return what's below that instead.
    if (msg.hasOwnProperty('d'))
      return msg.d;
    else
      return msg;
  },
  success: function(msg) {
    // This will now output the same thing 
    //  across any current version of .NET.
    console.log(msg.foo);
  }
});

Now, regardless which of these JSON forms the server returns:

// ASP.NET 2.0 with the ASP.NET AJAX Extensions installed.
{'foo':'bar'}
 
// ASP.NET 3.5 and 4.0.
{'d':{'foo':'bar'}}

Your success handler will simply receive this consistent JSON object every time:

{'foo':'bar'}

dataType: none of your business

It’s important to note the removal of the dataType parameter in the $.ajax() code above. This is required in order to prevent a double-eval of service responses containing only a single string.

Internally, jQuery uses a combination of the dataType parameter and the implicit type the response. If the dataType is "json" and typeof(response) is “string”, then jQuery uses eval() to deserialize the response.

In the example above, manually deserializing the response in dataFilter results in it being of type Object, jQuery leaves it alone, and our dataFilter’d object makes its way back to the success callback either way.

However, if the dataType is set to “json” and the “.d” sanitized response happens to be of JavaScript type “string”, jQuery will assume that it is a JSON response from the server and still needs to be deserialized. That will throw an error at best.

The solution is to simply drop the dataType parameter from the $.ajax() call. It is only needed for purposes of instructing jQuery how to deserialize the response, and we’re handling that ourselves now.

Thanks to Brett for pointing this out.

Wait, isn’t eval() supposed to be evil?

If the eval() usage gives you pause, don’t worry. For now (as of jQuery 1.3.2), this is the same mechanism that jQuery uses to deserialize JSON too. Though eval() is potentially evil, it is still a necessary evil in many browsers.

In my next post, I’ll show you how to modify this to leverage a native browser implementation of JSON.parse instead of eval(), available in some newer browsers.

That post is available now: Improving jQuery’s JSON performance and security.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

Never worry about ASP.NET AJAX’s .d again

Control-Oriented Vs. Data-Oriented Programming in Silverlight

If you build ASP.NET applications then you’re used to working with controls a lot.  Nearly everything you do requires accessing control IDs.  If you need to retrieve data entered by an end user you need to reference the controls that contain the data.  That’s just the way we do it in ASP.NET and if you’ve been writing ASP.NET applications very long its how you’re conditioned to think.

Silverlight changes the game quite a bit due to the way you can bind data to controls.  With Silverlight applications I don’t always name my controls since ultimately I care about accessing the data rather than the control that contains the data.  Sure, if I need to perform an animation or change a control’s style I’ll need to access the control directly by its name, but when it comes to accessing data there’s an easier way.  Silverlight provides two-way bindings that allow a data object to be bound to a control in a unique way.  If the user changes the data the source object is automatically updated without additional code on your part.  An example of a two-way binding defined in XAML is shown next:

<TextBox Text="{Binding MondayQuantity, Mode=TwoWay}"  Style="{StaticResource TimeSheetTextBoxStyle}" />


This example binds the DataContext (the main object bound to the overall form) object’s MondayQuantity property to a TextBox control.  The Mode is set to TwoWay rather than the default OneWay binding which means that any changes to the TextBox are automatically moved back to the MondayQuantity property in the source object.  As a result, you don’t need to access the TextBox to get the value entered since the source object that was originally bound to the control contains up-to-date data.  Having done a lot of ASP.NET programming this took some time to get used to, but it’s nice to leverage once you know about it. 

I’m working on an application that uses a Silverlight DataGrid control with nested ComboBox and TextBox controls in each row.  As a user changes  quantity or hour values the totals need to be updated.

image

Let’s take a look at different solutions that can be used to update the totals values.

A Control-Oriented Approach

One solution to updating the totals is to iterate through the target row and locate each TextBox to get the values.  That’s the control-oriented approach we’d normally use in ASP.NET applications.  To update TextBlock controls that track totals at the end of each row (red area in the image shown above) as a user changes values, you could use the following code which iterates through each column in a given row and locates TextBox controls:

//Get the DataGrid's selected item
TimeSheetViewRow dataContext = (TimeSheetViewRow)TimeSheetDataGrid.SelectedItem;
decimal totalQty = 0;
decimal totalHours = 0;

//Loop through all the columns for the selected row
for (int i = 2; i < TimeSheetDataGrid.Columns.Last().DisplayIndex; i++)
{
    StackPanel sp = (StackPanel)TimeSheetDataGrid.Columns[i].GetCellContent(dataContext);
    foreach (UIElement elem in sp.Children)
    {
        //Find the TextBox controls
        if (elem is TextBox)
        {
            TextBox tb = (TextBox)elem;
            if (!String.IsNullOrEmpty(tb.Text))
            {
                decimal val = decimal.Parse(tb.Text);
                if (tb.Tag.ToString() == "Quantity") totalQty += val;
                if (tb.Tag.ToString() == "Hours") totalHours += val;
            }
        }
    }
}
//Find totals TextBlocks and update them
StackPanel totalsSP = (StackPanel)TimeSheetDataGrid.Columns[TimeSheetDataGrid.Columns.Last()
    .DisplayIndex].GetCellContent(dataContext);
((TextBlock)totalsSP.FindName("TotalQuantityTextBlock")).Text = totalQty.ToString();
((TextBlock)totalsSP.FindName("TotalHoursTextBlock")).Text = totalHours.ToString();


While this technique works fine, it’s definitely not the easiest way to total each day’s hours and quantity and would have to be re-written if the TextBox controls’ container changes from a StackPanel to something else.  Let’s look at a more flexible data-oriented approach.

A Data-Oriented Approach

Since the TextBoxes in each row all have TwoWay bindings defined, the source object that was originally bound (of type TimeSheetViewRow) is automatically updated as TextBox values change.  As a result, I can simply grab the selected item (which represents the bound object) from the DataGrid and then total up the property values.  Once the totals are calculated the appropriate quantity and hours total properties can be updated on the source object which automatically updates the grid TextBlock controls bound to those properties.  It’s important to note that the TimeSheetViewRow class implements INotifyPropertyChanged so that it can notify Silverlight as property values change so that the data can be re-bound to the controls.  The control-oriented approach shown earlier can be simplified to the following:

TimeSheetViewModel vm = (TimeSheetViewModel)LayoutRoot.DataContext;
vm.UpdateRowTotals((TimeSheetViewRow)TimeSheetDataGrid.SelectedItem);


The code that performs the actual calculations is shown next.  It’s located in a ViewModel class named TimeSheetViewModel that exposes an UpdateRowTotals method.  The ViewModel class contains all of the properties that are bound to the form (called the View) that the end user sees.  I used reflection to simplify the calculation process since each property has a set naming convention (MondayHours, MondayQuantity, TuesdayHours, TuesdayQuantity, etc.) but I certainly could’ve written code to add all of the Monday – Sunday quantity and hours properties together more explicitly.

 

public void UpdateRowTotals(TimeSheetViewRow row)
{
    decimal qty = 0M;
    decimal hours = 0M;
    Type t = typeof(TimeSheetViewRow);
    foreach (PropertyInfo prop in t.GetProperties())
    {
        object val = prop.GetValue(row, null);
        decimal decimalVal = (val==null)
            ?0.00M:decimal.Parse(val.ToString());
        if (prop.Name.EndsWith("Hours")) hours += decimalVal;
        if (prop.Name.EndsWith("Quantity")) qty += decimalVal;
    }
    row.HoursTotal = hours;
    row.QuantityTotal = qty;
}

As the HoursTotal and QuantityTotal properties change the corresponding TextBlock controls that they’re bound to will be updated automatically.

You can see that with Silverlight you can focus on working with data as opposed to working with controls by using the built-in support for TwoWay binding.  Controls are there to present the data to the end user and allow them to change values.  By focusing less on controls we can reduce the amount of code that has to be written in many cases.  It takes a little getting used to especially if you’re used to the ASP.NET control-centric approach, but once the concept clicks it really changes how you think about writing data-oriented code.

Deploying ASP.NET Applications to Medium Trust Servers

99% of the projects my company works on for clients are deployed internally to an enterprise environment managed by a company.  We rarely have to worry about deploying to a shared hosting environment which is nice.  One of the client projects we finished up recently based on ASP.NET MVC, PLINQO and jQuery was deployed to a shared hosting provider for the client and nothing worked initially.  Everything worked locally of course even if we hit the hosting provider’s database from the staging server code base.  It’s never fun to have development or staging working with the same code failing in production.

After researching the error more we thought it related to data access permissions since we were getting null reference errors as collections were converted to lists (data wasn’t being returned from the database).  Finding the root cause of errors in this situation is like finding a needle in a haystack since you can’t attach a debugger, can’t run SQL Profiler or do anything aside from looking at log files, make code changes, FTP the files to the server and see what happens. 

After thinking through it more and running several isolated tests we realized it wasn’t a data access error that we were getting (even though that’s what logs led us to believe).  With a little research I came across the good old <trust> element that can be used in web.config.  It’s not something that I personally have had to use for over 5 years so I completely forgot about it.  By placing the following in web.config you can simulate a medium trust environment:

<system.web>
  <trust level="Medium"/></system.web> 

Changing the trust level made the staging environment fail with the same error shown on the shared host (which was awesome….rarely am I excited to get an error).  We found out that a PLINQO assembly we were using didn’t allow partially trusted calls so we located the source for that assembly, recompiled it to allow partially trusted callers and everything was fine. 

Bottom Line/Lesson Learned: If you’re deploying to a medium trust hosting environment you’d be wise to set the trust level to Medium up front to save time and energy down the road.

11 keystrokes that made my jQuery selector run 10x faster

As an ASP.NET developer working on the client-side, one problem you’ll encounter is how to reference the HTML elements that ASP.NET web controls generate. All too often, you find yourself wasting time trying to reference TextBox1, when the element is actually rendered as ctl00_panel1_wizard1_TextBox1.

Much has been written about this, including a post of my own, so I won’t go into detail about many of the workarounds. Instead, I want to take a closer look at the performance drawbacks of one popular solution: the [attribute$=value] selector.

By specifying id as the attribute in this selector, you can avoid ASP.NET’s ClientID issues completely. No matter what the framework prefixes your rendered elements with, they still “end with” the ID you specify at design time. This makes the “ends with” selector a convenient alternative to injecting a control’s ClientID property via angle-brackets.

However, are we trading performance for this convenience? If so, how much?

When Craig Shoemaker asked that question while interviewing me for an upcoming episode of Polymorphic Podcast, I realized I didn’t know the answer as clearly as I’d like. So, I decided to do a bit of benchmarking.

In this post, I’ll share the results of that benchmarking, and show you one way to significantly improve the performance of this convenient selector.

The test scenario

One difficulty when analyzing selector performance is that they all perform well on small test pages. Most performance issues aren’t readily apparent until a page grows in complexity and contains many elements. This can easily leave you overly confident in techniques that survive a simple proof of concept, but don’t scale well to practical usage.

Rather than construct a complex demonstration page from scratch to test against, I decided to use an existing page. With over 160 comments at the time of writing (and testing), the Highslide JS .NET project page is an ideal candidate. Its 1,000+ DOM elements are well suited to expose poorly performing selectors.

Enclosing each comment on the page, there’s a div like this one:

<div id="div-comment-35496" class="comment">
  <!-- Comment content here -->
</div>

If you imagine that the “div-“ prefix is “ctl00_”, these IDs are a great substitute for the ClientIDs that ASP.NET controls render within naming containers.

So for purposes of testing, I attempted to select the element div-comment-35496 on that page, assuming that I knew its ID of comment-35496 at design time and that the “div-“ prefix was added at run time. This is identical to the process of selecting the div rendered by an ASP.NET Panel control within a Content Page, for example.

Test methodology

To benchmark each selector, I used the following JavaScript:

var iterations = 100;
var totalTime = 0;
 
// Repeat the test the specified number of iterations.
for (i = 0; i < iterations; i++) {
  // Record the starting time, in UTC milliseconds.
  var start = new Date().getTime();
 
  // Execute the selector. The result does not need
  //  to be used or assigned to determine how long 
  //  the selector itself takes to run.
  $('[id$=comment-35496]');
 
  // Record the ending time, in UTC milliseconds.
  var end = new Date().getTime();
 
  // Determine how many milliseconds elapsed and
  //  increment the test's totalTime counter.
  totalTime += (end - start);
}
 
// Report the average time taken by one iteration.
alert(totalTime / iterations);

This simply executes the selector 100 times, recording how many milliseconds each run takes, and then determines the average.

I had originally recorded and displayed an array of each individual time, but found there was very little variation and stopped tracking each execution. The average is good enough for these purposes.

For each selector, I ran the test five times and then averaged the results, resulting in an average across 500 separate executions in semi-isolated batches. Then, I repeated the process for each major browser.

CERN probably won’t be flying me out to work on the LHC with this level of rigor, but it’s accurate enough for measuring the relative performance change between different selectors.

The baseline

jQuery’s #id selector leverages browsers’ native getElementById routine. Though slower than calling getElementById directly, this is a very fast way to reference our div as a jQuery object:

$('#div-comment-35496')

As you may expect, this browser assisted selector is fastest. In fact, every major browser consistently performed this in less than one millisecond in my testing. Most in less than a third of a millisecond.

To safely use this selector in ASP.NET, we have to manually inject the a control’s ClientID property. Otherwise, any naming container added, removed, or renamed would break our client-side code.

You’ve probably seen that accomplished like this:

$('#<%= comment-35496.ClientID %>')

It looks messy and requires a bit more effort, but it’s fast.

ASP.NET 4.0’s ClientIDMode property promises to eliminate this inconvenience in the long-term, but we’re stuck with it for now. For that matter, with many projects still using ASP.NET 1.x and 2.0, slow to adopt the latest version, we may be stuck with the problem for quite some time to come.

Convenience

To avoid the messy work of manually injecting ASP.NET’s rendered ClientIDs, you may have seen the suggestion that this is an easier way:

$('[id$=comment-35496]')

Indeed, this will successfully select the element that we’re after. Since its ID is div-comment-35496, searching for an element whose ID “ends with” comment-35496 works as desired.

Eliminating the angle-brackets is aesthetically pleasing and it’s less up-front work, but what about performance?

jQuery’s selector engine implements “ends with” by performing this test on every element in question, where value is the attribute you’ve specified and check is the string that you’re searching for:

value.substr(value.length - check.length) === check

That’s not so bad if you’re only doing it once, but doing it for every element on the page is a different story. Remember our test page has thousands of elements.

What’s worse, jQuery has no way to know that only one element should match the pattern. So, it must continue iterating through to the end of the page, even after locating the single element that we’re actually interested in.

How bad is it? Over the course of several hundred executions on the test page, I obtained these average speeds for a single $= selector execution in each browser:

The Chrome numbers are unsurprising, given its speedy V8 JavaScript engine. IE8 and Firefox 3.5 perform admirably too. These newer browsers all executed the selector very nearly as quickly as document.getElementById.

However, IE7 and Firefox 3.0 are substantially slower when executing the “ends with” selector. Remembering the non-trivial difference that Firebug made in this interesting post about JSON parsing speeds, I also tested with and without Firebug enabled in Firefox 3.0 (which turned out to be a significant factor here too).

Even though we’re only talking about milliseconds, the penalty in older browsers is too large to ignore — especially when the vast majority of users are still on IE6, IE7, or Firefox 3.0, not the new generation of faster browsers.

Convenience optimized

Remembering that the #id selector is quick because it leverages the native speed of getElementById, we can help jQuery execute the $= selector more efficiently.

If we modify the selector to descend from an HTML tag before performing the “ends with” search, jQuery can use getElementsByTagName to pre-filter the set of elements to search within. Since getElementsByTagName is a native browser routine, it is much faster than jQuery’s interpreted selector engine.

For example, since we know the element we’re after is a div, we could optimize the previous $= selector like this:

$('div[id$=comment-35457]')

The benefit is substantial:

The optimized selector runs more than twice as quickly in IE7 and Firefox 3.0!

Along the same lines, jQuery’s Sizzle engine is able to select CSS classes faster than it can perform substring searches within arbitrary attributes. So, the selector can be further optimized by descending from both an HTML tag and a CSS class.

Since the particular div we’re testing against has a CSS class of comment, let’s try this selector:

$('div.comment[id$=comment-35457]')

The results?

IE7 doesn’t improve much, but Firefox 3.0 shows another excellent increase in its performance. The reason that Firefox shines here is that it implements a native getElementsByClassName routine that IE7 doesn’t (though IE8 does).

While slower than the getElementById powered #id selector, these optimizations have given us a 3-10x speed increase while referencing exactly the same element as the original $= selector. That’s a pretty good return on the investment of typing a measly eleven characters (div.comment) in front of the selector!

A mountain out of a molehill?

This post may seem like a lot of effort to spend on a seemingly tiny performance differential. In fact, I almost considered leaving this one on the shelf, because it’s often difficult to sell the importance of milliseconds.

But, you know what? Milliseconds count! A performance difference of a few dozen milliseconds is a perceptible delay. A few hundred will alienate your users.

Research has consistently shown a strong correlation between fast sites and higher conversion rates, more user actions per visit, and user satisfaction. Compounded across the thousands or millions of times a particular function in your application will be used, it is absolutely worthwhile to invest a few minutes in order to save a few milliseconds.

Conclusion

I hope you’ve found this information useful. Without hard data, it’s difficult to decide which optimizations are premature and which are worthwhile. Especially since your page is likely to grow more complex over time, I think the data clearly shows that selectors which don’t directly target an ID should always descend from an HTML tag when possible.

Perhaps the most important takeaway is that you must keep in mind how easy it is to write one succinct line of jQuery code that results in a non-trivial loop. The real danger lies in putting a selector like $= within a loop yourself, unaware that what appears to be a simple loop is actually a relatively sluggish nested loop.

The other lesson here is that if speed is crucial, you should inject ClientIDs and use the #id selector (as in the baseline shown above). Even the most optimized “ends with” selector in this post still runs at least one order of magnitude slower than the direct #id selector.

Instead of simply posting that div.class[id$=id] is faster than [id$=id], I wanted to explain the sequence of events that led me to that determination. Armed with knowledge of how I optimized the “ends with” selector, I hope that you have a few new optimization tricks up your sleeve now.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

11 keystrokes that made my jQuery selector run 10x faster

Highslide JS .NET v4.1.4

A new version of Highslide JS .NET is available today. Nothing major has changed in the .NET control, but the newer Highslide JS version includes several bug fixes, compatibility improvements, and performance benefits.

To eliminate one common source of confusion, I’ve decided to begin versioning Highslide JS .NET based on the version of Highslide JS embedded within the the control. For example, since this release is v4.1.4, it contains v4.1.4 of Highslide.

Changes in v4.1.4 include:

  • Updated embedded Highslide JS script version to 4.1.4. You can see what has changed in that on the Highslide.com changelog page.
  • Added ControlBarPosition property to the HighslideManager, which allows you to position the enlargement’s control bar in any corner of the image.
  • Added several properties (ControlBarPreviousTitle, ControlBarNextTitle, ControlBarMoveTitle, and ControlBarCloseTitle) to control title attributes of links rendered in the control bar. Useful for localization.

As always, the free download is available on the Highslide JS .NET project page.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

Highslide JS .NET v4.1.4

Video: Getting Started with ASP.NET MVC 1.0

I had the opportunity to speak at the Best of Mix 09 Phoenix event with Tim Heuer and Rob Bagby and had a lot of fun hanging out with everyone.  I was the last talk and due to time constraints didn’t get a chance to cover everything I had hoped to cover, but all of the important topics were discussed. 

The projection screen doesn’t show up too well in the video unfortunately, but all of the slides and sample code can be downloaded here for those that may be interested in following along. The talk covers the fundamentals of ASP.NET MVC, discusses some great features the framework offers and describes how jQuery and even Silverlight can be integrated.  The downloadable code samples demonstrate all of the features discussed in the video.

Getting Started with ASP.NET MVC 1.0 

Click here to view in Windows Media Player (right-click and you can save the file)

Logo

For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit www.thewahlingroup.com/.

Emulating the UpdatePanel in ASP.NET MVC 1.0 with AjaxHelper

I just finished up a client application based on ASP.NET MVC 1.0 and thought I’d blog about some of the things I really liked.  If you didn’t catch my earlier post titled 5 Reasons You Should Take a Closer Look at ASP.NET MVC and are interested in learning more about what the MVC framework offers I’d recommend reading that first.  The client application my company built required a lot of AJAX functionality behind the scenes and I used jQuery along with MVC controller actions to pass JSON data back and forth in many cases.  However, I did take the UpdatePanel type approach in a few cases since it’s quite easy to do and very efficient as far as the data that gets passed back and forth between the client and server.

ASP.NET MVC 1.0 provides an AjaxHelper class that exposes a BeginForm() method.  HTML controls wrapped in the BeginForm() area are automatically AJAX enabled much like the ASP.NET UpdatePanel.  However, because ASP.NET MVC doesn’t use ViewState or ControlState at all, the calls back to the server are much more efficient when compared to the UpdatePanel (you can use a tool such as Fiddler to verify this:  www.fiddlertool.com).  Here are the basic steps to AJAX-enable sections of a view in ASP.NET MVC.

1. Add Ajax.BeginForm into your View

<% using (Ajax.BeginForm("EditCustomerProfile", null,
   new AjaxOptions { UpdateTargetId = "CustomerForm", OnSuccess = "onEditCustomerProfileSuccess" },
   new { id = "EditCustomerProfileForm" }))
   {
%>

<% } %>


BeginForm() has 11 different overloads that can be used.  This example creates an AJAX-enabled section using the AjaxHelper’s BeingForm() method and defines that a controller action named EditCustomerProfile will be called to retrieve the data.  Any route data that needs to be passed can be specified in the second parameter.  The third parameter represents the AjaxOptions that will be used as the client and server interact.  In this case I specify that a control with an ID of CustomerForm will be updated with the data returned from the server.  I also call a JavaScript success callback named onEditCustomerProfileSuccess to perform other necessary actions in the application if the AJAX call returns successfully:

function onEditOfficeProfileSuccess(content)
{
    if ($('#OfficeProfileValSummary').length == 0) //No validation control found so OK
    {
        ClearOfficeProfileControls();
    }
    GetOfficeProfiles();
}

The final parameter represents properties that are added to the form tag generated by BeginForm().  I simply assign the id of the form tag to EditCustomerProfileForm which is done to make it easier to filter controls using jQuery selectors elsewhere in the application.

2. Add the UpdateTargetID div

Once BeginForm() is defined you need to specify the object (div, span or other object) that will receive updates from the server as AJAX calls are made.  In my case I want an end user to complete a form, submit it to the server, validate it, perform business rules there, etc. and then return the form back to the client with a status message about the action.  The form is defined in a user control which is embedded within my ASP.NET MVC view using the HtmlHelper’s RenderPartial() method.  Since the form area gets updated after the call I wrap it with a div that has an ID of CustomerForm (the UpdateTargetID shown above).  Here’s the completed code:

<% using (Ajax.BeginForm("EditCustomerProfile", null,
   new AjaxOptions { UpdateTargetId = "CustomerForm", OnSuccess = "onEditCustomerProfileSuccess" },
   new { id = "EditCustomerProfileForm" }))
   {
%>
    <div id="CustomerForm">
        <% Html.RenderPartial("EditCustomerForm",Model.CustomerViewModel); %>
    </div>
<% } %>


When user submits the form and data returns from the server the CustomerForm div will automatically be updated without having to write any JavaScript code….just like the ASP.NET Web Forms UpdatePanel. The code for the controller action named EditCustomerProfile is shown next.  If everything validates properly it returns the EditCustomerForm user control with a message letting the client know that everything worked.  If errors are found they are added into the model’s error collection and displayed in the form.

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditCustomerProfile(Customer customer, string email)
{
    string emailMessage = null;
    try
    {
        //#### Handle Email
        if (!String.IsNullOrEmpty(email) && Regex.IsMatch(email, @"^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$"))
        {
            emailMessage = UpdateEmailAddress(email);
        }
        else //Email address is null or doesn't follow the RegEx pattern
        {
            emailMessage = "Please check that you entered your email address properly.";
        }

        //#### Handle updating Customer object data
        if (emailMessage == null && customer.IsCustomerValid)
        {
            OperationStatus opStatus = _CustomerRepository.Update(customer,
                c => c.CustomerID == customer.CustomerID);
            if (opStatus.Status)
            {
                ViewData["Status"] = "true";
                return View("EditCustomerForm",
                    new CustomerViewModel(_CustomerRepository.Get(c => c.CustomerID == customer.CustomerID),
                        "Navy", "Your profile information was saved."));
            }
        }
    }
    catch (Exception exp)
    {
        Logger.Log("Error in AccountController.EditCustomerProfile", exp);
    }
    ViewData["Status"] = "false";
    List<RuleViolation> violations = customer.GetRuleViolations().ToList();
    if (emailMessage != null) violations.Add(new RuleViolation("Email", emailMessage));
    ModelState.AddModelErrors(violations);
    return View("EditCustomerForm", new CustomerViewModel(_CustomerRepository.Get(c => c.CustomerID == customer.CustomerID),
        "Red", "There was a problem updating your profile."));
}

Adding UpdatePanel-like functionality into ASP.NET MVC applications is a snap and allows you to speed-up end user interaction with pages.  I personally like the fact that successful AJAX calls can easily be routed to callbacks without having to worry about wiring up any helper JavaScript objects.

 

Logo

For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit www.thewahlingroup.com/.

What ASP.NET developers should know about jQuery

As much as I enjoyed attending MIX09 this year, it wasn’t a difficult decision when Karsten asked me to write an article for the MIX Online site.

Reading this here, there’s a good chance the article is targeted below the amount of jQuery expertise you already have. However, it’s been brought to my attention that some readers have found it useful for sending to their more JavaScript-phobic coworkers.

So, I decided that it’s worth mentioning here after all:

It’s hard to believe that JavaScript is already well over a decade old. Often relegated to marginal tasks in its early years, JavaScript has grown to become a pillar of modern web development. With the current popularity of DHTML and AJAX, it can be difficult to find a site that doesn’t use JavaScript anymore. One of the driving forces behind JavaScript’s newfound popularity is a proliferation of JavaScript frameworks, such as jQuery.

 

Why?

Click here to continue reading this article on the MIX Online site »

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

What ASP.NET developers should know about jQuery

Using jQuery with Client-Side Data Binding Templates

A few weeks back I posted about a JavaScript data binding template solution that I’ve been using that makes it easy to bind JSON data to a client-side template without having to write a lot of JavaScript code.  One of the people that commented on that post asked if I could put together a sample that demonstrated the templates in action.  It took me a few weeks to get to it, but I finally made some time to put a sample together that demonstrates the fundamentals of using the client-side templates and binding JSON data to them.  As a review (in case you didn’t read my earlier post), the template solution I’ve been using recently on a client project is based on some code written by John Resig (creator of jQuery) which is extremely compact.  Here’s a tweaked version of his original code that I wrapped with a jQuery extender function (credit goes to Rick Strahl as well for a few tweaks he added):

$.fn.parseTemplate = function(data)
{
    var str = (this).html();
    var _tmplCache = {}
    var err = "";
    try
    {
        var func = _tmplCache[str];
        if (!func)
        {
            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +
            str.replace(/[rtn]/g, " ")
               .replace(/'(?=[^#]*#>)/g, "t")
               .split("'").join("\'")
               .split("t").join("'")
               .replace(/<#=(.+?)#>/g, "',$1,'")
               .split("<#").join("');")
               .split("#>").join("p.push('")
               + "');}return p.join('');";

            //alert(strFunc);
            func = new Function("obj", strFunc);
            _tmplCache[str] = func;
        }
        return func(data);
    } catch (e) { err = e.message; }
    return "< # ERROR: " + err.toString() + " # >";
}

The parseTemplate method can be applied against a client-side template like the one below.  Notice that the template is wrapped in a script block with the type set to text/html so that it isn’t rendered by the browser.  JSON properties are written out by using the <#= …  #> syntax and the template engine has full support for embedded JavaScript code.

<script id="MyTemplate" type="text/html">
    <table style="width:400px;">
        <thead>
            <tr>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Address</th>
            </tr>
        </thead>
        <tbody>
        <#
            for(var i=0; i < d.length; i++)
            {
               var cust = d[i];
        #>
                <tr>
                   <td id="CustomerRow_<#= i.toString() #>">
                        <#= cust.FirstName #>
                   </td>
                   <td>
                        <#= cust.LastName #>
                   </td>
                   <td>
                      <#= cust.Address.Street #>
                      <br />
                      <#= cust.Address.City #>, <#= cust.Address.State #>
                      &nbsp;&nbsp;<#= cust.Address.Zip #>
                   </td>
                </tr>
        <#
            }
        #>
        </tbody>
    </table>
    <br />
    <#= d.length #> records shown
</script>

This template outputs a simple table like the one shown next.  Sure, I could’ve generated the table using DOM manipulation techniques, but being able to tweak a data template is much easier and productive in my opinion.

image


In order to use the template you’ll need to have some JSON data available.  Here’s an example of creating JSON by hand and binding it to the template using the parseTemplate method shown earlier.  The data returned from the template data binding operation is passed to the html method of the target div which displays the data in the browser.  Note:  I’m defining the “d” property in the JSON object since WCF uses that name by default when it returns serialized JSON data.

var json =
        {
            "d":
            [
               { "FirstName": "John", "LastName": "Doe",
                 "Address":
                  { "Street": "1234 Anywhere St.", "City": "Phoenix",
                    "State": "AZ", "Zip": 85044 }
               },
               { "FirstName": "Jane", "LastName": "Doe",
                   "Address":
                  { "Street": "435 Main St.", "City": "Tempe",
                    "State": "AZ", "Zip": 85245 }
               },
               { "FirstName": "Johnny", "LastName": "Doe",
                 "Address":
                  { "Street": "643 Chandler Blvd", "City": "Chandler",
                    "State": "AZ", "Zip": 85248 }
              },
               { "FirstName": "Dave", "LastName": "Doe",
                 "Address":
                  { "Street": "18765 Cloud St.", "City": "Mesa",
                    "State": "AZ", "Zip": 85669 }
               }
            ]
        };
var output = $('#MyTemplate').parseTemplate(json);
$('#MyTemplateOutput').html(output);

Of course, in the real-world you’ll probably get the JSON data from some type of service (WCF, ASMX, REST, etc.).  Here’s a WCF service that returns a List of Customer objects and converts them to JSON.  The service has the client script behavior enabled so that serialization from CLR objects to JSON objects occurs behind the scenes automatically.

[ServiceContract(Namespace = "http://www.thewahlingroup.com")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CustomerService
{
    [OperationContract]
    public List<Customer> GetCustomers()
    {
        return new List<Customer>
        {
            new Customer {FirstName="John",LastName="Doe",
                          Address=new Address{Street="1234 Anywhere St.",City="Phoenix",State="AZ", Zip=85044}},
            new Customer {FirstName="Jane",LastName="Doe",
                          Address=new Address{Street="435 Main St.",City="Tempe",State="AZ", Zip=85245}},
            new Customer {FirstName="Johnny",LastName="Doe",
                          Address=new Address{Street="643 Chandler Blvd",City="Chandler",State="AZ", Zip=85248}},
            new Customer {FirstName="Dave",LastName="Doe",
                          Address=new Address{Street="18765 Cloud St.",City="Mesa",State="AZ", Zip=85669}}
        };
    }

}


jQuery’s ajax method can then be used to call the WCF service and retrieve the data (jQuery provides other methods such as getJSON that could be used too if desired):

$.ajax(
{
    type: "POST",
    url: "CustomerService.svc/GetCustomers",
    dataType: "json",
    data: {},
    contentType: "application/json; charset=utf-8",
    success: function(json)
    {
        var output = $('#MyTemplate').parseTemplate(json);
        $('#MyTemplateOutput').html(output);

        //Add hover capabilities
        $('tbody > tr').bind('mouseenter mouseleave', function()
        {
            $(this).toggleClass('hover');
        });
    }
});

This code defines the type of operation, service URL to call, any data passed to the service, the content type and a success callback.  Once the service call returns, the JSON data is bound to the template shown earlier by locating the area where the template should be rendered to (MyTemplateOutput in this example) and then calling parseTemplate.  Hover capabilities are also added using jQuery’s bind method to highlight rows as the user moves the mouse in and out of them. 

You can see that the amount of custom Javascript that has to be written is kept to a minimum by combining jQuery with the client-side template which ultimately leads to easier maintenance down the road.  This is just one of several different client-side template solutions out there.  ASP.NET 4.0 will also include a custom client-side template solution as well as mentioned in my previous post.

Download the sample code here

Logo

For more information about onsite, online and video training, mentoring and consulting solutions for .NET, SharePoint or Silverlight please visit www.thewahlingroup.com/.

How I handle JSON dates returned by ASP.NET AJAX

A calendar

The problem of how to handle dates in JSON is one of the more troublesome issues that may arise when directly calling ASP.NET AJAX web services and page methods.

Unlike every other data type in the language, JavaScript offers no declarative method for expressing a Date. Consequently, embedding them within JSON requires a bit of fancy footwork. Since the question of how I handle this problem is something asked often in emails and in comments on other posts here, I want to address the topic with its own post.

To that end, I will attempt to explain what exactly the problem is with dates in JSON, how ASP.NET AJAX solves it, and my alternative solution that I believe is easier and works just as well in most cases.

What’s the problem?

The fundamental problem is that JavaScript does not provide a way to declaratively express Date objects. You may previously have seen this described as (the lack of) a Date literal.

What are literals? To illustrate, these are literals for several other data types:

// String
'foo';
 
// Number
3.14;
 
// Boolean
true;
 
// Array
[1, 2, 3, 5, 7];
 
// Object
{ pi: 3.14, phi: 1.62 };

Unfortunately, when it comes to dates, the lack of a literal means that the only way to create one is by explicitly initializing a Date object:

// Correct.
new Date('4/26/09');
 
// Correct (the month is 0 indexed, hence the 3).
new Date(2009, 3, 26);
 
// Incorrect. This is a string, not a Date.
'4/26/09';

While this limitation is fine when writing client-side JavaScript code, it leaves us without a good way to transmit dates within JSON objects.

How ASP.NET AJAX handles it

While the lack of a date literal is a problem, it’s certainly not without solution.

In fact, ASP.NET AJAX already handles this if you’re using MicrosoftAjax.js to call your services. You may not have even noticed as server-side DateTime values are transparently converted into JavaScript Date objects on the client-side.

For example, consider this web service:

[System.Web.Script.Services.ScriptService]
public class DateService : System.Web.Services.WebService
{
  [WebMethod]
  public DateTime GetDate()
  {
    return new DateTime(2009, 4, 26);
  }
}

If you consume that web service with jQuery (or any method that circumvents the ScriptManager), you’ll find that ASP.NET AJAX serializes the DateTime as an escaped JavaScript Date initializer:

{"d":"/Date(1240718400000)/"}

Note: If you’re unsure about why the “d” is there, be sure to see my recent post about this security feature which was added in ASP.NET 3.5.

On the client-side, MicrosoftAjax.js uses a regular expression to isolate any Date constructors and then eval() to initialize Date objects. The end result is that proper JavaScript Date objects are instantiated for every DateTime value returned.

However, if you’re not using MicrosoftAjax.js (i.e. the ScriptManager) to call your services, you’ve got a bit of a mess to decode. You can use regex machinations to work around the problem, but is that really necessary?

How I handle it

Consider why you want to send a DateTime to the client-side to begin with. Most often, you’re displaying a string representation of it and have no need for the proper JavaScript Date object.

What’s more, if you end up with a JavaScript Date object, you’ll probably use additional code or a JavaScript library to display it in a user-friendly format.

As much as I appreciate a clever workaround, I’d much rather avoid the problem completely. Rather than jump through all of these hoops to instantiate a JavaScript Date object on the client-side and then format it, I suggest simply returning a formatted string.

For example, we might modify the previous example like so:

[System.Web.Script.Services.ScriptService]
public class DateService : System.Web.Services.WebService
{
  [WebMethod]
  public string GetDate()
  {
    return new DateTime(2009, 4, 26).ToLongDateString();
  }
}

Now, calling the service will return this JSON:

{"d":"Sunday, April 26, 2009"}

No more regular expressions. No more JavaScript Date objects. No more worrying about formatting the data on the client-side.

Even better, no functionality is lost. If we need to instantiate Dates, we still can.

Still want Dates?

Even if you do end up needing JavaScript Date objects, DateTime strings are sufficient for instantiating them. JavaScript’s Date constructor is very flexible:

// ASP.NET AJAX form
var foo = new Date(1240718400000);
 
// DateTime.ToLongDateString() form
var bar = new Date('Sunday, April 26, 2009');
 
// DateTime.ToShortDateString() form
var baz = new Date('4/26/2009');
 
// true!
foo === bar === baz;

By delaying string-to-Date conversions until truly necessary, we save effort on the server- and client-side. Not only that, but we have the option of retaining both the formatted string and the JavaScript Date to use as desired.

The best of both worlds.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

How I handle JSON dates returned by ASP.NET AJAX

WP Like Button Plugin by Free WordPress Templates