8/26/2008 10:52:00 PM

Brian Hitney's Enterprise Guild MVC Presentation

Tonight I attended the local Enterprise Guild's ASP.NET MVC presentation by Brian Hitney. I don't know if I've ever given a review of a colleague's presentation (so this might suck) but I feel one's in order.  Brian's doing his best in this area for Microsoft to spread this and other information and I want to take a moment to recognize, suggest some critique of, and applaud his efforts.

Brian's an excellent speaker and a major contributor to the .NET and Microsoft community in the southeast. He was patient, careful, and did his best to keep things on track without pandering to or disregarding the audience when they requested more information be given to specific areas of interest. He has a way with any collection of subject matter; he adds humor to the presentation, keeps the pace moving along, and overall seems to feel really cozy in front of a crowd. A truly good presenter knows the value in saying something akin to "I don't know, dude, that's an interesting point you bring up," and Brian's not afraid to do just this thing. I think that may be his biggest strength as a developer evangelist - he doesn't preach and he isn't a know-it-all.

I got the impression that most of the people in the audience tonight benefitted from the presentation, which covered some fundamental aspects of the MVC "idea," rather than focus on some of the lower-level points concerning the actual execution of a coding experience using the ASP.NET MVC framework. So when Brian made it clear that the presentation would be covering the "why's" and not the "how's," I have to admit my colleague and I had a mutual eye-roll. MVC isn't an easy concept to grasp, I know. It took me about 3 years to really understand how it's supposed to work. Even now I still struggle with some of the innerworkings of the approach. So that portion of my review is, I admit, somewhat selfish in nature. I would've like to have seen more low-level discussions of the technicalities. 

During the initial chat, Brian brought up Inversion of Control and Dependency Injection. I think a better approach for Brian when dealing with these more complex and abstract concepts would've been to defer to the audience's willfullness to learn more on them; maybe say something about them being important ideas that are "outside the scope" of the presentation (because, well, they are outside the scope of a presentation like this). Instead, Brian gave a few examples of IoC and/or DI. One in particular was to use the event model - a button-click event handler, to be precise - as an example of IoC. I don't claim to be a guru at IoC, but I am positive that I can't think of how IoC could be represented via such an example. I really can't, and I tried. My co-worker agreed with me on this matter, too, so I know I'm not nuts (or that I have a partner in my misunderstanding of something). That's my one major "you didn't capitalize the 'N' and the 'E' and the 'T' when you put '.NET' on your resume'"-type complaint with Brian's presentation. My guess is that Brian understands all of these ideas quite well and could discuss them rather fluently under the appropriate context. In that, when he put them on the slide he had excellent intentions that completely escaped him when he was in front of a crowd of geeks. It happens. 

There were a few technical items of note during the presentation. The first was when Brian created an ASP.NET MVC project in VS2K8. When the "do you want to create a test project" screen was presented and the MS Test the only option in the "what type of test project do you want to create" drop-down, Brian said "If you install NUnit you'll see it in here too." I have both VS2K8 installed and NUnit, and I don't see an NUnit option. So I conclude that there's some additional schnizzle that I need to download and install to tie NUnit to VS2K8, that I haven't yet read that particular blog post (note no link, feel free to hook me up in the comments), or that his statement was incorrect. Brian? Bueller? Anyone? What is it? How do I get NUnit to appear in that list?

Later occurred what I think was the only major and potentially heinous blunder of the presentation. A question was raised about the variance between ASP.NET MVC's behavior on IIS6 and IIS7. It was late in the presentation when an audience member asked about the differences between the two server versions. The meeting was in a new room, started late, and had a huge crowd, so I'm sure Brian was exhausted and ready to call it quits. So, when this question was asked, Brian's answer was simply to state that there was no difference in the way the routes had to be set up and that it'd all work just fine under either version. I'd been bitten by this variance myself (and I have a complete lack of being able to keep my trap shut) so I raised my hand and commented that this wasn't the case. For the record, I said this not to call Brian out and make him look like a dimwit but rather to make sure the correct information was given to the audience. I mean, that's why we're all there, and it is called a community group so I figure that's the best thing one could do in the situation. I specifically mentioned the approach taken in the Kigg framework, and how it seemed to accomplish this for both versions pretty elegantly. The crowd seemed generally cool with this and we moved on, Brian relatively unscathed. No harm, no foul, but I urge (read: plead with) Brian and the rest of the evangelists - don't forget that many of us in the community hinge on most of the things you say. If you tell me it works, I think it works, and when it doesn't work I think it's something I did. When I find out it's something you guys did and that I've wasted many hours trying to make something work that just isn't supposed to work, I want to forget I ever loved coding I get so irritated - nothing plagues a coder like time lost on poor documentation, so just keep doing your best to keep the facts straight. The whole with great power comes great responsibility speech is implied here. 

My favorite moment during the presentation was when Brian talked about the collection of form data in the "new MVC way." He specifically mentioned getting back down to basics and dealing more directly with the Request object. I'm a huge fan of this, and of removing a lot of the gunk between me and my HTTP protocol, so I was all about this commentary. Additionally helpful was his code example demonstrating form-collection using the BindingHelperExtensions class. This has been one of the things I've not yet learned how to do with MVC - dealing with forms. I've been more focused on link-based approaches using MVC and on JSON transmission, so the traditional forms approach had been something that'd eluded me. Brian's example of this was great. 

Brian did mention Phil Haack's ASP.NET Routing Debugger during his presentation, which I'm so downloading tomorrow it's not even funny. Thanks for that, Brian and Phil

Overall, a good presentation. I would like to see a round two of this presentation (or to provide it, as sometimes the requirement of teaching something enables/forces you to learn it pretty well) or to be provided something comperable to Brian's presentation on a more technical, "how-to" level. I look forward to his evolution as a DE, his upcoming travelling show with some of the other guys in his squad, and to learning more about ASP.NET MVC. 

Kick it! | del.icio.us | Comments (4) | Permalink

6/14/2008 12:52:00 AM

ASP.NET MVC, JSON, and Prototype

I've tinkered with the method of posting JSON between the browser and the server via a generic handler. When the new MVC Preview came out and had native support for JSON I knew I needed to do some further tinkering. This post will describe in brief how to perform such a thing. I'll demonstrate how to perform a login process using JSON communication between an MVC Controller's action method which returns a JsonResult instance. Sounds tricky, but that's how Prototype helps us. It makes the communication process pretty easy. I'll try to be pretty short and sweet here and will keep the code discussion to a bare minimum.

Environment Setup 

First and foremost, you'll need to learn the basics of the ASP.NET MVC approach and find the two downloads over at ScottGu's blog post on the topic. That's about the best place to start.  Once you've got everything installed you should create a new MVC project. Add a folder to the Views folder called Login. This is a relatively simple topic that all must implement at some point or another. I'll use the Prototype JavaScript framework for this. So make sure you download Prototype and put it into your web project. Finally, add a reference to the script in your Site.Master page, which should be in the Views/Shared folder. 

Creating the Login Index View and Controller

Within the new Login folder, create an MVC View Content Page named Index.aspx.  This page will contain some HTML code, as you'll see below. This code contains some form elements and some JavaScript code. The JavaScript code is what will perform the duty of packing up the data collected from the form in the structure of a JavaScript object called Login. Once the object is created, it will be shipped over HTTP to the server.

<%@ page title="" language="C#" masterpagefile="~/Views/Shared/Site.Master" autoeventwireup="true" codebehind="Index.aspx.cs" inherits="MvcPreviewThree.Views.Login.Index" %>

<asp:content id="Content1" contentplaceholderid="MainContent" runat="server">
    <div class="row">
        <div class="cell">
            <label for="username">username</label>
            <input type="text" id="username" value="username" />
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <label for="pwd">password</label>
            <input type="password" id="pwd" value="password" />
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <input type="button" id="buttonLogin" value="login" onclick="doLogin();" />
        </div>
    </div>

    <script language="javascript" type="text/javascript">

    var Login = Class.create(
    {
        initialize: function()
        {
            this.Username = $('username').value;
            this.Password = $('pwd').value;
        }
    });

    function doLogin()
    {
        var login = new Login();
        var request = new Ajax.Request('/Login/Authenticate', 
        {
            method: 'post',
            contentType: 'application/json; charset=utf-8',
            postBody: Object.toJSON(login),
            
            onSuccess: function(transport)
            {
                alert(transport.responseText);
            },
            
            onFailure: function()
            {
                alert('fail!');
            }
        });
    }

    </script>

</asp:content>
 

Controlling Things

Take note of the URL in the call to the Ajax.Request constructor. The call is going to be made to /Login/Authenticate. Understanding that step will give you a better comprehension of how the URL's are converted into useful routes on the server to view pages. The first step is to create a Controller class. Since I've created a Views folder named Login, I must create the class useful for controlling all login-related procedures. This class, LoginController, will contain action methods that perform various actions the user will need to execute during the Login routines. The first of these - the Index view - needs to be controlled first. 

public class LoginController : Controller
{
    public ActionResult Index()
    {
        return View();
    }


}
 

This one's pretty obvious - the call to View() will just render the Index view I already created, with the login form and JavaScript call. The next one isn't so obvious and requires a quick glance at some helper methods I've written into a JsonHelper class. This class just makes some of the heavy lifting easier in a moment. The ToJson extension method wouldn't have been possible without a post from ScottGu's blog.

public static class JsonHelper
{
    public static string ToJson(this object target)
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        return ser.Serialize(target);
    }

    public static T FromJson<T>(string json)
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        return ser.Deserialize<T>(json);
    }

    public static T FromJson<T>(Stream stream)
    {
        StreamReader rdr = new StreamReader(stream);
        return FromJson<T>(rdr.ReadToEnd());
    }
}

The last step in our controller class is the actual niftyness of the whole post. Within this method the code takes a peek at the current Request, specifically the incoming JSON string contained within the request's InputStream property. This is where I'll use my JsonHelper class, which makes it a snap to parse an HTTP Request into a JSON object. 

public JsonResult Authenticate()
{
    Login login = JsonHelper.FromJson<Login>(this.Request.InputStream);
    return new JsonResult
    {
        Data = (login.Username == "username" && login.Password == "password")
    };


}

The Final Touch

Last, I'll need to give the user some way of finding the Login's Index view so I'll add a link to the view in the Site.Master file's navigation section.

Once you've done all this you should be able to run the code with success. I'll get around to uploading this sample onto the server so you can see it working in the next few days, but I couldn't wait to share this technique. Using Prototype as a means to communicate with a ASP.NET MVC Controller class' JsonResult methods makes for a powerful combination of tools to build truly rich, interactive applications that run in all modern browsers.

Happy Coding! 

 

Kick it! | del.icio.us | Comments (4) | Permalink

3/28/2008 12:10:00 AM

Woot Watcher - My First ASP.Net MVC App

Like most everyone else in the ASP.Net community I've been dedicating a good deal of time recently to learning more about the ASP.Net MVC implementation. Today, as you may already know, Woot.com is having a woot-off. Given that most of the tools I've found on line for tracking these wonderful events seem to crash I thought I should create my own Woot-monitoring page.

Woot Watcher was inspired by a few simultaneous events. A woot-off was occurring, I was learning the ASP.Net MVC framework, and my finger became cramped beyond control from repeatedly tapping the F5 key. With that I decided I needed to simplify my ability to keep up with what was going on at Woot.com and that the best way to do that would be to use the ASP.Net MVC framework to do it.

So, feel free to check it out. You'll notice it changing frequently until the woot-off is over, then it'll just sort of stay the same each day. I'll try to add some Ajax features, but first I need to learn how the MVC model allows for this. For now, check out Woot Watcher.  

Kick it! | del.icio.us | Comments (2) | Permalink