Johnny Code

Fear no code

Why I bought a Crucial M4 SSD

By John Bubriski on May 2, 2012

(Disclaimer: This is not a completely scientific analysis. My conclusions are based solely on the user reviews on various retail sites. Do not blame me if you Crucial M4 dies. Yes, that is still a possibility just as it is with any SSD, Hard Drive, or any other piece of hardware.)

So far I’ve owned an 80 GB Intel X25-M and I currently own an 115 GB OCZ Vertex 2. Both drives treated me well, but I was looking for more. More space, that is.

Intel X25-M SATA Solid State Drive (SSD)

OCZ Vertex 2

Why do I need an SSD?

I wont go into the nitty-gritty detail, but here’s my take:

My sole machine is a laptop, so I don’t have the luxury of multiple drives and virtually unlimited RAM. I’m limited to one storage drive, and 8 GB of RAM. You may be lucky and have a laptop that has an extra drive bay instead of a CD drive, or one that supports more RAM, but that’s not me, and that’s definitely not everyone. Take a look at the excerpt from the Steam Hardware & Software Survey below (from March 2012). It’s specific to gamers, but even gamers don’t have the best machines! In my situation, I don’t feel that 8 GB is enough, and an SSD can help relieve the pain.

Steam Hardware & Software Survey - RAM stats

Another bonus for laptop users is durability. Apparently these drives can withstand up to 1500 G’s worth of shock. I’m not sure if that is specific to the memory in the drive, or the electronics as well. Either way, the lack of moving parts should make SSD’s significantly more reliable than a spinning disks in the event of a bump, drop, or mischievous 2-year-old. Baby Smash anyone?

What about desktop users who can jam 24 GB of RAM into their machine? Good for you!!! You probably don’t need an SSD with all that RAM. Once you’re machine is up and running and everything is loaded into RAM, you should be good to go. But what about that first load? An SSD would probably help with that, but the cost/benefit ratio is probably not as good.

But don’t take my word (opinion) for it, take a look at the articles below. Note that they’re not super recent, but most of the reasoning for buying an SSD should still be relevant:

Coding Horror (Jeff Atwood):

  • The State of Solid State Hard Drives
  • Revisiting Solid State Hard Drives
  • The Hot/Crazy Solid State Drive Scale

Hanselminutes (Scott Hanselman):

  • Your New Year’s Resolution – Put an end to spinning rust and buy yourself a SSD
  • Upgrading my Lenovo W500 to a OCZ Vertex 250GB SATA II Solid State Disk (SSD)

More:

  • Joel Spolsky – Solid State Disks
  • Anandtech Forums – Why buy/use an SSD?

So why a Crucial M4 and not a [Insert Model] [Insert Brand]?

There are many other SSD manufacturer’s out there. Some of the most well-known include:

  • OCZ
  • Intel
  • Samsung
  • Kingston
  • Corsair

Here are the factors that landed the Crucial M4 in my shopping cart, and subsequently, my laptop:

  • Reliability
  • Reliability
  • Reliability

The perceived reliability of the Crucial M4 blows away any other brand/series on the market today, at least from my perspective. Here are the customer rating stats from my 2 favorite online stores:

Amazon – 4.5/5 average rating from 448 reviews
NewEgg – 5/5 average rating from 145 reviews.

None of the other drives on the market today come close to having the same number of reviews and average rating. Here are some similar 256 Gb drives I looked at:

(Reviews are from Newegg.com at the time of writing. Note that some drives are listed multiple times, probably for different firmware revisions. I only grabbed the ones that had at least 14 reviews.)
Name/Average Rating/Votes

  • 5/5, 71 reviews, Samsung 830 Series
  • 5/5, 45 reviews, Corsair Force Series GT
  • 5/5, 31 reviews, Samsung 830 Series
  • 5/5, 30 reviews, Plextor M3 Series
  • 5/5, 20 reviews, Corsair Performance Pro Series
  • 5/5, 15 reviews, Kingston HyperX
  • 4/5, 115 reviews, OCZ Agility 3
  • 4/5, 54 reviews, Mushkin Enhanced Chronos
  • 4/5, 47 reviews, Mushkin Enhanced Chronos Deluxe
  • 4/5, 42 reviews, Intel 510 Series Elm Crest
  • 4/5, 39 Reviews, OCZ RevoDrive 3 X2 Series
  • 4/5, 38 reviews, Mushkin Enhanced Callisto Deluxe
  • 4/5, 27 reviews, OCZ Vertex 3
  • 4/5, 21 reviews, Kingston HyperX
  • 4/5, 19 reviews, Intel 520 Series Cherryville
  • 3/5, 92 reviews, OCZ Vertex 3
  • 3/5, 32 reviews, Corsair Force Series 3
  • 3/5, 23 reviews, Patriot Wildfire
  • 3/5, 23 reviews, OCZ RevoDrive 3 Series
  • 3/5, 14 reviews, OCZ Vertex 2

What about performance?

According to online benchmarks the Crucial M4 isn’t the fastest kid on the block, but it’s fast enough. It’s much faster than any other spinning disk drive out there, and if you compare it to other SSD’s the difference probably wont be noticeable in real-world scenarios. Check out the reviews if you want to see an in-depth anlysis:

  • AnandTech Review
  • Toms Hardware Review

What about price?

Money is money, but time is money too!

- me

How much is your time worth? Sure, you can save as much as $100, but the cost of owning an SSD isn’t limited to it’s purchase price. Below I’ve listed some factors that can increase the cost of ownership of your SSD. YMMV (Your mileage may vary), but if your drive dies, any or all of them can come into play:

Shipping time

Best case you’re probably looking at 2 day shipping both ways. That’s 4 days that you’re working with your old slow hard drive, or someone else’s old busted computer. Or worse yet, you’re not working at all. Not to mention the…

Shipping costs

It depends on what brand you buy, where you buy it, and when the drive dies, but those are 3 different factors that can result in shipping charges.

Customer support headaches (figuratively and literally)

I wont name names, but take a look at some of the reviews for other SSD’s. A lot of customers complain about drives dying, but some are more frustrated by poor customer service. Stress is a killer.

(Re-)Setup time

It takes time to install your OS, apps, and games, and then restore your data and configuration. Each one of these things can be quick on their own. Windows 7 has a snappy install process, I mostly use free apps, all my games are on Steam, and my data is mostly in the cloud (along with various config files). So what’s the big deal? If you have a good cloud backup strategy you’re probably fine. But what if you don’t? Hunting for your OS and game disks, downloading apps, and rummaging through external hard drives isn’t my idea of fun. God forbid you don’t have a good backup strategy which results in…

Lost data

Even if you saved/pushed your documents and code an hour ago, that’s still an hour’s worth of work that’s now gone. Worst case is that you didn’t push it today, or this week. If you don’t backup at all you may as well throw your computer out the window and save yourself from all the waiting.

Multiple failures

OK, so you RMA’d your broken drive for another… unreliable drive! Sweet! Now you get to go back to the top of the list and re-read this entire section!

So the Crucial M4′s are perfect?

I can’t tell you that your drive wont fail. I just bought my Crucial M4, so only time will tell how mine fairs. But as I said in my disclaimer at the top of this post, nothing is immune to failure, SSD’s included. However, I firmly believe the benefits outweigh the risks. If you do choose to go with a historically less reliable series/brand you’re taking your time and money into your own hands.

Other Links

  • Anandtech – My defacto standard for SSD information, guides, and reviews.
  • Anandtech Forum Post on all things SSD – A great post that can probably answer 99% of the questions you have about SSD’s.

Posted in Hardware | Tagged Computers, Crucial M4, Hard Drives, Laptops, Programming, SSD | Leave a response

Product Review of AutoCode: Visual Studio Code Snippets on Steroids

By John Bubriski on May 2, 2012

Disclaimer: I did pay $19.95 for this product, but I may receive a complimentary license in return for writing this review (Scroll to the end of the article for more info).

Background

Code snippets in Visual Studio are great. I Code Snippets all the time! My favorite is probably one of the simpler ones: prop. prop will generate the code for an auto-implemented property, and allow you to easily replace the type and property name. The initial generated code looks like this:

public int MyProperty { get; set; }

which you (easily) modify to this:

public string FirstName { get; set; }

(If you don’t know what I’m talking about go try it out now! RIGHT NOW! In Visual Studio, in a class block type: “prop <Tab> <Tab>”)

Yeah… they’re great. I’ve even made a bunch of custom Code Snippets. Generally I have ones for:

  • Inserting tasks comments like “// TODO: “.
  • A jQuery protection function.
  • SqlConnection and SqlCommand boilerplate using statements and setup.
  • Dapper boilerplate code.
  • Prototyping and stubbing out methods.
  • Other common ASP.NET markup tags.

(I want to throw my generic code snippets in a Github repo, but I haven’t gotten around to it yet. I do have my Dapper snippets on Github.)

But what if you want to do more fancy things? One thing I’ve always dreamed of having was a code snippet that would take a type name and generate this:

var myClass = new MyClass();

I cringe everytime I write that code because I shouldn’t have to. I tried every which way to support this in a code snippet, but they are simply not powerful enough. This is where AutoCode from DevProjects.net comes into play.

How does AutoCode work?

AutoCode is Visual Studio Code Snippets on Steroids

- me

Like regular code snippets, AutoCode snippets allow for templates and replacements, but they also allow code to be run. Much like a T4 template, they take a template, combine it with some potential input, and generate code from it. T4 templates are usually added directly to a project or triggered by Visual Studio for the creation of files. ASP.NET MVC makes extensive use of T4 Templates. AutoCode brings the power of T4 to your fingertips. When you press Ctrl+Enter it brings up an intellisense-like dialog:

AutoCode Intellisense Dialog

AutoCode Intellisense Dialog

From there, the dialog will guide you with the available snippet shortcuts and their usage. The built in snippets cover most general needs like:

Let’s kick it up a notch!

But why limit yourself to individual properties and methods? The “classa” shortcut will create an entire class from a single command:

int userId string firstName string lastName person classa

results in…

public class Person
{
    public Person()
    {
    }

    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And for those with a careful eye, you did notice my “incorrect” casing in the command, right? The command contained (lower) Camel Cased names, but AutoCode is smart enough to translate it into Pascal Casing!

But wait, there’s more!

AutoCode doesn’t stop at templates and replacements. It also contains additional commands for things like:

  • Method Refactoring
  • Clipboard Assistance
  • Code Evaluation
  • Creation of custom AutoCode snippets
  • Commenting/Uncommenting
  • Closing documents

Some of these, like method refactoring commands, simply execute IDE commands, but if you’re not familiar with the Visual Studio shortcuts, this can still be helpful.

Editions

AutoCode comes in 2 versions, Standard and Professional, and this is where we come to my 2 criticisms. The first problem is that the Standard Edition is free but it’s practically unsuable. Every time a command is executed a little “nagger” popup will appear. This really hampers a dev’s ability to gain any benefit from the Standard Edition, and more importantly, evaluate the product for purchase of the Professional Edition. Which brings me to my next criticism…

The “trial” version is annoying but I decided to take my chances and purchase the Professional Edition immediately. But instead of purchasing it for $19.95, I was required to donate $19.95 to get my activation code. I guess this is sort of splitting hairs, but it feels weird that someone accepting donations is forcing me to donate a certain amount of money. Why not simply put a normal price tag on it? I’m not sure if this was done to appear humble, for fee/tax reasons, or for some other reason. Again, I’m probably splitting hairs.

Conclusions

Buy it. It’s only $19.95.

Posted in Programming | Tagged .NET Framework, C#, Code, Code Snippets, Productivity, Visual Studio | Leave a response

My Cloud Backup Strategy

By John Bubriski on April 25, 2012

Not going to go into why you should backup, but here is how I handle the things that matter to me: Code, Documents, PC Games, and Photo and Video.

Code

This one is pretty much a no-brainer for me. Use Bitbucket to host your private repositories for free, and use GitHub to host your public ones.

Documents and other miscellaneous files

Some prefer Microsoft, Google, or another company. Take your pick (numbers from time of writing):

  • Microsoft SkyDrive – 7 Gb free
  • Google Drive – 5 Gb free
  • Dropbox – 2 GB free (plus referral bonuses)

PC Games

Just use Steam.

Photo and Video

I have a Flickr Pro Account. For $25/year you get:

  • Unlimited uploads and storage
  • Unlimited sets and collections
  • Access to your original files
  • Stats on your account
  • Ad-free browsing and sharing
  • HD video uploads & playback

Their upload download procedures aren’t super smooth, but I mostly do uploads and the Flickr Uploadr makes that pretty easy. I tried out Google’s Picasa a while back, but with my massive collection of family photos it was getting very expensive very fast.

I also have a Synology DS211J NAS that I use to store all my photos and videos in house. If you edit/view/print your photos a lot, having this local network copy/cache will help out a lot.

Bonus: I have 2 projects on Github relating to photo management.

“Organize My Photos” aims to organize all of your local photos into folders by date. It’s a really basic/ugly implementation in Winforms, but it works for my purposes.

“Organize My Flickr Photos” aims to keep your photos “backed up” to Flickr, avoiding duplication. I don’t think this code is fully functional right now. Last I checked I was fighting with the limitations of the Flickr API. Once over those hurdles it shouldn’t be too much work to get some nice sync action going on.

Posted in Programming, Technology | Tagged Backups, Cloud, NAS, Photography | Leave a response

Serializing Circular References with JSON.Net and Entity Framework

By John Bubriski on April 10, 2012

The Setup

You’re building a RESTful web service, and your technology stack looks something like this:

  • ASP.NET MVC 4 w/ Web API
  • Entity Framework Code First (I’m on 4.3.1, available via Nuget)
  • Newtonsoft JSON.Net (I’m on 4.5.1, available via Nuget)

We’ll pull the data out of the database using EF and setup the ASP.NET Web API to use the JSON.Net library to handle serialization/deserialization. To make your life easier you could use ST4bby to do the heavy lifting and generate your POCO’s.

Piece of cake, right?

A circular reference was detected while serializing an object of type ...

False.

The Problem

Circular reference exception??? Oh dear God, haven’t we figured this out yet???

Let’s start from the beginning.

You’ve setup JSON.Net as your default formatter, right? In case you haven’t done that grab the JsonNetFormatter from Henrik’s blog and enable it in the Application_Start method in the Global.asax:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonNetFormatter(new JsonSerializerSettings()));

That’s right, we blew away all the formatters, including the XML one and we’re not looking back.

Now let’s look at a simple example of serialization of relational collections, without EF. Below is a simple class which can hold references to other instances of the same class:

public class Bro
{
    public int BroId { get; set; }
    public string Name { get; set; }

    public List<Bro> Bros { get; set; }

    public Bro()
    {
        Bros = new List<Bro>();
    }
}

Not rocket science. A Bro can have many Bros, right? A more common example would involve Parent/Child relationships, but this is simpler and demonstrates the same issue. Now let’s expose our Bros to the world via an ASP.NET Web API Controller:

public class BrosController : ApiController
{
    public IEnumerable<Bro> Get()
    {
        var john = new Bro { Name = "John" };
        var jared = new Bro { Name = "Jared" };

        john.Bros.Add(jared);
        jared.Bros.Add(john);

        return new List<Bro> { john, jared };
    }
}

Again, not rocket science. If you’re unfamiliar with ASP.NET Web API, this is just like an ASP.NET MVC controller, except that it will handle all of the HTTP/REST stuff for you. The JSON.Net formatter will kick in and serialize our collection of Bros to JSON. Right? Almost.

If you’ve corretly setup our custom JsonNetFormatter, you’re going to get an exception about a circular reference:

Self referencing loop detected for type 'EntityFrameworkCodeFirstWithJsonSerialization.Bro'.

If you didn’t setup the JsonNetFormatter, I think that your page is gonna spin until the call stack fills up and you get a StackOverflowExpception.

So what gives? Isn’t it the year 2012? Shouldn’t we have figured out a way to serialize this data? Yes we should have, and yes we have.

The Solution

After a lot of searching, I finally found this page in the docs:

http://james.newtonking.com/projects/json/help/ under Serializing and Deserializing JSON -> Serialization and Preserving Object References (or Direct link with no navigation)

Which explains to set this setting:

PreserveReferencesHandling = PreserveReferencesHandling.Objects

… in order to… you guessed it, preserve references! JSON.Net is smart enough to detect the circular references, but since the default functionality is to serialize by value, it gives up so you don’t get StackOverflowExceptions!

So now your Application_Start method in the global.asax looks more like this:

var jsonSerializerSettings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
};

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonNetFormatter(jsonSerializerSettings));

And your Web API Controller works, spitting out JSON like this:

[
    {
        "$id": "1",
        "BroId": 0,
        "Name": "John",
        "Bros": [
            {
                "$id": "2",
                "BroId": 0,
                "Name": "Jared",
                "Bros": [
                    {
                        "$ref": "1"
                    }
                ]
            }
        ]
    },
    {
        "$ref": "2"
    }
]

Isn’t that awesome! To be honest, I never knew JSON was so smart! In case you don’t understand what’s happening, JSON.Net is taking the extra step to setup each reference with an additional meta-property called “$id”. When JSON.Net encounters the same instance in another place in the object graph, it simply drops a reference to the original instance, instead of duplicating the data, and causing circular reference issues!

What about Entity Framework

You said you were going to help me with my Entity Framework Code First problem!

Funny story: regular EF doesn’t have a problem with this! In fact, it handles it beautifully! All your references to parent and child objects are preserved and your JSON will look like what we saw above!

To “Fix” Code First we need to understand what it is abstracting away for us, and do a little bit more work (nothing you can’t handle dear reader!). If you already tried the above setting on your project you’ll notice that you now get a different Exception that looks something like this:

The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.

OK, so we traded one issue for another… or did we?

If we step back for a minute, we’ll remember that when we read Julia Lerman’s book on Programming Entity Framework: Code First it said that Code First generates proxy classes for us, even though we have our POCO’s (actually I don’t think she references the proxy objects in that book, but you should buy it anyway because she’s awesome and that’s a referral link)! So JSON.Net sees these weird proxy classes instead of our actual POCO’s. When it tries to serialize those proxy classes, all Hell breaks lose because the proxy classes are dynamic proxy classes, as in the dynamic keyword.

So what’s a Dev to do? Disable Proxy Generation!

using(var yourDbContext = new YourDbContext())
{
    yourDbContext.Configuration.ProxyCreationEnabled = false;

    return ...
}

Now our EF Code First setup works!

But what did I just enable/disable/break?

When proxy object creation is enabled for POCO entities, changes that are made to the graph and the property values of objects are tracked automatically by the Entity Framework as they occur. For information about change tracking options with and without proxies, see Tracking Changes in POCO Entities.

Therefore, when proxy object creation is disabled, changes are not tracked automatically. If you can live with that, then you’re all set!

Posted in Programming | Tagged .NET Framework, ASP.NET, ASP.NET MVC, ASP.NET Web API, Circular References, Entity Framework, JSON, JSON.Net, REST, Serialization | 2 Responses

How to Scrape Amazon Wishlists in 1 Line of C#

By John Bubriski on March 19, 2012

So I started a new open source project called Shing. It’s goal is simple: Scrape an Amazon Wishlist, get all the Product ID’s and generate the Amazon short links to the products.

I was showing the code to my colleagues when Joey, a friend and former coworker, offered some suggestions to improve the code.  This is the original working prototype, thrown together in about 5 minutes:

Note: the code below isn’t quite complete. It’s just a simple Regex that finds product links on the wishlist page. There can be other product links on the wishlist page like related products. Just a heads up.

string _regex = "/dp/(.*?)/";

/// <summary>
/// Returns a list of product ID's
/// </summary>
/// <returns></returns>
public List<string> Scrape(string urlToScrape)
{
    var webClient = new WebClient();

    var content = webClient.DownloadString(urlToScrape);

    var matches = Regex.Matches(content, _regex);

    var productIds = new List<string>();

    foreach (Match match in matches)
    {
        productIds.Add(match.Groups[1].Value);
    }

    return productIds;
}

And here was his suggested version:

private const string WishListRegex = "/dp/(.*?)/";

/// <summary>
/// Returns a list of product ID's
/// </summary>
/// <returns></returns>
public IEnumerable<string> Scrape(string urlToScrape)
{
    var content = new WebClient().DownloadString(urlToScrape);

    var matches = Regex.Matches(content, WishListRegex);

    foreach (Match match in matches)
    {
        yield return match.Groups[1].Value;
    }
}

His code returns the exact same results but a few minor differences make it worthwhile.

  • The regex is a constant – This should make the code a little more efficient by not creating a string every time the Scrape() method is called.
  • Scrape() returns an IEnumerable<string> – This allows for the next one which is…
  • Scrape() incorporates the yield keyword – This should make the code much more efficient in certain scenarios. Instead of creating a List in memory and then returning the entire thing at the end, the method will simply return results as you ask for them. This should reduce memory consumption and speed things up as well, again, if used correctly.

But why stop there? Just make it a one-liner

return Regex.Matches(new WebClient().DownloadString(urlToScrape), "/dp/(.*?)/").Cast<Match>().ToList().Select(m => m.Groups[1].Value);

This is purely for fun. I would never do this except as a joke.

The code should produce the same results, except that the regex isn’t a constant, and yield isn’t incorporated. Fun though.

Posted in Programming | Tagged .NET Framework, Amazon, C#, Code, Open Source, Regex, WebClient, Wishlist | 2 Responses

Getting a List of Alternative Forms

By John Bubriski on February 28, 2012

I forget why I needed to do this, but I was doing some heavy development around Kentico‘s BizForm‘s at the time and needed to pull back a list of alternative forms for a given BizForm. It’s not very complex, but it might not be obvious if you’re not familiar with Kentico’s database structure and their use of classes.

Anyway, here is the code:

SELECT ca.FormID, ca.FormDisplayName
FROM CMS_Class cc
JOIN CMS_AlternativeForm ca ON ca.FormClassID = cc.ClassID
WHERE cc.ClassName = 'BizForm.ContactUs'

Let me know if this helped you!

Posted in Kentico, Programming | Tagged Kentico Alternative Forms, Kentico BizForms, SQL | Leave a response

Logging Events with Kentico

By John Bubriski on February 27, 2012

Developing a custom web part or module and want to log some events into the Kentico Event Log? Here is some sample code to get you started.

Logging Exceptions:

var eventLogProvider = new EventLogProvider();
eventLogProvider.LogEvent("E", eventName, ex);

Logging Custom Events:

var eventLogProvider = new EventLogProvider();
eventLogProvider.LogEvent("E", DateTime.Now, "source", "code");

FYI, I believe that the EventLogProvider has some static methods on it to log events, but I thing they are the more verbose versions of the methods above. Happy logging!

Posted in Kentico, Programming | Tagged .NET Framework, ASP.NET, C#, Code, Kentico API Programming, Kentico CMS, Kentico Event Log, Kentico Module Development | Leave a response

Using HttpClient to Consume ASP.NET Web API REST Services

By John Bubriski on February 23, 2012

So you installed the ASP.NET MVC 4 Beta and followed the Web API introduction over at the ASP.NET website. Great! You now have a nice HTTP based API that plays nicely with jQuery and other client side JavaScript libraries, and even other server-side technologies. But how exactly do we perform server side consumption of that API in .NET?

**UPDATE**

I updated the post and the examples with the full code for making GET’s, POST’s, PUT’s, and DELETE’s. I didn’t have much time, so let me know if there are any mistakes/issues.

Let’s say that you want to build an uber-flexible n-tier architecture for your next great app. One option for decoupling your layers is to build them as web services. That way you not only decouple the code relationships, but you decouple the platforms as well.

For example, if you build your BLL (Business Logic Layer) as a web service any platform can interact with it. Your presentation layer can be a MVC site, a WPF app, a mobile app, or anything else you can think up. The only requirement is that the front end be able to reach the web service and correctly talk to it.

Where’s the meta data???

How are we going to generate the proxy classes for this new web service??? I’m not going to lie and say that your old friend the “Add Service Reference…” dialog is going to be able to help you out here. Because this is a simple HTTP based API, no meta data gets generated about the API itself (at least as far as I know, and at the time of writing this post).

While I love the “automagical” nature of the “Add Service Reference…” dialog, it always scared me a little bit. It hid a lot of code and required an active instance of the web service to be up and running somewhere (locally was fine). Now, we have complete control over the serialization and deserialization of the data and can write more testable code (more on that later).

Show me the frickin’ code!

Attached is a working sample solution that demonstrates my examples below.

First, create a new ASP.NET MVC 4 project and select the Web API template. I called mine “WebApi”:

After the solution loads let’s make sure that our web service is in an accesible location. Open up the project Properties > Web and then set the Specific Page to be “Values” and the Specific Port to be 9000. We’ll reference that port in our test consumer in a minute:

You can test out the default API by just hitting F5. The local web service URL (http://localhost:9000/api/values) should open in your default browser and you should see some XML (The styling may be different in your browser):

<?xml version="1.0" encoding="utf-8"?>
<string>value 1</string>
<string>value 2</string>

(Note: If you want to see the JSON, you can send an HTTP “Accept Header”. The Web API will see this and spit back your data serialized to JSON. Make sure you use this header when making requests from jQuery. Check out the ASP.NET Web API Introduction for an example, or use Fiddler.)

When you ran your project, a route defined in the Global.asax sent your request to the ValuesController in the Controllers folder. In the ValuesController, the request matched the first action via the HTTP request method verb and the parameters. To see this in action try going to http://localhost:9000/api/values/5. Additionally, requests can be mapped by name too.

So far so good. Let’s spice up the API a little bit and return our own custom type. Create a new class library project within your solution. I called mine “WebApi.Dal”. Rename the deafult “class1.cs” to “MyDataClass.cs” and let Visual Studio auto update the references. Now add some properties. Mine ended up like this:

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

namespace WebApi.Dal
{
    public class MyDataClass
    {
        public string MyProperty1 { get; set; }
        public bool MyProperty2 { get; set; }
        public int MyProperty3 { get; set; }
        public decimal MyProperty4 { get; set; }
    }
}

Now let’s switch back to the Web API project. Add a reference to your DAL project and replace the first controller action with this one:

// ... usings, namespace and class/controller declarations.

// GET /api/values
public MyDataClass Get()
{
    return new MyDataClass
    {
        MyProperty1 = "Property 1", // String
        MyProperty2 = true, // Bool
        MyProperty3 = 987654, // Integer
        MyProperty4 = 100.87m // Decimal
    };
}

// Rest of the class/controller definition...

Now run the solution again and you should see this:

<?xml version="1.0" encoding="utf-8"?>
<MyDataClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <MyProperty1>Property 1</MyProperty1>
    <MyProperty2>true</MyProperty2>
    <MyProperty3>987654</MyProperty3>
    <MyProperty4>100.87</MyProperty4>
</MyDataClass>

Great! Piece of cake!  Now back to the problem at hand.

Consuming the Web API Service

Back in Visual Studio create a Console Application project. I called mine “WebApi.Tester”. Add a reference to the WebApi.Dal project, but you don’t need to add one to the WebApi project. Having access to the classes that were used to serialize the Web API data will allow us to deserialize the data easily, and we don’t need any “direct” relation to the web service itself, just the data it provides.

In the Nuget Package Manager search for System.Net.Http and install the package that matches that name (a bunch of other results show up, but get the one from Microsoft) and the one that matches the name with “Formatter” on the end.

Then search for “json” and add the Json.NET package from Newtonsoft.

Then Add a Reference to System.Net.Http.Formatting and System.Json.

Now you should now have references to:

  • Newtonsoft.Json
  • System.Json
  • System.Net.Http
  • System.Net.Http.Formatting
  • System.Net.Http.WebRequest
  • WebApi.Dal

When we go to test this setup, we want both the WebApi MVC project to run, as well as the WebApi.Tester Console app.  To do that, open up the Solution Properties, check the radio button that says “Multiple startup projects”, and set WebApi and WebApi.Tester as startup projects:

Now we are ready to write some code.  Here is a base client class I whipped up that provides a generic interface to the Web API service:

public class BaseClient
{
    protected readonly string _endpoint;

    public BaseClient(string endpoint)
    {
        _endpoint = endpoint;
    }

    public T Get()
    {
        using (var httpClient = new HttpClient())
        {
            T result = default(T);
            Task responseTask = null;

            httpClient.GetAsync(_endpoint).ContinueWith((requestTask) =>
            {
                responseTask = requestTask;
                HttpResponseMessage response = requestTask.Result;

                response.EnsureSuccessStatusCode();

                response.Content.ReadAsAsync().ContinueWith((readTask) =>
                {
                    result = readTask.Result;
                });
            });

            // HACK: My version of the await keyword
            while (responseTask == null || !responseTask.IsCompleted || result == null) { }

            return result;
        }
    }
}

(Important: As of this writing, the above code may fail. Keep reading for a solution.)

So about that code above… it doesn’t always work…  It appears that there is some issue with the deserializer and I get the following exception when reading the result from the inner async method:

“The input stream contains too many delimiter characters which may be a sign that the incoming data may be malicious.”

Basically, there is some sort of “security” measure in place in case the data is too big and there are too many delimiters.

Not to worry, I got your back!  Just substitute that inner async call with this one, which delegates the deserialization to the Newtonsoft JSON library!

response.Content.ReadAsStringAsync().ContinueWith((readTask) =>
{
    result = JsonConvert.DeserializeObject(readTask.Result);
});

I asked about the above issue on the official ASP.NET forums and I got a response on this thread. It looks like you just need to set the SkipStreamLimitChecks static property to true on the MediaTypeFormatter class. As of this writing, I haven’t tested that solution but I left the commented samples intact in case you want to give it a go.

But let’s be honest with eachother.  You think that code is ugly.  It is ugly, it’s not just you.  So I started another thread about how to reign that code in and clean it up.  I got a great response from a guy in this thread.  Since the async code is so ugly in .NET 4, and in my case it wasn’t really needed, I left it out.  So the first return is the one that executes in the example and it’s still using Newtonsoft JSON:

public T Get()
{
    using (var httpClient = new HttpClient())
    {
        var response = httpClient.GetAsync(_endpoint).Result;

        // This works:
        return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);

        // This may not work:
        return response.Content.ReadAsAsync().Result;

        // This may not work:
        return response.Content.ReadAsOrDefaultAsync().Result;
    }
}

So now my code is a lot shorter, cleaner and easier to grok. For now we’re basically skipping the async stuff, but I think that’s a smart decision until we can leverage the await keyword and all it’s compiler magic.  For a quick sample of how the await keyword in .NET 4.5 relates to the Web API, check out this post by the architect behind all this stuff, Henrik F Nielsen.

Sample Solution

I threw together a simple sample solution that is a complete working example. Nuget package restore is enabled and I removed all the packages to make the zip file as small as possible.  The first build of the solution will take a minute because it has to go fetch all the packages and their dependencies. Let me know if you have any problems running the code.

Web API with HttpClient Sample Solution

In case you don’t feel like downloading the zip, the full relevant code from the solution is below:

using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class BaseClient
{
    protected readonly string _endpoint;

    public BaseClient(string endpoint)
    {
        _endpoint = endpoint;
    }

    public T Get<T>(int top = 0, int skip = 0)
    {
        using (var httpClient = new HttpClient())
        {
            var endpoint = _endpoint + "?";
            var parameters = new List<string>();

            if (top > 0)
                parameters.Add(string.Concat("$top=", top));

            if (skip > 0)
                parameters.Add(string.Concat("$skip=", skip));

            endpoint += string.Join("&", parameters);

            var response = httpClient.GetAsync(endpoint).Result;

            return JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result);
        }
    }

    public T Get<T>(int id)
    {
        using (var httpClient = NewHttpClient())
        {
            var response = httpClient.GetAsync(_endpoint + id).Result;

            return JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result);
        }
    }

    public string Post<T>(T data)
    {
        using (var httpClient = NewHttpClient())
        {
            var requestMessage = GetHttpRequestMessage<T>(data);

            var result = httpClient.PostAsync(_endpoint, requestMessage.Content).Result;

            return result.Content.ToString();
        }
    }

    public string Put<T>(int id, T data)
    {
        using (var httpClient = NewHttpClient())
        {
            var requestMessage = GetHttpRequestMessage<T>(data);

            var result = httpClient.PutAsync(_endpoint + id, requestMessage.Content).Result;

            return result.Content.ReadAsStringAsync().Result;
        }
    }

    public string Delete(int id)
    {
        using (var httpClient = NewHttpClient())
        {
            var result = httpClient.DeleteAsync(_endpoint + id).Result;

            return result.Content.ToString();
        }
    }

    protected HttpRequestMessage GetHttpRequestMessage<T>(T data)
    {
        var mediaType = new MediaTypeHeaderValue("application/json");
        var jsonSerializerSettings = new JsonSerializerSettings();
        jsonSerializerSettings.Converters.Add(new IsoDateTimeConverter());

        var jsonFormatter = new JsonNetFormatter(jsonSerializerSettings);

        var requestMessage = new HttpRequestMessage<T>(data, mediaType, new MediaTypeFormatter[] { jsonFormatter });

        return requestMessage;
    }

    protected HttpClient NewHttpClient()
    {
        return new HttpClient();
    }
}

Resources

  • Web API Section on ASP.NET
  • Henrik F Nielsen’s Blog
  • ASP.NET Web API Forums

 

Posted in Programming | Tagged .NET Framework, ASP.NET, ASP.NET MVC, ASP.NET Web API, C#, Code, HTTP, HttpClient, jQuery, JSON, REST, WCF, Web Services, XML | 17 Responses

Get BizForm Record ID

By John Bubriski on February 22, 2012

Here is a post I wanted to write a few months ago while I was actively developing Kentico based websites, but I never got the chance to finish it. The code should be solid, and I’ll explain it as best I can.

If you’re working with BizForm’s programmatically you’re going to need to get the ID of a specific row so you can update or delete it. If you know the table structure, there’s nothing stopping you from going straight to the database, but if you do it using Kentico API’s and queries the code should be more upgrade-friendly.

This code makes some minor assumptions that are hard coded, but could be easily abstracted out:

  • The BizForm’s code name is “ContactUs” with an ID field (Primary Key) of “ContactUsId”.
  • I’m using a hard-coded where condition getting the first record. This could easily be changed to pass in another parameter to search on.

Without further ado, here’s the code:

public int GetRecordId()
{
    // Given the Code Name of the BizForm and the current site, get the BizForm object.
    var bizFormInfo = BizFormInfoProvider.GetBizFormInfo("ContactUs", uxBizForm.SiteName);

    if (bizFormInfo != null)
    {
        var dataClassInfo = DataClassInfoProvider.GetDataClass(bizFormInfo.FormClassID);

        if (dataClassInfo != null)
        {
            // Using the built in Select query, get the record we're looking for.
            var connection = ConnectionHelper.GetConnection();
            var whereCondition = String.Format("ContactUsId = '1'");
            var dataSet = connection.ExecuteQuery(dataClassInfo.ClassName + ".selectall", null, whereCondition);

            // Note the use of Kentico's aptly named DataHelper class.
            if (!DataHelper.DataSourceIsEmpty(dataSet) &amp;&amp; dataSet.Tables[0].Rows.Count == 1)
            {
                return ValidationHelper.GetInteger(dataSet.Tables[0].Rows[0][0], 0);
            }
        }
    }

    // If we get here, we didn't find a valid record.
    // If we get here you should probably do one of the following:
    //   Redirect to the "new record" page
    //   Redirect to an error page
    //   Or throw an exception
    return 0;
}

Posted in Kentico, Programming | Tagged .NET Framework, ASP.NET, C#, Code, Kentico API Programming, Kentico BizForms, Kentico CMS | Leave a response

How to Recursively Get Files in C# the Easy Way

By John Bubriski on February 21, 2012

Need to get all the files contained in a directory, recursively searching through sub directories? No problem!

Here is how to do it without writing your own recursive function:

var fileNames = Directory.GetFiles(directoryName, "*.*", SearchOption.AllDirectories);

That’s it! No explicit recusrion required!

If you want to do searching where you can stop when a given file is found, then you would need to implement the recursion yourself. This article shows you how to do that if needed:

How to recursively search directories by using Visual C#

Posted in Programming | Tagged .NET Framework, C#, Code, Files and I/O | Leave a response

Next »

About Me

I'm a Software Engineer at Worcester Envelope in Auburn, MA. Check out the About page to learn more about me.
Follow @JohnBubriski

Pages

  • About Me
  • Achievements!
  • Contact Me
  • Developer Resources
  • Kentico Resources
    • Kentico Tips and Tricks
    • Settings Module for Kentico CMS

Tags

.NET Framework AES ASP.NET ASP.NET MVC ASP.NET Web API AspDotNetStoreFront blogging C# Code Code Camp Cryptography Decryption Elmah Encryption Entity Framework Exceptions Extension Method HTML IIS IIS6 javascript jQuery JSON Kentico API Programming Kentico BizForms Kentico CMS Kentico Event Log Kentico Module Development Learning Python 3 Microsoft PHP Productivity Quick Tip REST Shortcuts SQL SQLite Development Symmetric Encryption Time Saver Travian Add On Project URL Routing Using PyGame Visual Studio web-service wordpress

Archives

  • 2012 (15)
  • 2011 (11)
  • 2010 (19)
  • 2009 (11)

Programming Blogs

  • Stack Overflow
  • Coding Horror
  • Code: Impossible
  • Self Elected
  • Chris Jenning's Blog

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Copyright © 2012 Johnny Code.

Powered by WordPress and Hybrid.

Maintained by John Bubriski