Scott Hanselman

NuGet Package of the Week #4 - Deserializing JSON with Json.NET

April 1, '11 Comments [20] Posted in Javascript | NuGet | NuGetPOW | Open Source
Sponsored By

Hey, have you implemented the NuGet Action Plan? Get on it, it'll take only 5 minutes: NuGet Action Plan - Upgrade to 1.2, Setup Automatic Updates, Get NuGet Package Explorer. NuGet 1.2 is out, so make sure you're set to automatically update!

The Backstory: I was thinking since the NuGet .NET package management siteis starting to fill up that I should start looking for gems (no pun intended) in there. You know, really useful stuff that folks might otherwise not find. I'll look for mostly open source projects, ones I think are really useful. I'll look at how they built their NuGet packages, if there's anything interesting about the way the designed the out of the box experience (and anything they could do to make it better) as well as what the package itself does.

Json.NET is a popular high-performance JSON framework for .NET

If you're moving data around on the web, you'll eventually come upon JSON (JavaScript Object Notation) or as I like to call it, XML with curly braces. (Kidding) (No, I'm not kidding, you can easily convert between XML and JSON in most cases)

It's a lightweight data-interchange format. "It is easy for humans to read and write. It is easy for machines to parse and generate." It's also just JavaScript.

image

From JSON.ORG:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Basically stuff is either a name/value pair, or a list of stuff. That's it. It's great way to push data around, and since it's so flexible and works with JavaScript, it has become THE way to access many popular APIs for sites like Twitter and Facebook.

Json.NET is James Newton-King's excellent library for accessing and working with JSON on .NET. The 4.0 release is cool not only because it's in NuGet, but also because it's currently the best way to deal with JSON data structures on the Windows Phone. Json.NET is notable particularly for James' obsessive focus on performance (check the charts and graphs!) It's also been around FOREVER. I blogged about Json.NET in 2006, in fact.

Inside the Json.NET NuPkg

If you open up the Newtonsoft.Json.4.0.1.nupkg using the NuGet Package Explorer (that's a ClickOnce link, son) I can learn a lot about how James has packaged up his library.

NuGet Package Explorer - Newtonsoft.Json.4.0.1 (15)

First, notice now he's got a number of folders under his /lib folder. I talked about this a little with the last NuGet Package of the Week, but James has taken it to the max. Kudos to him!

With NuGet, you can have one package that includes versions of assemblies for many different Framework Versions. Check the NuGet documentation on Supporting Multiple .NET Framework Versions and Profiles.

James has create a single NuGet package for Json.NET that does the right thing for .NET 2.0, 3.5, 4, SL4, and the Windows Phone 7. Nice.

One thing I think James should add is a Newtonsoft.Json.Sample package per David Ebbo's post "Take NuGet to the next level with sample packages." I found myself wondering where to start with Json.NET as there was no sample code included. No worries, to the cloud web! James has amazing documentation on Json.NET on his site.

Using Json.NET

I've got this silly little site called SmallestDotNet.com that will look at your system using your Browser's UserAgent (and some JavaScript) to determine what version of .NET you have, and suggest the smallest possible download for you to up to date.

NOTE: This SmallestDotNet site was launched in 2008 but was broken on IE9 until my new friend Calinoiu Alexandru Nicolae from Romania (@CalinBalauru on Twitter) volunteered to fix it. Big thanks to Calin for his work on the SmallestDotNet site! Work is ongoing.)

The site also has a simple JSON payload that will give you the correct direct link to the right download for you. I never understood why it was so hard to get a direct download for .NET, so we put it in a basic JSON payload so you could access it programmatically.

The SmallestDotNet JSON payload looks like this. It's not very sophisticated, but it is what it is.

{
"latestVersion": null,
"allVersions": [

],
"downloadableVersions": [
{
"major": 4,
"minor": 0,
"profile": "client",
"servicePack": null,
"url": "http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=5765d7a8-7722-4888-a970-ac39b33fd8ab"
},
{
"major": 4,
"minor": 0,
"profile": "full",
"servicePack": null,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=en"
},
{
"major": 3,
"minor": 5,
"profile": "client",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyId=8CEA6CD1-15BC-4664-B27D-8CEBA808B28B&displaylang=en"
},
{
"major": 3,
"minor": 5,
"profile": "full",
"servicePack": 1,
"url": "http://go.microsoft.com/fwlink/?LinkId=124150"
},
{
"major": 3,
"minor": 0,
"profile": "full",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en"
},
{
"major": 2,
"minor": 0,
"profile": "full",
"servicePack": 2,
"url": "http://www.microsoft.com/downloads/details.aspx?familyid=5B2C0358-915B-4EB5-9B1D-10E506DA9D0F&displaylang=en"
},
{
"major": 1,
"minor": 1,
"profile": "full",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&DisplayLang=en"
}
]
}

Maybe I can access it with Json.NET? I wonder if it'll be easy or hard. There's a number of ways I can do it. This one uses the JObject "DOM" in JSON.NET:

var client = new WebClient();
client.Headers.Add("User-Agent", "Nobody");
var response = client.DownloadString(new Uri("http://www.hanselman.com/smallestdotnet/json.ashx"));
JObject o = JObject.Parse(response);'
//Now o is an object I can walk around...

Or, I can make C# classes that LOOK like the shape of my JSON payload and deserialize directly into them, which is cool:

class Program
{
static void Main(string[] args)
{
var client = new WebClient();
client.Headers.Add("User-Agent", "Nobody"); //my endpoint needs this...
var response = client.DownloadString(new Uri("http://www.hanselman.com/smallestdotnet/json.ashx"));

var j = JsonConvert.DeserializeObject<SmallestDotNetThing>(response);
}

public class SmallestDotNetThing
{
public DotNetVersion latestVersion { get; set; }
public List<DotNetVersion> allVersions { get; set; }
public List<DotNetVersion> downloadableVersions { get; set; }
}

public class DotNetVersion
{
public int major { get; set; }
public int minor { get; set; }
public string profile { get; set; }
public int? servicePack { get; set; }
public string url { get; set; }
}
}

Now, look at the j variable in this screenshot. How cool is that?

The JSON has deserialized into C# objects in a Watch Window

There's lots of choices on how you want to consume your JSON with .NET.

New Json.NET Features

The new Json.NET is compiled on .NET 4, and includes some really cool dynamic support. From James' blog, see how things used to work, and how the new C#4 dynamic keyword makes working with JSON more fun.

JObject oldAndBusted = new JObject();
oldAndBusted["Name"] = "Arnie Admin";
oldAndBusted["Enabled"] = true;
oldAndBusted["Roles"] = new JArray(new[] { "Admin", "User" });

string oldRole = (string) oldAndBusted["Roles"][0];
// Admin


dynamic newHotness = new JObject();
newHotness.Name = "Arnie Admin";
newHotness.Enabled = true;
newHotness.Roles = new JArray(new[] { "Admin", "User" });

string newRole = newHotness.Roles[0];
// Admin

This is really an amazing open source library and I encourage you to check it out if you're doing anything at all with JSON, and maybe throw JamesNK a few coins for his efforts. Thanks, James!

Another Json Library: JsonFx 2.0

If you're really interested in ways to consume JSON using C# dynamics, also check out JsonFx 2.0 on GitHub or JsonFx on NuGet! This library is extremely easy to use with dynamics.

Check out how this simple code:

dynamic foo = new JsonFx.Json.JsonReader().Read(response);

Gets you this result...note that is a C# dynamic typed object:

JSON deserialized into a DYNAMIC

Very nice. Enjoy!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 258 - Inside Entity Framework 4.1 CodeFirst with Jeff Derstadt and Tim Laverty

March 30, '11 Comments [6] Posted in Data | Podcast
Sponsored By

imageThis week Scott sits down with the Lead Dev and Lead PM for Entity Framework 4.1 (Magic Unicorn Edition!) to talk about the improvements from the first version. What's improved and changed? What do they think about NHibernate or just doing SQL on your own?

Also, check out the video interview with Jeff Derstadt on Hanselminutes on 9!

Download: MP3 Full Show

Links:

Plus, you can get Entity Framework from NuGet and use it in your project immediately.

image

NOTE: If you want to download our complete archives as a feed - that's all 258 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes or Subscribe to my Podcast in iTunes or Zune

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX, MVC, Silverlight, Windows Forms and WPF. Enjoy developer tools like .NET Reporting,ORM,Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Enabling dynamic compression (gzip, deflate) for WCF Data Feeds, OData and other custom services in IIS7

March 30, '11 Comments [10] Posted in ASP.NET | IIS | OData
Sponsored By

I'm working on a thing that uses an HttpWebRequest to talk to a backend WCF Data Service and it'd be ideal if the traffic was using HTTP Compression (gzip, deflate, etc).

On the client side, it's easy to just add code like this

request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate

or more manually

var request = HttpWebRequest.Create("http://foofoo");
request.Headers["Accept"] = "application/json";
request.Headers["Accept-Encoding"] = "gzip, deflate";

However, you need to make sure this is installed and turned on in IIS7 in you server.

Launch your IIS Manager and go to the Compression module.

Compression Button in IIS Manager

There's check boxes, but it's not installed you may see this yellow alert on the right side.

Compression Alert in IIS Manager

If it's not installed, go to the Server Manager, Roles, Web Server. Under Role Services, check your installed Roles. If Dynamic Compression isn't installed, click Add Roles and install it.

The Dynamic Compression module in IIS manager is installed

You can go back to compression for your site and ensure Dynamic Compression is checked. At this point, Dynamic Compression should be setup, but you really need to be specific about what mimeTypes will be compressed.

Back in IIS Manager, go to the page for the SERVER, not the SITE. Click on Configuration Editor:

The Configuration Editor in IIS Manager

From the dropdown, select system.webServer/httpCompression:

Selecting the httpCompression node in the Configuration Editor in IIS Manager

Then click on Dynamic Types and now that you're in the list editor, think about what types you want compressed. By default */* is False, but you could just turn that on. I chose to be a little more picky and added application/atom+xml, application/json, and application/atom+xml;charset=utf-8 as seen below. It's a little gotcha that application/atom+xml and application/atom+xml;charset=utf-8 are separate entries. Feel free to add what ever mimeTypes you like in here.

Adding MimeTypes graphically in IIS Manager

After you've added them and closed the dialog, be sure to click Apply and Restart your IIS Service to load the new module.

GUIs suck! Command Lines Rule!

If you find all this clicking and screenshots offensive, then do it all from the command line using AppCmd for IIS7. That's lovely also.

appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']" /commit:apphost
appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/atom%u002bxml',enabled='True']" /commit:apphost
appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/atom%u002bxml;charset=utf-8',enabled='True']" /commit:apphost

Do check your ApplicationHost.config after running this command. See how we had to escape the "+" in "atom+xml" above and made it "atom%u002bxml"? Make sure that + got into your applicationHost.config unescaped. It should look like this in the System.webServer/httpCompression section.





Now, use Fiddler to confirm that compression is turned on by sending a request with the header "Accept-Encoding: gzip, deflate" included. Make sure that Fiddler's "AutoDecode" and Transforms are turned off if you really want to be sure you're looking at the raw stuff.

Confirming in Fiddler that gzip compression is turned on

Turning on Compression is a VERY low effort and VERY high reward thing to do on your servers, presuming they aren't already totally CPU-bound. If you're doing anything with phones or services over low-bandwidth 3G or EDGE networks, it's a total no brainer. Make sure you know what's compressed on your systems and what's not, and if not, why not.

Be explicit and know what your system/sites HTTP Headers are doing. Compression is step 0 in service optimization. I think I mentioned this in 2004. :)

Enjoy!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Modifying the default code generation/scaffolding templates in ASP.NET MVC

March 28, '11 Comments [13] Posted in ASP.NET | ASP.NET MVC
Sponsored By
image

One of the things people like the most about my ASP.NE MVC 2 Ninja Black Belt Tips video, besides the Bill Cosby sweater, is the tip where I show how to modify the default CodeTemplates that are used in Code Generation in ASP.NET MVC (either version).

Eilon mentioned it on an internal mailing list this week so I thought it'd be worth surfacing again in case you haven't heard of this, Dear Reader.

Soon, we'll see even more powerful, flexible, and fun ways to customize your own Scaffolding in ASP.NET MVC 3, so keep an eye out, 'cause it's coming.

Bring the CodeTemplates local to your project

imageWhen you use the Visual Studio "tooling" (that means dialogs and stuff) to Add View or Add Controller, you're actually executing a T4 template and generating a little bit of code. Where does this start and how can you change it?

Try this. Create a new ASP.NET MVC project.

Now, go to:

C:\Program Files (or x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp (or Visual Basic)\Web\MVC (or 2) 3\CodeTemplates

See all those folders? Turns out everything under CodeTemplates are T4 templates that can be either modified in place or even better, can be brought local to your project. Local CodeTemplates will override the global ones.

Copy that folder (or just subfolders like AddController, or AddView) to your ASP.NET project. I do this by dragging from Explorer directly into the Visual Studio Solution Explorer as seen  here:

image

You might get some errors when you drop the folder. Ignore them and instead, select the Templates using Ctrl-Click, then right click and select Properties. (You can delete any templates you won't be using.)

image

Now, see where it says Custom Tool? Clear that string out completely. You're tell Visual Studio that you don't want these T4 Templates to be run during a build. They will only be called manually by the Tooling dialogs like Add View and Add Controller.

You change these templates, or in the case of Add View you can make your own. For example here I've made a new "My Awesome List.tt" as a copy of List.tt and it shows up in the Add View dialog.

image

Now I can not only totally customize what gets generated from the Add Controller and Add View dialogs, I can add custom templates to the drop down. Most importantly, these changes live in the CodeTemplates folder of my project and are carried along with my project in Source Control so others on my team or company can use them as well.

Have you customized yours? Enjoy.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Good Exception Management Rules of Thumb - Back to Basics Edition

March 23, '11 Comments [58] Posted in Back to Basics | Learning .NET
Sponsored By

Almost five years ago I posted this "Good Exception Management Rules of Thumb" and had some interesting and useful comments. As with all lists of rules of thumbs, they may no longer be valid. What do you think?

Cori Drew commented to me in an email that she often sees code like this in the wild (changed to protect the innocent 3rd parties). This kind of code inevitably shows up in a file called Utils.cs, which may be your first clue there's trouble.

public void HandleException(String strMessage)
{
//Log to trace file only if app settings are true
if (Properties.Settings.Default.TraceLogging == true)
{
try
{
TraceSource objTrace = new TraceSource("YadaYadaTraceSource");
objTrace.TraceEvent(TraceEventType.Information, 5, strMessage.ToUpper());
objTrace.Flush();
objTrace.Close();
}
catch
{
//do nothing if there was an error
}
}
throw new Exception(Environment.NewLine + strMessage);
}

What's wrong with this code, Dear Reader?

There's a number of things that we can learn from, so have at it in the comments in nice lists bulleted with asterisk, won't you? You can comment on lines, or the larger strategy or both. I'll update the post with a roll-up once you come up for breath.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.