Wednesday, January 22, 2014

Ignoring properties when serializing to JSON using JSON.NET

I ran into this particular issue while using SignalR, but it would happen in any case where you are serializing data to JSON using Newtonsoft’s JSON.NET library.  I was finding that properties on my C# object were clearly marked with the [ScriptIgnore] attribute were still being serialized, which was sending unnecessary data down to the browser.


1
2
3
4
5
6
7
8
[ScriptIgnore]
public string TileName
{
get
{
return Tile.GetTileName(this.TileCode);
}
}

The answer turned out to be simple: SignalR uses JSON.NET behind the scenes to do the heavy serialization lifting, and JSON.NET looks for the [JsonIgnore] attribute instead.







1
2
3
4
5
6
7
8
[JsonIgnore]
public string TileName
{
get
{
return Tile.GetTileName(this.TileCode);
}
}

If only all of my annoying little bugs were this easy to solve!

  

Friday, July 16, 2010

jQuery, JSONP, and the Same-Origin Policy

First of all, my apologies for the rather massive delay on my JavaScript template series.  The combination of a new job and a family doesn’t allow much time for blogging.  But the topic of client-side template engines is still a hot one, so I plan to resume the series in the near future.

I just finished reading the post on DotNetCurry about using jQuery to query Twitter’s public API.  It is a great post, but I thought that some developers might want some additional details on how exactly the code in the article is able to get around browsers’ same-origin policy.  At first glance, there appears to be some magic involved.

As I’m fond of saying, there is no magic in software development, so let’s see what is really going on:

Browsers prevent JavaScript code from accessing resources from a different domain than the one that delivered the page in the first place.  This is a security feature designed to prevent the browser from unwittingly passing (possibly sensitive) data from one site (your bank’s online account page, for example) to a malicious third party.  Unfortunately, this same policy means that well-meaning scripts are unable to access potentially useful external resources (a third-party web service like Twitter’s, for example).

Is there a loophole?  It turns out that the <script> tag is exempt from the same-origin policy.  It really must be, if you think about it: otherwise, a page would only be able to reference JavaScript files served from the same domain as the page.  Content delivery networks, for example, would be impossible as a result.

JSONP to the rescue.  JSONP stands for “JSON with Padding”.  Actually, I’ve always thought that this was a misleading name.  It is padded, in a sense, but I think a better name would have been “JSONC” for “JSON with Callback”.  Instead of using vanilla Ajax to call a remote web service that then returns JSON to our page, we put the URL to the remote web service in the src=”” attribute of a <script> tag and (here is the key part) include the name of a callback function in the URL.  The typical way this is done is to append callback=<functionname> to the end of the URL:

<script type="text/javascript" src="http://api.twitter.com/1/statuses/user_timeline/mattspeterson.json?callback=DisplayResults"></script>

We are responsible for writing the DisplayResults() function to handle the JSON data returned by the web service call and passed as a parameter to this function.  The remote web service is responsible for noticing that we have appended the name of a callback function and wrapping the results appropriately when they are sent to us.

But the example in the blog post referenced above didn’t use this technique.  So what gives?

It turns out that jQuery’s $ajax.getJSON() method is doing some extra leg-work for us.  Let’s have a look at a similar example:

<script type="text/javascript">

    $(document).ready(function () {
        $.getJSON("http://api.twitter.com/1/statuses/user_timeline/mattspeterson.json?callback=?", DisplayTweets);
    });

    function DisplayTweets(tweets)
    {
        // Bind the tweets returned to the DOM using your JavaScript template engine of choice...
    }

</script>

The getJSON() method looks for callback=? in the first parameter (the URL) and if it is present, dynamically creates a “throwaway” callback function and puts its name in the ? placeholder when it makes the Ajax call to the URL.

Using your web developer tool of choice (I’m using Google Chrome’s tools), you can verify that this is what is happening:

image

Let’s have a look at the response we get back from this call to the Twitter API:

image

The response isn’t JSON-encoded data, it is a call to the ad-hoc callback function that jQuery created for us on the fly with the data passed as a parameter.  So where is this callback function?  jQuery has dynamically added it to the DOM:

image

image

$ajax.getJSON() does one more bit of work for you: it calls $.parseJSON() to convert the JSON-encoded string returned from the Twitter web service to a JavaScript object before passing it to your named callback function:

image

Hope this helps shine a light on the inner workings of JSONP.  The lesson here is that jQuery really does a lot of the messy heavy lifting for you so that your web application can get around a well-intentioned security policy imposed by your browser.

Monday, March 29, 2010

JavaScript Template Engines - Introduction

I’m about to begin a series of posts on JavaScript template engines.  There is currently a fair amount of buzz about them among web developers and I think they serve a purpose, so I’d like to dig into them a bit.  I’m considering using this series as the basis for an upcoming talk as well.

In the next post (part I), I’ll explain what JavaScript template engines are and how they work.  In part II, I’ll look at the use cases for them and break down when they are (and are not) appropriate.  Finally, I’ll put together a series of posts where I investigate particular template solutions.  Among the criteria I’ll be evaluating are: size of the library, template syntax style, features, and performance.  I don’t have a fixed list in mind, but I imagine I’ll write about five or six of the most popular ones.  Some candidates are:

In addition, Microsoft has recently announced a proposal for a template engine to be built into a future release of jQuery core, which seems like a natural addition to the library.  I’ll keep an eye on this as well.

Finally, I’m aware that client-side data binding is a feature of the ASP.NET Ajax library (now integrated into the ASP.NET Ajax Control Toolkit).  I imagine that there are also similar capabilities in YUI, although I haven’t used it.  However, both of these solutions include a great deal of functionality beyond pure JavaScript templates, so I doubt I’m going to spend any time on them.  Microsoft seems to have acknowledged this and is nudging developers interested in a simple client-side solution to the aforementioned jQuery proposal.

Stay tuned!

Thursday, August 6, 2009

Debugging Tip of the Day

I feel like a moron for having to be reminded of something obvious like this, but when tracking down a particularly nasty bug, it helps to start by looking into parts of the code you don't understand particularly well...

Monday, April 28, 2008

Coding Music

I love music as much as I love writing software, but I've found that most music is too distracting for listening while coding. Then I discovered ambient music. Like most music genres, the definition as to what constitutes ambient music is a bit fuzzy, but I would define it as music which is written to be heard, but not necessarily to be listened to. Very often, ambient is lumped into the category of new age music and indeed, some new age music is also ambient, but they aren't technically the same thing.

But I try to be practical, so if you are interested in exploring the genre, here are artists and albums I would recommend starting with:

(I've linked to the downloadable MP3 album on Amazon where possible; some albums aren't available in MP3 format, so I linked to the CD version. In some cases, these are available for download on the iTunes music store, but in keeping with my recent "no DRM" policy, I'm not linking to those...but just so you know, many of them are there.)
  • Brian Eno - Ambient 1/Music for Airports - Brian Eno is generally considered to be the father of modern ambient music and this album, released in 1977, is his first major work in the genre.
  • Brian Eno - Discreet Music - To be honest, I don't care for the B-sides on this album (variations on Pachelbel's famous Canon in D), but the 31-minute title track is worth the price.
  • Harold Budd and Brian Eno - Ambient 2/The Plateaux of Mirror - This time, Eno collaborates with another of the early ambient composers, Harold Budd (more on him later).
  • Harold Budd - The Room - Budd has a similar style to Eno, but different enough for variety. This is my favorite Harold Budd album.
  • Steve Roach - Dreamtime Return - Steve Roach is another giant of the genre, and this album would easily make most ambient fan's "top ten" list. This album has a more tribal, rhythmic sound than most of his work (or the rest of this list, for that matter), but is still beautiful. Unfortunately, Amazon doesn't seem to currently have this album in downloadable form.
  • Steve Roach - Structures from Silence - Another great album from Steve Roach. Again, this one isn't available in MP3 format, but Amazon does have the CD.
A few more that are a little less well-known, but I love nonetheless:
  • Deepspace - The Barometric Sea - This one lives a little closer to the "space music" corner of the ambient genre, but a great album.
  • Deuter - Earth Blue - Deuter usually lives in the meditative, "spiritual" area of the genre. All of their albums are good, but I have this album and like it, so I've included it.
  • Falling You - Touch - This isn't strictly an ambient album (some of the tracks actually have lyrics), but it is incredibly haunting and beautiful. One of my favorites.
  • Jon Serrie - Century Seasons - Jon Serrie specializes in space music. His work is so beautiful. This is a compilation album, but since Amazon does not carry it (the iTunes store does), I've linked to a page of his other downloadable albums.
  • Liquid Mind - I haven't linked to a specific album because, unfortunately, I think all of his stuff sounds pretty much the same. But that doesn't make it any less beautiful.
  • Michael Stearns - Encounter - This is my absolute favorite ambient album. Cold, distant, and haunting, I would describe this as an alien abduction set to music. When I was a kid living near Little Rock, I used to sit in bed at night listening to a local AM radio talk show about weird stuff like UFOs and space travel. The host used bits of this album as bumper music, so I would fall asleep with this in my head. I never knew the album title or Stearns' name until years later when I stumbled across it online and recognized the music from the title track. Amazon has the CD, but I believe iTunes has it in downloadable form if you want it right away. Great stuff, but oddly, none of Stearns' other music sounds like this.
  • Oƶphoi - Hymns to a Silent Sky - Amazon doesn't have this one at all, but iTunes does. Very strange name, but very nice music.
  • Paul Avgerinos - Sky of Grace - Another album I would put in the "not quite ambient" basket, but beautiful nonetheless.
Enjoy!

Wednesday, March 5, 2008

Where's My DataItem?

One of the most commonly-used patterns when developing with ASP.NET's data-bound controls is the idea of catching the control's RowDataBound or ItemDataBound event and customizing the display of that row/item in some way based on the data in the underlying data item:


protected void grdBallots_RowDataBound ( object sender, GridViewRowEventArgs e )

{

    
if ( e.Row.RowType == DataControlRowType.DataRow )

    {

        
DataRowView rowView = ( DataRowView ) e.Row.DataItem;



        
if ( rowView != null )

        {

            
// ...do customizations here...

        }

    }

}



One of the new server controls that is part of the recent v3.5 release of the .NET Framework is the ListView control. This control combines the templated flexibility of the older Repeater control with the power and ease of use of the GridView control. However, the first time you attempt to use the technique above to customize the way a particular item is displayed, you will notice that the ListViewItem object (obtained in the ItemDataBound event through the ListViewItemEventArgs.Item property) does not contain a reference to the DataItem. So how do you get a reference to the DataItem?

It turns out that an extra object layer has been added to the ListView control's class hierarchy:


protected void lvwFiles_ItemDataBound ( object sender, ListViewItemEventArgs e )

{

    
if ( e.Item.ItemType == ListViewItemType.DataItem )

    {

        
ListViewDataItem dataItem = ( ListViewDataItem) e.Item;

        
DataRowView fileData = ( DataRowView ) dataItem.DataItem;



        
if ( fileData != null )

        {

            
// ... do your customization here...

        }

    }

}



So there you go!