My Resume

  • My Resume (MS Word) My Resume (PDF)


Affiliations

  • Microsoft Most Valuable Professional
  • INETA Community Champion
  • Leader, NJDOTNET: Central New Jersey .NET User Group

Wednesday, September 10, 2008

S-E-Ooooh, That's How You Do It!

My boss, Kevin, and I headed out to Seattle last month (coincidentally during the time that some of our Infragistics buddies were heading up the speaker list at DevScovery) to attend an expert-level SEO seminar given by the bright folks over at SEOmoz.  And, boy was it enlightening!

Now, before I go any further, I'm going to have to state right up front that (until late last month) I have been wandering through my professional web career knowing only a bare minimum about SEO.  I thought I understood basic concepts like linking and keyword placement - the more times you link to a page and repeat a word, the higher your search rank, right?  Unsurprisingly, it turns out to be a bit more involved that that. :)

There's no way I'm going to duplicate in a blog post or even a series of blog posts what I learned at that awesome seminar - if you're truly that interested, I would suggest signing up for the training or at the very least checking out the articles on SEOmoz.  However, I wanted to 'jot down' a few of my largest takeaways, because they really made me reevaluate my view on the way SEO works.  Since I have a knack for oversimplifying things (verging on naivety), I figured a bulleted list would do just the trick.  So, below you'll find my ridiculously simplified...

List of Things You Probably Already Knew About SEO But Didn't Realize How Important They Were (or at least I didn't...):

  1. Backlinks.  I'm sure it comes as no surprise that having other sites (especially the big/important ones) link to yours is beneficial, but I'd have to say the most unexpected thing I took away from this seminar was just how important they are!  From what I understand, these account for the vast majority of your PageRank-ings - I'm talking well over half.  That means you need to beg, borrow, cheat, and steal (wait, no... not those last two) to get everyone and their dog to link back to you (assuming their dog's site has a lot of traffic, of course!).  As always, the better their PageRank, the better your Link Juice.

  2. Oh, yeah - Link Juice and nofollow!   To be honest, I'd never heard the term 'link juice' before.  But after hearing it explained, it was just so incredibly appropriate I really became endeared with it.  Put simply, think of the traffic to any one of your pages as water flowing into a pipe.  You start out with 10 gallons of water coming into one pipe (this landing page) from which it is split up and diverted to various other pipes (pages you're linking to from the landing page).  Each of these splits divides and cuts down the volume of the initial 10 gal., such that if you have, say, 10 links on your page each of them gets 1 gal. of that initial 10.  Now, if you play that concept all the way through each page, constantly splitting up the water on every page, you can imagine how quickly that 10 gallon deluge can become just a trickle...  Obviously, we'd like to see some pages on our site get more traffic than others, so how do we  keep our existing links so people can still navigate our site, yet "divert the water" to the pages that we think are the most important?  Fortunately, the answer is pretty simple - the "rel='nofollow'" tag!  Placing this tag on any of your links basically tells search engines "this page really isn't important to me and I really don't want to waste my influence on it."  It's kind of like disavowing all knowledge of your pages... even if it quite obvious that they're worth something to you (since they still exist, after all).

  3. Then there's plain ol' good, properly-formatted, and relevant content...  Really, from what I could tell, those first two bullets are the major players in terms of tips & tricks.  The search engines are getting better at filtering out spammers every day through various techniques, so your ultimate defense is to create interesting content, and make use of standard best practices like putting your important keywords in your <title> and <hx> tags, concentrating on creating relevant content, and trying to keep your markup light and semantically correct.  Simple... right?  "Easier said than done" is more like it!

I had intended from the start for this to be a quick overview of what I took away from my recent training and nowhere near a "deep dive" into SEO.  But, to help you on your way, I've collected a few resources that might help you learn some more if I've happened to pique your interest... which I certainly hope I have!

Additional Resources:

Hope this all helps!  Oh, and please leave me a comment and let me know if it does - I'd love to hear about it!

Saturday, August 2, 2008

The NJDOTNET Dojo is Born!

If you're a developer in the Princeton, NJ area, you'll be pleased to know that the NJDOTNET organizers have decided to create yet another group for your .NET learning pleasure!  Just this past Thursday, we had our first NJDOTNET Dojo meeting, at which I gave a presentation on the Web Development Productivity Tools I use to get things done. 

This new group will continue to meet on an on-going basis every Thursday night that there isn't another meeting (the main User Group or Agile discussion) going on.  Basically, if you're looking to learn about .NET, come on down to the Infragistics HQ on any given Thursday and you're bound to be satisfied!

See this forum thread for more details.

Tuesday, July 1, 2008

Use ASP.NET MVC ActionFilters to Render AJAX Responses!

In my previous blog post on ASP.NET MVC, I walked through an example based on the MVC Preview 2 bits which showed how to make your own custom view engines and ActionFilters.  I also proved (or at least hope I proved) just how powerful these parts of the framework can be, especially when used in conjunction with each other.  The truth is that - while I thought they made great examples on how to extend the base parts of the framework - the whole thing seemed kind of kludgie to me.  What I mean is that it felt kind of awkward having to use the ActionFilter to change which ViewEngine is being used on the fly.  I don't know, maybe I just feel like view engines should be more closely tied to the controller and shouldn't just be chosen willy-nilly like that!

This was all before the introduction of the ActionResult in MVC Preview 3.  Oh man, was this a great addition!  Expanding the notion of being "loosely coupled", the controller action's job is no longer to execute logic and chose which view to display-- ok, well, it is...  only now its main responsibility is returning an ActionResult, which is basically a command object that tells the framework what to do instead the controller taking that action itself.  This not only helps us to decouple the controller (allowing for easier testing, etc.), it also lets us know what the controller wants the framework to do before it happens.  When you think of it, this is pretty powerful stuff, and gives us access to a whole new part of the process in which can inject additional logic.  And inject it we shall...

The SerializableViewDataAttribute Revisited

In my previous post, the attribute that I adorned my Actions with was pretty stupid.  It just said, "Is this an AJAX request? If so, set our custom view engine."  Pretty much all of the meaningful (and interesting) logic happened in our custom view engine.  Now, with the introduction of the ActionResult we no longer have to wait until the view engine phase to get access to (and override) the way our data is returned to the client - we can hijack it in the attribute, and manipulate the Action's result!  Before I confuse you any more, here's the code:

SerializableViewDataAttribute: Preview 3 style
public class SerializableViewDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Get the (lowercase) render mode from the querystring
var method = filterContext.HttpContext.Request.QueryString["renderMode"] ?? string.Empty;
method = method.ToLowerInvariant();

// Get the view data from the context (using a custom extension method defined elsewhere)
var viewData = filterContext.GetViewData();

// If this isn't a serializable request or it has no data, just return
if (string.IsNullOrEmpty(method) || viewData == null) return;

// Decide which method to use
switch (method)
{
case ("xml"):
filterContext.Result = getXmlResult(viewData);
break;
case ("json"):
filterContext.Result = getJsonResult(viewData);
break;
case ("partial"):
// If this is supposed to be a partial request, just change the view name.
// Obviously, this implies that this view exists (in addition to your
// original view that the controller was pointing to to begin with.
var viewResult = ((ViewResult)filterContext.Result);
viewResult.ViewName = "Partial" + viewResult.ViewName;
break;
}
}

private static ActionResult getJsonResult(object viewData)
{
// Since there's a JsonResult Action,
// all we have to do is pass in the data
return new JsonResult { Data = viewData };
}

private static ActionResult getXmlResult(object viewData)
{
// There's no "XmlResult" so we have to serialize it ourselves
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
new XmlSerializer(viewData.GetType()).Serialize(writer, viewData);
}

// ...then pass it into a ContentResult
return new ContentResult
{
ContentType = "text/xml", // Be sure to set the ContentType!
Content = sb.ToString()
};
}

}


As you can see, it is a lot like the logic that was used to create my custom view engine in the last post.  In fact, I essentially copied and pasted it (and added support for partial rendering)!  Also, now that all of this logic lives in the ActionFilter we have no more need for that pesky custom view engine.  So long, cruft!


For the benefit of those who may not have read the explanation of this logic in my previous blog post, I'll go ahead and repeat (as well as expand on) it here.  This version should actually be a lot easier to understand since the logic is now contained in one place instead of spread out between the ActionFilter and the ViewEngine.  Here's a basic run-down of what's going on:


  1. The first thing to note is that we're overriding the OnActionExecuted method of the ActionFilter.  What this implies is that the controller action to which this attribute is applied has already completed, so we now have access to everything it's done: ViewData, TempData, ViewName, etc.  We could also have overridden the OnResultExecuting method as well; this would be somewhat similar to the difference between the PreRender and Render events when using Web Forms.
  2. Once the "event" has been triggered, the first thing we want to do is figure out what, exactly, is expected of us - AKA, which serialization mode (if any) we should be using.  In this implementation, I have decided to glean this information from the querystring, but you can just as easily use any other environment variable you'd like (such as the Route Data, cookies... whatever!).
  3. Next, I get the ViewData from the context, if any, using the filterContext.GetViewData() extension method.  Though this method is defined elsewhere and you can't see it in this snippet, it's not really all that interesting - it's just a convenience method that drills down into filterContext.Controller.ViewData (or ViewData.Model, if available) and returns it.
  4. Check the render method that we got in Step #2 and if that or the ViewData is invalid, there's nothing for us to do, so we're done and we just return.
  5. Assuming we didn't bail out in Step #4, we then go on to overwrite the existing ActionResult (or its properties), depending on what the user has asked for.  This particular version supports:
    1. JSON:  Along with the introduction of the ActionResult came the JsonResult, which is a super-cool implementation of ActionResult that serializes whatever data you give to it into JSON to be rendered down to the browser.  As you can see in this example, this makes handling requests for JSON data really simple and easy.
    2. XML:  Though there is no "XmlResult" as there is for JSON, the MVC framework still provides a ContentResult which is a lot like the JsonResult in spirit.  Both of them allow us to send data in some form back to the browser without requiring a View to render it with.  Going back to our example - you can see that it takes a bit of work, but the end result is a raw batch of just XML sent back to the client for processing.
    3. Partial Rendering:  I included this render mode as a bit of a teaser - I should have a follow-up post going in-depth about using partial rendering in ASP.NET MVC.  For now, I'll just say that you can think of it a lot like the ASP.NET AJAX UpdatePanel server control...

  6. That's it!  If we've gotten to this step and not hit any of the three types above, this particular filter will just let the request continue on and have no effects what-so-ever.  That probably means it'll just end up rendering out a fully-rendered page like any other normal (non-AJAX) request.  The important part to note here is that this filter only injects behavior when it is appropriate.  Otherwise, things proceed as normal and noone even needs to know that these actions are AJAX-ified unless you want them to.


I don't know about you, but the power that this kind of stuff gives us just makes my head spin!  Hopefully you find the above useful; if you do, please feel free to contact me and let me know, especially if you end up using it in one of your apps!



As always, you can check out all of the source code in my repository: http://code.jesschadwick.com/


This particular piece of code can most easily be found at this direct link.

Wednesday, June 25, 2008

Where the heck can I download Firefox 2.0!?

Now that Firefox 3.0 is finally released, Mozilla has done a real good job of clearing out any mention of it from their website.  Thing is, we web developers still need to test on it!

Well, after a bit of querystring hacking (simply replacing "product=firefox-3.0" with "product=firefox-2.0.0.14"), I came up with this link, which should get you what you need:

Download Firefox 2.0.0.14

Thursday, June 19, 2008

Inaugural NJDOTNET Agile Meeting **Tonight**

As I announced at the last few weeks' NJDOTNET Study & User Group meetings, we'll be having our very first NJDOTNET Agile meeting tonight, Thursday, June 16th starting at 6:30 PM in the Infragistics auditorium in East Windsor (the same location as the regular NJDOTNET user group meetings). Here's a little bit about the group:

Taking a cue from both the growing ALT.NET movement and quite a few members of the main NJDOTNET user group, I've decided to augment the monthly meetings of our established user group to create a more interactive, discussion-based meeting. These Open Spaces meetings will occur once a month, on the weeks following the regular User Group (the third Thursday of the month). Hopefully the addition of these meetings will allow everyone to get the benefit of a different style of interaction and learning that the “Lecture-Learn” style of the main user group cannot provide.

I'll see everyone there!

Tuesday, June 10, 2008

ASP.NET MVC: Using Custom View Engines and Filters for AJAX

Way back in the time of ASP.NET MVC Preview 2 (last month), I was preparing for a presentation and decided that it would be nice to show just how simple it is to make your own View Engine.  Having found David Higgins' JsonViewEngine a few days earlier, I decided to expand a little upon it and add the option to emit either XML or JSON using the same engine.  After a little while, I had something looking like this that supported both:

SerializableViewEngine

public class SerializableViewEngine : IViewEngine
{
    public void RenderView(ViewContext viewContext)
    {
        string method = viewContext.RouteData.Values["responseType"] as string;

        string serializedData = string.Empty;
        switch (method.ToLowerInvariant())
        {
            case "json":
                serializedData = new JavaScriptSerializer().Serialize(viewContext.ViewData);
                break;
            case "xml":
                serializedData = SerializeToXml(viewContext.ViewData);
                break;
        }

        viewContext.HttpContext.Response.Clear();
        viewContext.HttpContext.Response.Write(serializedData);
    }

    protected static string SerializeToXml(object o)
    {
        StringBuilder sb = new StringBuilder();
        using (TextWriter writer = new StringWriter(sb))
        {
            new XmlSerializer(o.GetType()).Serialize(writer, o);
        }
        return sb.ToString();
    }
}

As far as building a custom ViewEngine goes, I figure this is a great example - other than the fact that I extracted my "SerializeToXml" logic out, this is a one-method override!  At first glance this (and David's) implementation may seem a little "underpowered" because of how few lines it took, but if you disassemble the System.Web.Mvc assembly or look at the MVCContrib code, you'll see that even real-world ViewEngine implementations can be this simple!  I guess that's one of the nice side-effects of separation of concerns - when big things are broken up into a bunch of pieces, those pieces are usually pretty small!

As for the details of this particular example, you'll notice that it checks the RouteData dictionary (populated from the routing tables you specified elsewhere) to see if it contains "responseType" (e.g. if one of your routes was "{responseType}/{controller}/{action}" and the url that was called looked something like "/json/products/categories") and try to honor it by serializing the ViewData that was passed from the controller into the requested result.  Once it has serialized the data, it just writes it directly to the Response and you're done!  You could then use this View Engine to render out all the async calls all day and night, just by setting the ViewEngine property on the controller instance like so:

Setting the ViewEngine

public void AsyncCategories()
{
    var categories = repository.GetCategories();
    this.ViewEngine = new SerializableViewEngine();
    return RenderView("Category", categories);
}

Simple as that, right?  Well, sure... but what happens when you end up making duplicate Actions for your "normal" browser and AJAX requests that have all the same logic with the exception of that one line?  The line that sets the ViewEngine is hard-coded in there, so you have to have separate Actions, right? 

Enter the ActionFilter!

Wrong!  After thinking about it for a minute I realized that this is the perfect place to use an ActionFilter (which was a good thing, because I just so happened to need a code example for that, too)!  And so, I got to coding and came up with this guy:

SerializableViewDataAttribute

public class SerializableViewDataAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        var controller = ((Controller)filterContext.Controller);

        if (filterContext.RouteData.Values.ContainsKey("responseType"))
            controller.ViewEngine = new SerializableViewEngine();

        base.OnActionExecuting(filterContext);
    }
}

As you can read about here (if you haven't already), ActionFilters are the perfect way to "inject" behaviors into your controllers.  I like to compare them to the ol' Web Forms ASP.NET Page Lifecycle events such as PreInit, Init, PreRender, Render, etc. that let you plug in to the various stages of processing a request and allow you to manipulate it accordingly.  For example, by overriding the OnActionExecuting method on the ActionFilterAttribute as shown above, you can plug into the request after it's reached the controller, but before any action has actually been taken on it.  I believe I could have also used OnActionExecuted to accomplish the same thing since I'm only setting the ViewEngine, but that just didn't "feel" right.

Using this new custom ActionFilter, I could apply it at the Action level - or the Controller level if I wanted to apply it to all of the controller's actions - and get rid of those silly duplicate Actions.  Now, instead of having the AsyncCategories Action shown above (which is assumedly just a duplicate of some other Action, perhaps called Categories) that explicitly overrides the ViewEngine with every request, I can now drop the line that sets the View Engine and let my new ActionFilter take care of setting it for me when it is appropriate!  In other words, the code above now turns into the code below, which handles both "regular" and AJAX calls with the same code!

Removing the ViewEngine code from the AsyncCategories Action

[SerializableViewData]
public void Categories()
{
    var categories = repository.GetCategories();
    return RenderView("Category", categories);
}

The first time I successfully saw the result of running this demo was the first time the power of ASP.NET MVC really hit me.  This whole example was just a bunch of really small and straight-forward (dare I say 'simple'?) pieces that, when put together, create some really amazing and powerful results.

Grab the Code and See For Yourself!

You can see all of this stuff in action by downloading the code from my website:

 

I welcome any and all feedback y'all can throw my way.  Enjoy!

UPDATE:  As the beginning of the post says, these are what you can do with the Preview 2 bits.  With the addition of the ActionResult in Preview 3 and the related methods on ActionFilter, you can actually ditch the custom ViewEngine altogether and just use the ActionFilter!  Not the ActionFilter I show here, mind you, but an updated version I will show in an up-coming blog.  :)

Thursday, June 5, 2008

Douglas Crockford JavaScript Videos Online!

I was doing some JavaScript development earlier tonight, Googled an issue I was having and at the bottom of a blog post the author linked to a bunch of videos on Y! Video of a Douglas Crockford presentation, "The JavaScript Programming Language".  These videos are - hands down - the best use of my time spent learning JavaScript ever.

Here they are:

There is also an "Advanced" series, too!

Monday, June 2, 2008

ASP.NET MVC Firestarter - June 7th!

Are you interested in diving deep into the new ASP.NET MVC framework?  If so, come check out the NYC ASP.NET MVC Firestarter!


I'm not going to duplicate too many details here, but it's Saturday, June 7th, 2008 at the Microsoft offices in NYC (1250 Ave. of Americas). 

Check out this link for more information and to register!

Oh yeah - there's gonna be free food, too! :)

The Search for a Proper VM Host

The task that's been consuming my past few weekends (and a good deal of my weeknights) has been exploring various options for running various virtual machines on my desktop PCs (as opposed to my "server", which runs Gentoo Linux without debate or question).  "Why?" you might ask, and for good reason, since I am continually asking myself the same thing...  Even I am not sure that this is really the best route to go, but I'll try to enumerate my goals below which may shed some light on my rationale.

My Goals

  • Avoid the pain of dealing with pre-release software and frameworks.  I've always been incredibly interested in bleeding-edge technologies and releases and being an early adopter often has its painful side-effects.
  • Avoid bloat.  Keep it "clean and simple." I'm a minimalist and I don't like bloat.  Visual Studio may be the best .NET IDE around, but it's friggin' huge!  I may use it (and my other development tools) a lot, but I don't consider them part of my "core OS/tools".  When I boot up, I want to be up and running as quickly as possible; and when I'm running, I don't want anything other than what I currently need (and that includes stupid OS "features") to be hogging my resources, be it CPU, RAM, or even disk space.  I want to load those those in their own VM and turn them off/on when I need them; having them in their own VM also gives me the freedom to store them wherever I want and even transport them other places (like work)!
  • Be "Agile".  The key to agility is being able to do things quickly.  I also think a key part of Agile development practices is being able to not only try something just to see how it turns out, but the implied converse of easily being able to roll back to a clean environment before you tried that thing out.  Applying this principle at the OS level is a very powerful concept.  (This is very closely related to the first bullet-point above)
  • Run Linux as much and where ever possible.  This one has no real logic to it - it's completely emotionally-driven.  I love the idea of the power I get running Linux and I'd like to harness that power wherever possible.  The downside to this (as I found out in this process) is that the UI in Linux really sucks;  it's ugly to the point of un-usability.  (Yes, I know function, experience, and style are very different things, but in this case style overrules them all.)

My Stabs at Success

  1. VMWare ESX Server.  This looked like the ultimate answer, since it appeared to serve all of my goals above.  Unfortunately, the install for ESX didn't really go very smoothly (not to mention the fact that it was slightly, ah, "questionable" - legally speaking - to begin with...) so I gave up on it quite easily.
  2. VMware Server on Ubuntu JeOS.  I downloaded and burned a copy of this at 3 AM Saturday morning, but never installed it.  Why?  'Cause I re-read its overview and saw that it is meant to run ON a VM host, not act as one!  Stupid (actually, time for bed...)!  Luckily I only wasted about 20 minutes and a CD downloading and burning it.
  3. VMware Server on Ubuntu Server Edition.  Well, I got everything up and running with minimal overview...  Then I realized I didn't just need to host VMs...  I needed to be able to "consume" them on the same machine!  DOH!  In retrospect, this was an incredibly blatant oversight.
  4. VMware Server on Xubuntu.  Now we're on to something!  Linux host with very minimal overhead - I had the whole system up and running, hosting VMs, and running the client with only 600 Mb RAM.  This was awesome, and it met all of my goals.  Problem was - it met them a little too well.  Sure, I wanted a minimal system to host VMs with no bloat, but the fact is, I kinda wanted some of that bloat.  IM, Twitter, and even Microsoft Office are the types of things that I want available all the time and not things I want or need to virtualize.  Sure, there are OSS replacements or workarounds that can handle pretty much all of my needs, but I came to the sad, sad realization that Linux as a desktop just plain sucks.  It's powerful, sure - but it looks like crap, and that makes it just plain dreadful to spend most of your time in... especially in a "minimal" environment like the one I was shooting for.
  5. VMWare Player on a trimmed-down Vista.  Luckily, I was trying out all of the previous attempts on an extra HD, not actually overwriting my existing Vista install; an install which, quite honestly, I never intended to completely replace as I do play games on it occasionally.  This is the solution I eventually settled for (at least for now), since it seemed the best compromise of all my goals, including those hidden ones I discovered along my journey.  I'm wondering, though, if this really is the best solution...  For starters - you'll notice the other solutions involve VMWare Server whilst this one uses Player.  That's right - since I'm on a 64-bit machine and stupid Vista doesn't allow non-signed drivers (and for some strange reason stupid VMWare doesn't provide signed drivers for Server), I'm left with the crappy, non-feature-ridden VMWare Player.  Which sucks.  Oh yeah, and did I mention Vista is bloaty!?

The Bloat that is Vista

Even after I spent quite a while picking and choosing which services to kill (practically all of them - including Themes - except the bare system ones) in order to make my Vista install as lean as possible, it still took up 15% of my total 6 GB of RAM!  Here's a few screenshots of my system after it's booted up before I've run anything (except SnagIt and FolderShare):

Vista - Memory Hog Vista Task Manager - Full

That is not my idea of "minimal", especially compared to my Xubuntu install!  I don't have a screenshot of the latter, so you'll just have to trust me when I tell you - 617Mb.  A fully-running system (including X & XFCE Window Manager) took 617Mb of RAM... and that was without any real attempts at minifying it any more than the default install!  Now I'm left wondering what a stripped-down install of XP would look like....

So, I'm back to square one - facing the dilemma that I've been tortured with for the past 6 years since I began using Linux: suffer with the unsavory UI and awkward UX that is the Linux Desktop, or deal with the bloat that is Windows.

It really is a no-win situation.

Sunday, April 20, 2008

Central New Jersey MS Certification Study Group

We had our inaugural meeting of the "NJDOTNET Spring '08 MCTS Study Group" this past Thursday, and I thought it was a wild success!  I had just under 30 people register (express interest) over the past few weeks, about 5 email me before the meeting to let me know that they wouldn't be able to attend this first one (but, yes, they are very excited!), and an even 20 people actually show up.  I sure am happy with those numbers!  My favorite part about the whole thing is the positive energy and just raw desire to dive deep into .NET that all of the members are showing.  It really is a great thing to know that you'll be able to meet up with these people (and this energy) for at least a few hours every week.

For those of you who haven't heard through the various other channels, we can still squeeze a few more members in.  So, if you're interested in getting your MCTS certification in Windows Forms or ASP.NET, please feel free to let me know.  We meet every Thursday night at 6:30 PM at the Infragistics headquarters just outside of Princeton, NJ.  Check the NJDOTNET Website for more information, including directions.