in

Platinum Bay

Peace, Love, and...

This Blog

Syndication


.NETicated

August 2009 - Posts

  • jQuery and MVC: JSON Form Submission

    In my last two posts (jQuery and MVC: JSON and Favorite Image Icons with jQuery and MVC) I covered some basics of jQuery’s AJAX functionality to improve user experience. One of the scenarios which may not seem particularly asynchronous friendly is form submission. Fortunately, jQuery provides for asynchronous post, and in JSON format too.

    The complete code to perform this is:

    $('form').submit(function(e) {
    e.preventDefault();
    $.post($(
    this).attr("action"), $(this).serialize(), function(json) {
    // handle response
    }, "json");
    });

    First, get a jQuery reference to the form element and add a submit event handler:

    $('form').submit(function(e) {

    Next, we need to cancel the form’s default behavior by using the preventDefault function:

    e.preventDefault();
    Next, and this is the cool part, we call the post method in jQuery. The post method takes four arguments: url, data, callback, and type. The first three should be familiar from the previous blog posts, but the last one is new. The type parameter specifies the type of data and accepts "xml", "html", "script", "json", "jsonp", or "text". The example above is using JSON.

    Rather than hard coding the url, it can be retrieved from the form element itself:

    $(this).attr("action")

    And rather than manually pulling form fields into the data object, as the form may change, we can call jQuery’s serialize function on the form itself:

    $(this).serialize()

    Finally, we can tie it all together with an MVC action. This example uses the Employee entity from the Northwind database. Since the identifier on the Employee entity is EmployeeID and not ID, id needs to be specified as an action parameter in order to retrieve the correct employee from the database.

    [AcceptVerbs(HttpVerbs.Post)]
    public JsonResult Edit(int id, Employee employee)
    {
    // do work
    return new JsonResult { Data = new { Success = true } };
    }

    One common scenario for this functionality is to provide asynchronous searching within a page. Even asynchronous form submits are possible with jQuery, making your arsenal that much more powerful.

    Posted Aug 31 2009, 10:33 PM by Steve with 16 comment(s)
    Filed under: , ,
  • Favorite Image Icons with jQuery and MVC

    User experience, that’s the name of the game these days. Green screens and console applications are (hopefully) becoming a thing of the past. In the web world, this means a more fluid and asynchronous experience. In my last post, I gave a quick introduction to using jQuery and MVC to perform asynchronous requests to the browser. In this post, I will expand on that topic and show how to build a favorite image icon.

    The concept is pretty simple. For example, in the Twitter web UI, an empty star image appears on the right side of a tweet if you mouse over it.If the star is clicked, the icon changes to a flashing dot, and then to a yellow star indicating that the tweet has been favorited. It’s a neat, asynchronous effect, and it’s fairly simple to achieve.

    First, we need three images. Here are the images that Twitter uses:

    Next, a CSS style is defined for the off, on, and loading states. The purpose of each style is to allow style switching to not only change the picture, but also to allow the state to be determined through the style class assigned.

    .favimgoff, .favimgon, .imgload { width: 16px; height: 16px; border: 0px; background-repeat: no-repeat; }
    .favimgoff { background-image: url(images/icon_star_empty.gif); }
    .favimgon { background-image: url(images/icon_star_full.gif); }
    .imgload { background-image: url(images/icon_throbber.gif); }

    On the MVC side, an action is needed to handle the server processing.

    public JsonResult SetOrRemoveUserFavorite(int favoriteId)
    {
    JsonResult result = new JsonResult();

    // do work here, and set SetOn to the proper state
    result.Data = new { Success = true, SetOn = true };

    return result;
    }

    Next, on the client side, add an image tag with the class attribute and id set. The image is set to a one pixel transparent gif otherwise certain browsers may not render the background image.

    <img class="favimgoff" src="<%= Url.Content("~/Content/images/spacer.gif")%>" id="1" />

    Finally, jQuery on the client side takes care of the tying it all together:

    $('.favimgoff, .favimgon').click(function() {
    var $favimg = $(this);
    if ($favimg.attr('class') != 'imgload') {
    $favimg.removeClass().addClass(
    'imgload');
    $.getJSON(
    '<%= Url.Action("SetOrRemoveUserFavorite", "Services") %>', {
    favoriteId: $favimg.attr(
    'id')
    },
    function(json) {
    if (json.Success) {
    if (json.SetOn) {
    $favimg.removeClass().addClass(
    'favimgon');
    }
    else {
    $favimg.removeClass().addClass(
    'favimgoff');
    }
    }
    else {
    alert(
    'Favorite could not be set. Please refresh the page and try again.');
    }
    });
    }
    });

    Let’s step through the jQuery script. First, define the click event handler for both classes, and get a reference to the image clicked:

    $('.favimgoff, .favimgon').click(function() {
    var $favimg = $(this);

    Next, to avoid any duplicate action taken while the process is run, make sure the image isn’t in the loading state. This is necessary because jQuery will still have an event reference to the original image even when the class changes from the original two classes of on or off.

    if ($favimg.attr('class') != 'imgload') {

    Next, remove any existing class and add the loading class so the user gets feedback that their action is being processed:

    $favimg.removeClass().addClass('imgload');

    Then, make a server call to the action defined, and pass the id of the item as a parameter to the action:

    $.getJSON('<%= Url.Action("SetOrRemoveUserFavorite", "Services") %>', {
    favoriteId: $favimg.attr(
    'id')
    },
    function(json) {
    if (json.Success) {

    Finally, based on the SetOn value returned from the server call, remove the loading class and set the appropriate class:

    if (json.SetOn) {
    $favimg.removeClass().addClass(
    'favimgon');
    }
    else {
    $favimg.removeClass().addClass(
    'favimgoff');
    }

    If by chance the server call fails and Success is false, alert the user:

    alert('Favorite could not be set. Please refresh the page and try again.');

    That’s it. Utilizing the baked-in goodness of jQuery and ASP.NET MVC, providing a rich, asynchronous user experience doesn’t have to be complex.

    Posted Aug 29 2009, 08:01 PM by Steve with 8 comment(s)
    Filed under: , ,
  • jQuery and MVC: JSON

    I strongly dislike synchronous browser requests: the request has to be sent to the server, server action is performed, a server response is received, and the page is re-rendered which usually involves reloading images, style sheets, JavaScript files, etc. It takes time, sends an awful lot of traffic across the wire, and it doesn’t provide for the best user experience. In some scenarios this makes sense, but in most cases I find it to be an annoyance.

    Enter jQuery to the rescue. jQuery is the most exciting innovation to happen to JavaScript since, well, maybe JavaScript itself. One of the jQuery features I enjoy the most is the AJAX functionality which allows jQuery to talk to the server asynchronously, or behind the scenes.

    I personally like to use the JSON (JavaScript Object Notion) format, which is lighter-weight than XML. Using jQuery, a JSON GET request is written as:

    $.getJSON('[url]', { [parameters] }, function(json) {
    // callback function code
    });

    Let’s say I want to perform an asynchronous search in my web page for people names without having to reload the page. In MVC, I need an action to handle the request:

    public class SearchController : Controller
    {
    string[] peopleNames = new[] { "Bob", "Steve", "Joe", "Frank", "Lou" };

    public JsonResult Search(string q)
    {
    var results = peopleNames.Where(n => n.Contains(q));

    if (results.Count() > 0)
    return new JsonResult { Data = new { Success = true, Results = results } };
    else
    return new
    JsonResult { Data = new { Success = false } };
    }
    }

    The first thing to notice is the built-in JsonResult type on the Search action. MVC understands and is able to handle JSON data. Simply return a JsonResult object and populate the Data property with the data to be returned. The serialization of that data is handled under the covers.

    Back in the MVC View, call getJSON to make a request to the action and handle the response:

    $.getJSON('<%= Url.Action("Search", "Search") %>', { q: $('input#search') }, function(json) {
    if (json.Success) {
    // results found
    }
    else {
    // nothing found
    }
    });
    Note that Url.Action is used to get the virtual url. Url.Action and Url.Content are great ways to handle relative paths. Next, the search query is passed from an input field with an ID of search. And finally, the callback is handled. jQuery handles the deserialization under the covers, and the values can be handled as simple properties.

    The introduction of ASP.NET MVC and jQuery make asynchronous calls very quick and easy, and help to provide the end user with a better experience. In future posts, we’ll look at more specific examples of utilizing jQuery and MVC to provide a better user experience.

    Posted Aug 28 2009, 07:09 PM by Steve with 45 comment(s)
    Filed under: , ,
  • Reflection-Based Performance Analysis

    Back in 2007, I took some SharePoint training from Todd Bleaker (MVP, owner of MindSharp, and SharePoint guru). At one point he posed a question about the performance of the following methods:

    public string OptionOne()
    {
        string str = "Hello World";
        return str;
    }
    
    public string OptionTwo()
    {
        string str;
        str = "Hello World";
        return str;
    }
    
    public string OptionThree()
    {
        string str = null;
        str = "Hello World";
        return str;
    }
    
    public string OptionFour()
    {
        return "Hello World";
    }

    I took the challenge and wrote the above methods. Then to evaluate the probable performance I compiled the code and opened the resulting assembly in Reflector. Here is the Reflector output:

    public string OptionOne()
    {
        return "Hello World";
    }
    
    public string OptionTwo()
    {
        return "Hello World";
    }
    
    public string OptionThree()
    {
        return "Hello World";
    }
    
    public string OptionFour()
    {
        return "Hello World";
    }

    You may notice that all the methods appear the same. What happened? Compiler optimization? To find out I checked the IL, shown below:

    .method public hidebysig instance string OptionOne() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string str,
            [1] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "Hello World"
        L_0006: stloc.0 
        L_0007: ldloc.0 
        L_0008: stloc.1 
        L_0009: br.s L_000b
        L_000b: ldloc.1 
        L_000c: ret 
    }
    
    .method public hidebysig instance string OptionTwo() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string str,
            [1] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "Hello World"
        L_0006: stloc.0 
        L_0007: ldloc.0 
        L_0008: stloc.1 
        L_0009: br.s L_000b
        L_000b: ldloc.1 
        L_000c: ret 
    }
    
    .method public hidebysig instance string OptionThree() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string str,
            [1] string CS$1$0000)
        L_0000: nop 
        L_0001: ldnull 
        L_0002: stloc.0 
        L_0003: ldstr "Hello World"
        L_0008: stloc.0 
        L_0009: ldloc.0 
        L_000a: stloc.1 
        L_000b: br.s L_000d
        L_000d: ldloc.1 
        L_000e: ret 
    }
    
    .method public hidebysig instance string OptionFour() cil managed
    {
        .maxstack 1
        .locals init (
            [0] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "Hello World"
        L_0006: stloc.0 
        L_0007: br.s L_0009
        L_0009: ldloc.0 
        L_000a: ret 
    }

    What is really happening is that Reflector is making a best guess optimization as to what the original code looked like. We can clearly see in the IL that OptionFour is probably the most performant, and OptionThree is probably the least. This is because OptionThree is loading a null and storing it in local 1, then loading the string and storing it in the same location, making the first load unnecessary.

    Reflector can be a great tool to use for analyzing possible performance, as well as debugging assemblies. If you don’t have it, download it today: www.red-gate.com/products/reflector/

    Posted Aug 28 2009, 04:51 AM by Steve with 2 comment(s)
    Filed under: ,
  • Running T4 Templates with MSBuild

    If you haven’t explored T4 yet, you’re missing one of Visual Studio’s best, and best kept, secrets. T4, which stands for Text Templating Transformation Toolkit, is code generation built right into Visual Studio 2008. It is also available in Visual Studio 2005 if you install the Visual Studio SDK. It is a great feature that I use quite frequently to automate repetitive tasks.

    T4 template execution only occurs though when the template file is open in the editor and saved. In other words, template execution does not occur when you type Ctrl+B to build the project. There are scenarios however where execution of the templates at every build is the desired behavior.

    I did find several custom MSBuild tasks to perform this behavior, but I wanted to avoid additional assembly references. Instead, the following custom MSBuild target was created to address this.

    First and foremost, a .targets file is created in the MSBuild directory (%systemdrive%:\Windows\Microsoft.NET\Framework\v3.5):

    <?xml version="1.0" encoding="utf-8"?>
    <
    Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <
    Target Name="ExecuteT4Templates">
    <
    ItemGroup>
    <
    T4Templates Include=".\**\*.tt" />
    </
    ItemGroup>
    <Exec
    WorkingDirectory="C:\Program Files\Common Files\microsoft shared\TextTemplating\1.2\"
    Command="TextTransform &quot;%(T4Templates.FullPath)&quot;" />
    </
    Target>
    </
    Project>

    There are a couple important things to note. First, a custom target is created, and an item group is added to the target. In the item group, we create a new item called T4Templates that will recurse the project and hold information for each text template that is found. Finally, an execute task is added which calls TextTransform.exe for each file found.

    Once the targets file is create, the project file is edited to import the new targets file using Import. I put it above the first PropertyGroup node so it’s visible when future maintenance is performed, but it can be placed anywhere within the root Project node:

    <Import Project="$(MSBuildToolsPath)\T4Execution.targets" />

    Finally, the DefaultTargets attribute in the Project node is modified to include the ExecuteT4Templates target: Note: This change is required for any project where this behavior is desired.

    DefaultTargets="ExecuteT4Templates;Build"
    Now whenever the project is built (Ctrl+B), template execution occurs. To be fair, there are several issues with the above approach, including:
    • Template execution does not occur when Debug (F5) is triggered unless a project file or property has changed.
    • There is no built-in way to get the number of items in an ItemGroup to use conditional execution.

    How important is this functionality in your projects? How would you do it differently?

  • Pop Quiz: .NET Integers, Unit Testing, and Boundary Checking

    I ask this question in a bunch of my talks, mostly because most folks aren’t aware of this. What is the bug in the following method?

    public int Add(int num1, int num2)
    {
        return num1 + num2;
    }

    Do you see it? In a simple unit test, the method appears to work as expected:

    [TestMethod()]
    public void AddTest()
    {
        MathHelper target = new MathHelper();
        int num1 = 16;
        int num2 = 16;
        int expected = 32;
        int actual = target.Add(num1, num2);
        Assert.AreEqual(expected, actual); // PASS
    }

    However, what if we pass in a different set of parameters, say int.MaxValue?

    [TestMethod()]
    public void AddMaxTest()
    {
        MathHelper target = new MathHelper();
        int num1 = int.MaxValue;
        int num2 = int.MaxValue;
        int result = target.Add(num1, num2);
    
        Assert.Fail("Expected an overflow exception. Received: " + result);
    }

    Any guesses on the outcome of this test? In actuality, no exception is thrown. The test fails with the output: “Assert.Fail failed. Expected an overflow exception. Received: -2”. The output from the fail assert is “-2”. What!? Is it a bug in the .NET framework? What’s going on?

    The answer lies in that I am passing in a signed int. In a signed int, the top bit is flag bit indicating positive or negative, leaving the other 31 bits to indicate the numeric value. When doing binary math that overflows the 31 bits, the 32nd bit is switched as though it is unsigned. In this case a positive becomes a negative and the result becomes –2. Let’s hope the system isn’t trying to deposit $100 into an account with $2,147,483,647.

    But what does this mean to the original method? How do we handle this scenario? The point of this experiment isn’t to demonstrate a potential issue with the .NET framework. Rather, I’d like you to take notice of the first unit test. The test does evaluate the method for proper functioning, 100% code coverage would be achieved on the Add method, and yet the issue at hand is not found. And to this I would like to make an important point:

    Code Coverage is a misleading metric.

    In order to properly test your code, it is important to not only make sure you test as much as possible, but to ensure you also perform boundary checking. If the max values weren’t tested, it might not have been found that the code could erase $2,147,483,749 from some pour soul’s bank account. Well, he’d be poor after the fact. Are here is my second point:

    Boundary check everything.

    To help solve this problem, there is a neat tool from Microsoft Research called Pex. From the Pex website:

    Right from the Visual Studio code editor, Pex finds interesting input-output values of your methods, which you can save as a small test suite with high code coverage. Pex performs a systematic analysis, hunting for boundary conditions, exceptions and assertion failures, which you can debug right away. Pex enables Parameterized Unit Testing, an extension of Unit Testing that reduces test maintenance costs.

    What I would really love to see someday is a combination of existing code coverage in Visual Studio Team System with parameter boundary checking in Pex to give a truer sense of test coverage. Maybe for Dev11?

  • LINQ: Porting jQuery’s Each

    As some astute readers pointed out, this functionality does in fact exist in LINQ. The name isn’t terribly obvious however: Aggregate. I was able to update the original tests to use the Aggregate method. The main difference is that a non-generic IEnumerable does not contain this functionality. For that type I had to use:

    .OfType<>()

    The updated test methods are here:

    IEnumerable<string> collection = new[] { "Hello", "World", "!" };
    string result = collection.Aggregate((str1, str2) => (str1 + " " + str2).Trim());
    IEnumerable<int> collection = new[] { 1, 2, 3, 4, 5 };
    int result = collection.Aggregate((num1, num2) => num1 + num2);
    IEnumerable collection = new[] { "Hello", "World", "!" };
    string result = collection.OfType<string>().Aggregate((string str1, string str2) => (str1 + " " + str2).Trim());
    var collection = new List<string> { "Hello", "World", "!" };
    string result = collection.Aggregate((str1, str2) => (str1 + " " + str2).Trim());

    I love learning new stuff, thanks to Steve Gilham and Jordan Terrell for their comments below.

     

    I really like the Each function in jQuery, and I find myself wanting to use it in LINQ. Since it doesn’t exist I decided to write one. Here goes:

    using System;
    using
    System.Linq;
    using
    System.Collections;
    using
    System.Collections.Generic;

    public static class
    ExtensionMethods
    {
    public static TType Each<TType>(this IEnumerable<TType> collection, Func
    <TType, TType, TType> func)
    {
    var result = default
    (TType);

    foreach (var queryable in
    collection)
    result = func(result, queryable);

    return
    result;
    }

    public static TType Each<TType>(this IEnumerable collection, Func
    <TType, TType, TType> func)
    {
    return
    collection.OfType<TType>().Each(func);
    }
    }

    You can then call these extension methods using any IEnumerable type, such as List, Collection, etc. I’m utilizing lambdas to define inline methods, though a delegate to an existing method could be passed in as well.

    IEnumerable<string> collection = new[] { "Hello", "World", "!" };
    string result = collection.Each((str1, str2) => (str1 + " " + str2).Trim());
    IEnumerable<int> collection = new[] { 1, 2, 3, 4, 5 };
    int result = collection.Each((num1, num2) => num1 + num2);
    IEnumerable collection = new[] { "Hello", "World", "!" };
    string result = collection.Each((string str1, string str2) => (str1 + " " + str2).Trim());
    var collection = new List<string> { "Hello", "World", "!" };
    string result = collection.Each((str1, str2) => (str1 + " " + str2).Trim());

    What do you think? Would you do it differently?

    Posted Aug 26 2009, 07:26 PM by Steve with 8 comment(s)
    Filed under: ,
  • Static Page Checking in ASP.NET MVC

    If you have built an ASP.NET web forms site of any substance, you have undoubtedly been bitten when code in the web form becomes outdated due to code change. It’s easy to see when the page is open in Visual Studio, as the code has red squiggles and the error shows up in the Error List tool window. As soon as the page is closed however, that error disappears. Even running a build will be successful. For some of my sites, which have over 150 pages, this can be very annoying to say the least.

    ASP.NET MVC has a neat hidden feature to solve this problem. The MVC team was most likely were stung by the same issue more than once. This feature is static page checking during compilation. Unfortunately, instead of being an option in the Properties window for the project (future release idea?), it is in the *.*proj xml file itself. To enable this feature:

    1. Right-click on the Project node in the Solution Explorer tool window
    2. Choose “Unload Project” - Note: If your project is under version control, you will be prompted to do a check-in. Simply click “Continue” to ignore the check-in request.
    3. Right-click the Project node again
    4. Choose “Edit *.*proj", and the project file will now open in Visual Studio with color coding and IntelliSense
    5. In the first PropertyGroup node, there is a new node named MvcBuildViews
    6. By default this is set to false. Simply change the value to true
    7. Right-click the Project node and choose “Reload Project”
    8. If prompted that the file is already open, click yes to close the xml view.
    9. Build your project

    You will notice that builds take longer than they did prior to this change. This is because under the covers, MSBuild is now making an additional call to aspnet_compiler in the AfterBuild MSBuild target:

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v temp -p "[physical path]"

    To avoid this delay in day-to-day development, you may choose to copy the MvcBuildViews node into the build-specific PropertyGroup nodes, and set it to false for Debug and true for Release.

    Update: @jglozano points out that this only works with the default WebForms View Engine.

    Hope this helps

    Posted Aug 21 2009, 02:35 PM by Steve with 47 comment(s)
    Filed under: ,
Powered by Community Server (Commercial Edition), by Telligent Systems
© Platinum Bay | Some Rights Reserved Creative Commons License

Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever (abusive, profane, rude, or annonymous comments) - so keep it polite, please.