Thoughts on Windows Phone 7…

Add Comment | Jan 09, 2012

So, first off, I’m by no means a mobile developer.  I’ve played around with some samples here and there, but I have not built anything significant to date.  So I’m not that familiar with the publishing process for iPhone, Android and WP7 applications.

OK, with that out of the way, I will say that I am an owner of 2 WP7 devices (one for me, and one for my wife).  We both like them a lot, think the UI is great and intuitive, and like how the device is laid out.  Honestly, when I go back to my iPod Touch device, I find it a bit clunky compared to the WP7 devices.

I have about the same number of apps on both devices – my iPod Touch has a few more financial and personal applications than my WP7 device does because of the sheer number of more apps in the App Store.  But I have a good number of apps that exist on both platforms (e.g. Netflix, Amazon, IMDB, Evernote, etc.) and I think a good number of them look and perform better on the WP7 device.

But what bothers me is that the activity in the App Store dwarfs the activity in the WP7 Marketplace.  The apps on my iPod Touch seem to have updates every week or so – updates that provide fixes and functionality.  The apps from the WP7 Marketplace are few and far between, and usually don’t provide a lot of functionality.  Granted, this is not scientific – but more of an informal observation.

But what this tells me is that companies aren’t investing a lot in WP7 applications.  Looking through the WP7 Marketplace, while there are a large number of apps, there aren’t a lot of “professional” applications.  There’s no E-Trade, Schwab or an app for my personal bank; few productivity apps that are free; and just a bunch of odd apps scattered throughout the marketplace.  My guess is that a lot of developers are building apps for personal gain; but few companies are building apps.

All of this makes me concerned for the future of WP7.  I think it’s a great OS that has a lot of potential, but I’m afraid that it’s going to be a niche OS at best.  I think Microsoft should pay attention to some of the items in this blog post about how they can get the WP7 out there.  If they don’t react and try to improve the reach of WP7, I think Microsoft’s future in the mobile space is over.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

JSON.net and Deserializing Anonymous Types

Add Comment | Jan 06, 2012

I had a situation where I had to deserialize a small chunk of JSON-formatted data and I didn’t want to create a class for it since it was a very specific use and I was confident there wasn’t a need to reuse it elsewhere in the application.

 

If I did have a class defined for the JSON data, I could easily use JSON.NET’s JsonConvert.DeserializeObject method:

 

   1: string myJson = "[{id: 10, typeID: 4},{id: 100, typeID: 3}]";
   2: MyObject obj = JsonConvert.DeserializeObject<MyObject>(myJson);
   3: Console.WriteLine(obj[0].id);

 

So this is easy to do, but I really didn’t want to define a MyObject class for a one-time use.  So I thought I’d go the route of an anonymous type and use JSON.NET’s JsonConvert.DeserializeAnonymousType method.  I thought it was a bit vague how to use this since it asks for a type parameter – but since my output will be an anonymous type, what would my type parameter be?

Well, the best way that I came up with in a short period of time was to define a dummy anonymous type and pass it to the JsonConvert method.  It’s a little bit of overhead and an extra line of code, but it does work.

 

   1: string myJson = "[{id: 10, typeID: 4},{id: 100, typeID: 3}]";
   2: var dummyObject = new[] { new { id = 0, typeID = 0 } };
   3: var myObjects = JsonConvert.DeserializeAnonymousType(myJson, dummyObject);
   4: Console.WriteLine(myObjects[0].id);

 

The slightly confusing part was the Intellisense provided by JSON.net:

 

JSON_NET_intellisense


Seeing the ‘T’ type parameter makes you think you need a call to typeof() or something similar.  But in the case of deserializing to an anonymous type, you just need an instance of the anonymous type.

I thought I may have been missing something, but a little Bing research showed that there were similar approaches taken (see here and here).

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

My Two DEVLINK 2011 Talks Uploaded

Add Comment | Aug 25, 2011

After an incredible trip to Chattanooga, TN (my first trip to Tennessee, by the way), I finally made it back home to Pittsburgh and found some time to upload my two DEVLINK talks (slides and code).  I tried something a little different this time by adding my code to GitHub and my slides to SlideShare.  We’ll see how that works out – but I’m optimistic.  So without further adieu, I present to you my 2011 DEVLINK talks.

 

Talk #1: Greenfield Development with CQRS (and Azure, and MVC, and a bunch of other stuff….)

Admittedly a bit of an overly achieving topic, but the talk went well.  I did not do a very good job of managing time, due to the fact that the discussions in the session were that engaging and interesting.  But I think the talk went well and introduced the basics of a CQRS application being hosted in Azure.

GitHub Repo: https://github.com/DavidHoerster/BuzzyGo

Talk #2: jQuery and OData – Perfect Together

I really enjoyed this talk.  I’ve given WCF Data Services / OData talks before, but this one had a great dynamic in the room – the questions were great, the interaction was awesome.  Overall, I had a great time.

GitHub Repo: https://github.com/DavidHoerster/AgileBaseball

Again, thanks to everyone that attended my talks.  I had a great time and I’m looking forward to next year’s DEVLINK!!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

HTML / CSS / JavaScript – We Need An Acronym

8 Comments | Aug 10, 2011

I’m a big fan of client-side development using HTML / CSS / JavaScript for about the past 2 or 3 years – really ever since I dug into jQuery and really began to appreciate the power that the technologies on the client-side possess.  Nowadays, everything is HTML / CSS / JavaScript – it’s in all the articles, all the techies are talking about it, and it’s on everyones’ resumes.

In looking at candidate resumes or listening to presenters speak about web technologies, we constantly hear “HTML / CSS / JavaScript”.  They’re presented in different order, but regardless, it’s still quite a mouthful to say or read over and over.  It’s 10 syllables – way too much for these OCD days.  And especially since we live in a 140 character world, we need an acronym or a shortening for this term.  I’ve given this much thought and have arrived at my contribution to this serious, serious problem.

 

JACSHT

 

That’s right.  We’ll just take the first two characters of JAvascript, CSs, and HTml, and voila!  A new word!  I mean, we have:

  • AJAX (asynchronous JavaScript and XML – way too long and it’s not even XML all the time anymore!);
  • JSON (JavaScript Object Notation – and is it JAY-son or jay-SOHN?)
  • and so on.

So how could this work?  I think this could lend so much truth to many conversations:

 

HIRING MANAGER: So, do you know JACSHT?

CANDIDATE: No, sir, I don’t know JACSHT.

HIRING MANAGER: How can you expect me to employ you if you don’t know JACSHT?  The whole world is moving towards JACSHT.

CANDIDATE: Sir, I wish I knew as much JACSHT as you.

 

DEV1: I just got back from BUILD and now I know all about JACSHT.

DEV2: Oooh, I’m not doing JACSHT in my job.  I wonder if anyone will care if I’m not doing JACSHT?

 

See how easy this is?  And it really conveys a ton of meaning when a DEV doesn’t know JACSHT.

 

So I’m proposing that we begin to refer to the client side technologies of HTML, CSS and JavaScript as JACSHT.  It’s easy to say (heck, even a little funny) and communicates effectively when a DEV doesn’t understand that technology.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Creating a PHP MD5() Extension Method for C#

5 Comments | Aug 01, 2011

In the project that I’m working on (let’s call it BrainCredits v2.0), I wanted to integrate a user’s Gravatar into the system (like how StackOverflow does it).

To Gravatar’s credit, they make it very easy to incorporate a user’s image – just hash the user’s email address (which I have) to the end of their URL and you’ll get the image back.  The email address just has to be hashed using the MD5 algorithm, and they provide examples of how to do that in PHP.  Oh, it looks so easy:

echo md5( "MyEmailAddress@example.com " );

It’s a one-liner in PHP – just call md5() passing in the string you want to hash and you’ll get your hash back.  There must be a similar method in C#, right?  As far as I can tell, there isn’t.  You have to:

  1. instantiate the MD5CryptoServiceProvider,
  2. convert your string to a byte array,
  3. run that byte array through the crypto provider to compute the hash (and get a byte array back)
  4. and instead of just converting that byte array back to a string, you need to run through each byte and convert it via this:
myByte.ToString("x2").ToLower()

Now you have your string.  Lots of work, especially compared to PHP.  Perhaps this is why so many developers go towards PHP?  Anyway, I need to generate this hash, and decided to create an Extension Method for it.  My full code looks like this:

using System.Text;

namespace System
{
    public static class StringExtensions
    {
        public static String MD5(this String stringToHash)
        {
            var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] emailBytes = System.Text.Encoding.UTF8.GetBytes(stringToHash.ToLower());
            byte[] hashedEmailBytes = md5.ComputeHash(emailBytes);
            System.Text.StringBuilder sb = new StringBuilder();
            foreach (var b in hashedEmailBytes)
            {
                sb.Append(b.ToString("x2").ToLower());
            }
            return sb.ToString();
        }
    }
}

 

You would call it like this:

String emailToHash = "dhoerster@gmail.com";
String hashedEmail = emailToHash.MD5();

 

Oh, that’s easy!  And it makes sense.

Well, I hope this helps someone, and maybe there will be some suggestions on how to improve this.  Good luck!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

JSON.NET Custom Converters–A Quick Tour

Add Comment | Jul 26, 2011

I have to admit that I’m a basic user when it comes to JSON serialization/deserialization.  I’ve used JSON.NET and the DataContractJsonSerializer.  I’ve read that JSON.NET is faster and more efficient than the built-in .NET serializer, but I haven’t had to build a system that is dependent on squeezing microseconds out of my serialization routines.  That said, I do prefer JSON.NET because it is more flexible when it comes to using DataContractAttribute and DataMemberAttribute for customizing your JSON output.

So I came across an interesting question on StackOverflow today, asking how a json string like:

{‘one’: 1, ‘two’: 2, ‘three’: 3, ‘four’: 4, ‘blah’: 100}

would have its “one” and “two” properties deserialized to an object’s One and Two properties (easy) and anything else in the json string would be dumped into a Dictionary<string,object> (hmmm…not so easy).  So the resulting object would look like:

Mapped mappedObj = { 
  One = 1; 
  Two = 2; 
  TheRest = [{three=3}, {four=4}, {blah=100}]'; 
}

I’ve read about custom JSON.NET converters, but had never written one.  So I decided to give it a shot and discovered that it’s really not too bad.  Here’s my sample code:

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

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Reflection;

namespace JsonConverterTest1
{
    public class Mapped
    {
        private Dictionary<string, object> _theRest = new Dictionary<string, object>();
        public int One { get; set; }
        public int Two { get; set; }
        public Dictionary<string, object> TheRest { get { return _theRest; } }
    }

    public class MappedConverter : CustomCreationConverter<Mapped>
    {
        public override Mapped Create(Type objectType)
        {
            return new Mapped();
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var mappedObj = new Mapped();
            //get an array of the object's props so I can check if the JSON prop s/b mapped to it
            var objProps = objectType.GetProperties().Select(p => p.Name.ToLower()).ToArray();

            //loop through my JSON string
            while (reader.Read())
            {
                //if I'm at a property...
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    //convert the property to lower case
                    string readerValue = reader.Value.ToString().ToLower();
                    if (reader.Read())  //read in the prop value
                    {
                        //is this a mapped prop?
                        if (objProps.Contains(readerValue))
                        {
                            //get the property info and set the Mapped object's property value
                            PropertyInfo pi = mappedObj.GetType().GetProperty(readerValue, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                            var convertedValue = Convert.ChangeType(reader.Value, pi.PropertyType);
                            pi.SetValue(mappedObj, convertedValue, null);
                        }
                        else
                        {
                            //otherwise, stuff it into the Dictionary
                            mappedObj.TheRest.Add(readerValue, reader.Value);
                        }
                    }
                }
            }
            return mappedObj;
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            //a sample JSON string to deserialize
            string json = "{'one':1, 'two':2, 'three':3, 'four':4}";

            //call DeserializeObject, passing in my custom converter
            Mapped mappedObj = JsonConvert.DeserializeObject<Mapped>(json, new MappedConverter());

            //output some of the properties that were stuffed into the Dictionary
            Console.WriteLine(mappedObj.TheRest["three"].ToString());
            Console.WriteLine(mappedObj.TheRest["four"].ToString());
        }
    }
}

It’s pretty simple to create a custom converter and it’s almost limitless as to what you can do with it.

Of course, my sample code above is pretty simple and doesn’t take into account arrays or nested objects in the JSON string; but, that can be accounted for by using the JsonToken enumeration (which I do above in detecting a property) and checking for the start of a nested object or an array.

I found this an interesting exercise and gave me an opportunity to take a tour of a feature in JSON.NET that I’ve read about but never used.  I hope you find it interesting.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Things I Didn’t Know – Stacking Your Using Statements

One Comment | Apr 15, 2011

One of the things that I love about the .NET framework is that I am constantly learning new things about it, finding new jewels that save me time, and just some really interesting bits.  This latest item I found falls into the “interesting bits” category.

Probably like many of you, I’ve written a number of console applications to do some tasks quickly and with little fanfare.  Usually these tasks are one-time tasks, and the console application is almost a throw-away project once I’m done with it.  Because of this, I usually attempt to get things done quickly and sometimes my code isn’t the neatest – shocking, I know!

Well, for this one task, I had to read information from a CSV file, write a status to a TXT file and also write some updates to our data layer.  These tasks involve the use of IDisposable objects; and as a result, I usually wrap these in a using block.

Here’s what my code usually looks like:

   1: using (StreamWriter sw = new StreamWriter(statusFile, true))
   2: {
   3:     using (StreamReader sr = new StreamReader(filename, Encoding.Default))
   4:     {
   5:         using (CsvReader csv = new CsvReader(sr, true))
   6:         {
   7:             //some work is done here
   8:         }
   9:     }
  10: }

 

So not too bad, but most of the ‘real’ code in my project tends to be in the middle of the IDE due to all of the indenting.

I can stack my using statements, instead, on top of each other, and have them all be contained with a single block, like so:

   1: using (StreamWriter sw = new StreamWriter(statusFile, true))
   2: using (StreamReader sr = new StreamReader(filename, Encoding.Default))
   3: using (CsvReader csv = new CsvReader(sr, true))
   4: {
   5:     //some work is done here
   6: }

 

Much cleaner, much more condense, a little easier to read (IMHO) and it saves a few lines.  It’s nice when you find out something new in a language you’ve been using for years.  I’m a little embarrassed that I didn’t know you could do this, but I’m glad I know now.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Philly Code Camp 2011.1 - Recap and Session Materials for My Two Talks (OData and LINQ)

One Comment | Apr 11, 2011

Well, another Philly Code Camp has come and gone, and it was a great time. I made it a one-day trip, which I think I'm getting too old to keep doing. Left the house at 4 AM from Pittsburgh, made it to Philly by 8:15 AM; I left around 4 PM and got home by 9 PM (no thanks to my TomTom, which took me on a scenic tour of old town Fort Washington).

I was expecting a nice and relaxing day at Philly Code Camp where I had one talk (A Beginner's Guide to LINQ) at 2 PM; but I got an email from Marc Ziss asking if I could do another session due to a speaker getting sick. So I filled in for Roberto Hernadez and presented on An Introduction to WCF Data Services and the OData Protocol (I need to shorten that title!) at 10 AM. Roberto's talk was on NHibernate 3, which I know nothing about, so I couldn't fill in for the topic. Since he had to drop out the day before and the schedules were already printed up, there was no time to get an update out to all attendees.  So I ended up with a lot of people coming into my session, staring at the projector with a confused look for a few seconds, and then looking disappointed that the topic wasn't NHibernate. But I would say a good 50% of the attendees stuck around and we ended up with an 80% full room towards the end, which I was impressed with.

Both sessions had great interaction with the attendees, great questions, and gave me a few things to think about for the next time I use these topics. Thanks to everyone who attended my sessions and thanks to the folks at Philly Code Camp for allowing me to speak.

By the way, my current "new adventure" is a start-up called BrainCredits. It's a site that allows you to track all of your informal learning - code camps, webinars, podcasts, articles you've read, etc. - in one place. We're currently in "laying low" mode, but you're more than welcome to sign up and get credit for my talks. It's free to sign up, and if you have any feedback on the site, please email me at david@braincredits.com. The URLs to my lessons on BrainCredits.com are:

OData: http://www.braincredits.com/Lesson/10774
LINQ: http://www.braincredits.com/Lesson/10760

In fact, all of the Philly Code Camp sessions are indexed there - so you can grab credit for any session you attended. Just do a tag search for "philly".

If you just want to download my slides and code from the presentations, the materials are on my SkyDrive account at:

http://cid-a5ab7de2a28501ee.office.live.com/browse.aspx/Public/Philly%20Code%20Camp%202011.1

Thanks again, and see you at the next Philly Code Camp!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

CMAP 2010.2 Session Materials

One Comment | Nov 07, 2010

So I had a great time at this past weekend's Central Maryland Code Camp (CMAP).  I was honored that the organizers chose two of my talks for their schedule (Intro to Threading and A Beginner's Guide to LINQ).  I have to admit that I didn't manage my time very well with the Intro to Threading talk; and, as a result, I didn't really get to my favorite code samples.  But I feel like I came back strong with my LINQ talk and managed the clock pretty well.  We'll see when the evals come in.

My session materials, both slide decks and code samples, can be downloaded from my SkyDrive account.  Here's the link

I hope everyone had a great time at CMAP, and I'll see you at my next Code Camp adventure!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Altoona (PA) Area .NET User Group (AltooNUG): Welcome to the Club!!

Add Comment | Sep 08, 2010

There's a new .NET user group forming out there -- in Altoona, PA.  I've been lucky enough to listen in on the initial conversations of AltooNUG and I'm excited to hear that they are holding their first meeting on September 21st, 2010!

Here's the initial informatioin about the group's first meeting.  If you're in or around the Altoona, PA area, you should drop in and pay them a visit.  There's a lot of interest in starting this group and I think there will be a lot of activity coming out of Altoona very soon.

Good luck AltooNUG!!

 

Meeting Date/Time/Location
Sept. 21 2010, 6pm – 8pm
@ Link Computer Corp.
Bellwood PA
 
Planned Topics
Review of Central PA .Net user group CodeCamp (held Sept 11th in Harrisburg)
Roundtable discussion on how members are using .Net
Formulate LinkUp presence/strategy
Plan topic/time/location for next two meetings
Eat pizza
 
Directions To Link
Link is in Bellwood, which is about 8 miles north of Altoona, just off of I-99/U.S. 220.
·         Get off I-99 (U.S. 220) at exit 41 (Bellwood Exit), taking PA-865 North (really west) toward Bellwood.
·         Drive 1/3 mile, take your first left onto E Pleasant Valley Blvd.
·         Drive 1/2 mile, turn right onto Stadium Dr.
·         Drive 1/4 mile to Link Corp. (on your right).
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati