What's in a controller? That which we call an action…


Recently, fellow MVP and , Jeffrey Palermo blogged a pretty interesting idea called .  Within his post, he states:

My interest in this space is purely practical.  I really don’t care how patterns are published.  I don’t care about “being true” to the MVC pattern or any other pattern.  I’m more interested in being effective with web applications on .Net.  After have experience with MvcContrib, CodeCampServer, and a much larger ASP.NET MVC implementation (200+ screens), I have come to see how controllers end up searching for an identity.  What is a ProductController anyway?  That’s just about as specific as classes called ProductService, ProductManager, ProductUtility, etc.

Jeffrey’s approach is pretty cool if you ask me since it puts a spin on how is implemented. Jeffrey is trying to tackle the design (implementation) of actions within controllers by providing a different perspective on the issue. His approach is actually very similar to what provides within its framework; where an Action is the center all of execution and the controller takes a back seat during the request.

Now, I want to be clear that in no way shape or form, do I have disrespect for what Jeffrey is trying to test. He’s a very talented individual who’s very knowledgeable on the subject and I have the outmost respect for him.

Having said that, I think the following tweet might have been taken out of context:

actioncontroller_tweet

What I meant by going “too far” was with regards to escalation of an action to the level of a controller. Granted, this is a simple spike and could be easily refactored into something leaner.  I totally agree with Jeffrey that the discussion here is about the design of controllers and actions. In particular on how one thinks of controllers within their web application. The approach of the ActionController works extremely well when you mix both application logic as well as ‘request’ logic within your controller.  In other words, your controller knows how to map against the request (http://mydomain.com/home/index) and also performs other logic within the action (interacting with repositories, domain, etc.).

A Little Bit of History…

For me, the approach for the controller is a little different due to my background with J2EE applications.  When I first introduced with MVC, it was around a home grown MVC framework written in Java.  The framework was loosely based around some of the concepts that were presented in the of the .

Our home grown framework consisted of one that handled all requests from the caller.  Once a request was received, it iterated through a list of to either fetch or persist data to the database then it would render the selected view.  Pretty straightforward interaction for all the pieces within the request pipeline.

Other Java MVC frameworks such as and follow a similar approach of defining a DispatcherServlet to handle all requests. Granted Struts handles things more at the action level, while SpringMVC does it at controller level. Which means that

My Approach

Now that you know some of my background, allow me to show you my approach for controllers within my MVC application.  The following source is from my sample MVC application:

namespace Mvc.Controllers
{
    using System.Web.Mvc;
    using Common;
    using Models.Post;
    using Services;

    public class PostController : Controller
    {
        private readonly IPostService postService;
        private readonly ICategoryService categoryService;

        public PostController(IPostService postService, ICategoryService categoryService)
        {
            this.postService = postService;
            this.categoryService = categoryService;
        }

        public ActionResult Index()
        {
            var posts = postService.RetrieveAll();
            var model = posts.ConvertAll(dto => dto.ToViewModel());

            return View(model);
        }

        public ActionResult New()
        {
            var categories = categoryService.RetrieveAll();
            var model = categories.ConvertAll(dto => dto.ToViewModel());

            return View(model);
        }

        public ActionResult Create(PostViewModel post)
        {
            var dto = post.ToDTO();
            postService.Create(dto);

            return RedirectToAction("Index");
        }
    }
}

As you can see in this contrived example, each of my actions are pretty small since all they do is handle the request, in the form of a , then pass the ViewModel to the corresponding service for processing. If the service returns data in the form of , the result is then converted into a ViewModel and passed back to the View.

For my needs, this simple approach works.  Not only that, I’ve also managed to keep the size of my actions pretty small. I’ve used this approach on the , and it worked quite well with multiple Views/ViewModels.  Also, other ASP.NET MVC sample applications such as Nerd Dinner and take a similar approach. Looking outside the ASP.NET MVC world, in this instance , they seem to follow a similar approach for their .

What’s your approach?

author: Javier G. Lozano | posted @ Saturday, June 20, 2009 11:58 PM | Feedback (12)

ASP.NET MVC 1.0


Now, I know a few days late on this blog post.  Granted, at the time, I was doing a webcast on ti! :) Any way, be assured that I’ve already congratulated Phil and team on getting ! To find out more about the intricate details, check out on it (remember, he’s the PM).

Now, during the time I’ve been talking with people about the MVC bits, I’m still surprised that they ask these questions (just to name a few):

  • Are Web Forms going away?
  • How do I convert my Web Forms project to an MVC project?
  • What’s the ramp up time for learning MVC?

All of these are valid questions, and unfortunately, some of them (except for the first one) don’t have a direct answer.  What these questions do tell me that there is still A LOT of education and knowledge that needs to happen within the ASP.NET/MVC community.  The question is not when/how do I move to MVC, but more is the use of MVC right for me/my project?  This is something that can only be answered by you after enough information is gather about your current context and your desired out come.

On a different note, I would like to address a blog post that come up this weekend entitled, .NET MVC vs Ruby on Rails.  I must say that the Simon, the author, does bring up very good points about what MVC looks like to the RoR developer.  In particular, points 3-5.  Now, I’m not going to get into a but I will say that some of us are working hard on point #4.

author: Javier G. Lozano | posted @ Monday, March 23, 2009 10:41 AM | Feedback (2)

Contextual Sessions with NHibernate – Part 2


In my previous post, I talk about how the problem with sessions and NHibernate (NH) can get pretty tricky to deal with; specially within ASP.NET web applications.  This post shows how you can use a pretty nice feature within NH that simplifies this problem.

A Solution

NH supports a mechanism of providing a ‘current’ session via the ISessionFactory.GetCurrentSession method by using a concept called Contextual Sessions.  This is what the NH documentation says about the feature:

Most applications using NHibernate need some form of "contextual" sessions, where a given session is in effect throughout the scope of a given context. However, across applications the definition of what constitutes a context is typically different; and different contexts define different scopes to the notion of current.

Starting with version 1.2, NHibernate added the ISessionFactory.GetCurrentSession() method. The processing behind ISessionFactory.GetCurrentSession() is pluggable. An extension interface (NHibernate.Context.ICurrentSessionContext) and a new configuration parameter (hibernate.current_session_context_class) have been added to allow pluggability of the scope and context of defining current sessions.

See the API documentation for the NHibernate.Context.ICurrentSessionContext interface for a detailed discussion of its contract. It defines a single method, CurrentSession(), by which the implementation is responsible for tracking the current contextual session. Out-of-the-box, NHibernate comes with one implementation of this interface:

  • NHibernate.Context.ManagedWebSessionContext - current sessions are tracked by HttpContext. However, you are responsible to bind and unbind an ISession instance with static methods on this class, it never opens, flushes, or closes an ISession itself.

The hibernate.current_session_context_class configuration parameter defines which NHibernate.Context.ICurrentSessionContext implementation should be used. Typically, the value of this parameter would just name the implementation class to use (including the assembly name); for the out-of-the-box implementation, however, there is a corresponding short name, "managed_web".

As you can see, NH has thought about this problem and has provided a way to make the interaction with ‘current’ sessions, way easier.  With this, the code within your implementation can get can get a little bit cleaner:

   1: namespace Web {
   2:     using System;
   3:     using System.Web;
   4:     using NHibernate.Context;
   5:     using Persistence;
   6:  
   7:     public class ContextualSessionModule : IHttpModule {
   8:  
   9:         public void Init(HttpApplication context) {
  10:             context.BeginRequest += context_BeginRequest;
  11:             context.EndRequest += context_EndRequest;
  12:         }
  13:  
  14:         public void Dispose() {
  15:         }
  16:  
  17:         private static void context_BeginRequest(object sender, EventArgs e) {
  18:             var application = (HttpApplication)sender;
  19:             var context = application.Context;
  20:  
  21:             BindSession(context);
  22:         }
  23:  
  24:         private static void BindSession(HttpContext context) {
  25:             var sessionBuilder = SessionBuilderFactory.CurrentBuilder;
  26:  
  27:             // Create a new session (it's the beginning of the request)
  28:             var session = sessionBuilder.OpenSession();
  29:  
  30:             // Tell NH session context to use it
  31:             ManagedWebSessionContext.Bind(context, session);
  32:         }
  33:  
  34:         private static void context_EndRequest(object sender, EventArgs e) {
  35:             var application = (HttpApplication)sender;
  36:             var context = application.Context;
  37:  
  38:             UnbindSession(context);
  39:         }
  40:  
  41:         private static void UnbindSession(HttpContext context) {
  42:             var sessionBuilder = SessionBuilderFactory.CurrentBuilder;
  43:  
  44:             // Get the default NH session factory
  45:             var factory = sessionBuilder.GetSessionFactory();
  46:  
  47:             // Give it to NH so it can pull the right session
  48:             var session = ManagedWebSessionContext.Unbind(context, factory);
  49:  
  50:             if (session == null) return;
  51:             session.Flush();
  52:             session.Close();
  53:         }
  54:     }
  55: }

Most of ISession management churn is pushed into the Bind and Unbind methods of the ManagedWebSessionContext class.  It’s within the implementation of those methods that storage of the ISession takes place within the HttpContext.Items property.

The biggest added value for this approach is the new implementation of ISessionBuilder, :

   1: namespace Persistence {
   2:     using NHibernate;
   3:  
   4:     public class ContextualSessionBuilder : SessionBuilderBase {
   5:         private static ISession staticSession;
   6:  
   7:         public override ISession CurrentSession {
   8:             get {
   9:                 
  10:                 ISession session;
  11:  
  12:                 try {
  13:  
  14:                     // Get the default SessionFactory
  15:                     var factory = GetSessionFactory();
  16:  
  17:                     //Let NH handle the 'churn' for you
  18:                     session = factory.GetCurrentSession();
  19:  
  20:                     staticSession = null;
  21:                 } catch {
  22:                     //HACK: Here to support the calling of sessions from the HttpApplication start
  23:                     if (staticSession == null) {
  24:                         staticSession = OpenSession();
  25:                     }
  26:  
  27:                     session = staticSession;
  28:                 }
  29:  
  30:                 return session;
  31:             }
  32:         }
  33:     }
  34: }

As you can see, this implementation of ISessionBuilder does not know (or care) about the current HttpContext instance…and why should it?  The concern of SessionBuilder is to abstract all the work related to persistence and not any of the side-effects it might have to put up with.

One important thing to note here is that the only pieces we had to change were out IHttpModule and ISessionBuilder implementations since these two respectively, deal with the persistence mechanism of our application.

Now, we’re pretty close to being done with this feature, but since the next section focuses on how to configure this piece within NH and not your application, I left that piece for another blog post.

For now, Happy Codin’!

author: Javier G. Lozano | posted @ Wednesday, February 18, 2009 4:26 PM | Feedback (2)

Contextual Sessions with NHibernate – Part 1


As with any piece of software development, there is more than a million ways to skin a cat.  Working with NHibernate in a multi-threaded environment is no different. :)  To help with the illustration of the interaction of NHibernate and ASP.NET, I’ve created a sample application out on Google code.  Please feel free to check it out and run it locally.  The only requirement for the sample is to have a local install of SQL Server Express.

The Problem

Those of you using NHibernate in a multi-threaded environment (say ASP.NET) have probably written code to maintains an ISession open for the during of a request (worker thread) so that any component within that request that needs an ISession, can just re-use it.  Typically the solution involves some fancy work with the HttpContext.Items collection by adding and removing sessions from the HttpApplication.BeginRequest and HttpApplication.EndRequest.  All of this code is infrastructure and requires some intimate knowledge of how ASP.NET works.  For all general purposes, your code can be similar to that of CommonSessionModule.cs:

   1: public class CommonSessionModule : IHttpModule {
   2:  
   3:     public void Init(HttpApplication context) {
   4:         context.BeginRequest += context_BeginRequest;
   5:         context.EndRequest += context_EndRequest;
   6:     }
   7:  
   8:     public void Dispose() {
   9:     }
  10:  
  11:     private static void context_BeginRequest(object sender, EventArgs e) {
  12:         var application = (HttpApplication)sender;
  13:         var context = application.Context;
  14:  
  15:         var sessionBuilder = SessionBuilderFactory.CurrentBuilder;
  16:         context.Items[Constants.SessionKey] = sessionBuilder.OpenSession();
  17:     }
  18:  
  19:     private static void context_EndRequest(object sender, EventArgs e) {
  20:         var application = (HttpApplication)sender;
  21:         var context = application.Context;
  22:  
  23:         var session = context.Items[Constants.SessionKey] as ISession;
  24:         if (session != null) {
  25:             session.Flush();
  26:             session.Close();
  27:         }
  28:  
  29:         context.Items[Constants.SessionKey] = null;
  30:     }
  31: }

To make the code simpler to read, I’ve introduced a ISessionBuilder and SessionBuilderFactory to handle the interaction with NHibernate and its pieces. 

As you can see from the sample above, there is quite a lot of churn happening with the Items collection.  We have to intimately know how to add and remove the active ISession (per thread) based on some constant key.  To make matters worse, the implementation of ISessionBuilder needs to know how to pull the ‘current’ ISession out of the Items collections.  The CommonSessionBuilder.cs file shows this type of interaction:

   1: public class CommonSessionBuilder : SessionBuilderBase {
   2:     public override ISession CurrentSession {
   3:         get {
   4:             //Handle the ISession from the context
   5:             var currentContext = HttpContext.Current;
   6:             var session = currentContext.Items[Constants.SessionKey] as ISession;
   7:  
   8:             //HACK: Here to support the calling of sessions from the HttpApplication start                
   9:             if (session == null) {
  10:                 session = OpenSession();
  11:                 currentContext.Items[Constants.SessionKey] = session;
  12:             }
  13:  
  14:             return session;
  15:         }
  16:     }
  17: }

Most of the “common” (Configuration settings, ISessionFactory creation, etc) are part of the SessionBuilderBase class since those pieces are going to be needed regardless the implementation we use for the CurrentSession method.  For this implementation of CurrentSession, we have to pull the current ISession from the Items collection to give it back to the caller of the property (in this instance, the RepositoryBase class):

   1: public class RepositoryBase<TEntity> : ICRUDRepository<TEntity>
   2:     where TEntity : EntityBase, new() {
   3:  
   4:     protected readonly ISessionBuilder _sessionBuilder;
   5:  
   6:     public RepositoryBase(ISessionBuilder sessionFactory) {
   7:         _sessionBuilder = sessionFactory;
   8:     }
   9:  
  10:     #region ICRUDRepository<TEntity> Members
  11:  
  12:     public void Create(TEntity entity) {
  13:         ISession session = GetSession();
  14:         using (ITransaction transaction = session.BeginTransaction()) {
  15:             session.Save(entity);
  16:  
  17:             transaction.Commit();
  18:         }
  19:     }
  20:  
  21:     public TEntity Retrieve(Guid entityId) {
  22:         ISession session = GetSession();
  23:         ICriteria criteria = session.CreateCriteria(typeof(TEntity));
  24:         criteria.Add(Expression.Eq("Id", entityId));
  25:  
  26:         return criteria.UniqueResult<TEntity>();
  27:     }
  28:  
  29:     public IList<TEntity> RetrieveAll() {
  30:         ISession session = GetSession();
  31:         ICriteria targetObjects = session.CreateCriteria(typeof(TEntity));
  32:  
  33:         return targetObjects.List<TEntity>();
  34:     }
  35:  
  36:     public void Update(TEntity entity) {
  37:         ISession session = GetSession();
  38:  
  39:         using (ITransaction transaction = session.BeginTransaction()) {
  40:             session.Update(entity);
  41:  
  42:             transaction.Commit();
  43:         }
  44:     }
  45:  
  46:     public void Delete(TEntity entity) {
  47:         ISession session = GetSession();
  48:         using (ITransaction transaction = session.BeginTransaction()) {
  49:             session.Delete(entity);
  50:  
  51:  
  52:             transaction.Commit();
  53:         }
  54:     }
  55:  
  56:     #endregion
  57:  
  58:     protected ISession GetSession() {
  59:         return _sessionBuilder.CurrentSession;
  60:     }
  61: }

All CRUD methods do a call to the GetSession method which in turn call’s the ISessionBuilder.CurrentSession method to fetch the current ISession instance.  Again, the reason for this indirection is to allow flexibility on the way an ISession is acquired during runtime.  Since it’s not the concern of the RepositoryBase to manage the intricacies of NHibernate, having such approach here keeps the code clean and clear from any unnecessary clutter.  Always a good thing to have! :)

Hopefully by now you’re noticing that this approach doesn’t do a good job at separating concerns for the data layer.  The CommonSessionBuilder class has to have knowledge of a web context, however, it’s sole purpose is to handle pieces for data access.  So, how do we solve this approach and minimize our dependency on the web context?  We use a pretty nice (not so visible) feature of NHibernate called, Contextual Sessions.

I will address Contextual Sessions on a follow up post and show how the code changes by using this pretty awesome feature!

Keep Codin’!

author: Javier G. Lozano | posted @ Tuesday, February 17, 2009 8:56 PM | Feedback (0)

Etixo


As some of you already know, I blogged about from the .  Also, I started to make it a bit more streamlined.  More importantly, I want use these posts as a way to share my ideas on how to use the new .  Not that I am “the source” for the right implementation, but I do want to provide another insight to the problem.  Anywho…

Instead of keeping my source in zip files and bits and pieces, I created a fork of the called (Oxite ALTered).  I know Rob is .  However, he’s taking a different approach to the problem.  He’s refactoring the core of the application and applying more DDD discipline to it.  Don’t get me wrong, that’s totally awesome and he’s doing a great job at it (just like he’s doing with this ). I want to take the utilitarian approach and show how you can refactor the infrastructure of the application to separate concerns. From there, you can always refactor to a DDD foundation.

Another goal I have for this project is to apply some of the concepts and tooling from I did this last year. Hopefully, this can serve as a nice sample for developers that are either stuck with the question “how do I move to MVC from Webforms?” or “how do I use tool X with MVC?”.

If you’re interested in helping out with the refactoring with related MVC content, please let me know. I can give you write access to the source out in Google Code.

Happy Codin’!

author: Javier G. Lozano | posted @ Sunday, January 11, 2009 10:59 PM | Feedback (1)

New Year’s Resolutions


I know, I know…I’m a little late on the resolutions.  But like they say, it’s better late than never!

So, I've been thinking about I want to change/enhance in 2009 for the past couple of weeks.  First I must say that I did achieve my theme for 2008 of Simplicity. However, I did SUCK at the whole “content, content, content” piece given the fact that I only 40+ posts in all of 2008!

So, here’s what I’m going to make up for these pieces ….

Professional Resolutions:

  • Stick with the “simplicity” theme (it’s great!).
  • Start my business.
  • Complete my “product”.
  • Write my online book.
  • Blog at least twice a week.
  • Start (and keep) going with an open source project.

Personal Resolutions:

  • Spend more time with my family (during normal hours).
  • Get in shape (and stay that way).
  • Learn Japanese & Latin.
  • Have more fun

That’s it!  Pretty simple and straight forward, right? :)

author: Javier G. Lozano | posted @ Sunday, January 11, 2009 10:19 PM | Feedback (0)

Views, Models and ViewModels - Part 1


Not sure how many of you read my first post on my thoughts on Oxite. Well, here's my offering on trying to make things a little closer to MVC by offering my perspective on the code.  Please note that I want to keep these simple refactorings as conversational as possible, so if you see something that offends or upsets you with my interpretation/implementation, PLEASE COMMENT. :)

Let's examine the SignIn action under the AccountController:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SignIn(string username, string password, bool rememberMe, string returnUrl)
{
    PageTitle.AdditionalPageTitleSegments = new string[] { "Sign In" };

    if (string.IsNullOrEmpty(username))
        ModelState.AddModelError("username", "You must specify a username.");

    if (string.IsNullOrEmpty(password))
        ModelState.AddModelError("password", "You must specify a password.");

     if (ViewData.ModelState.IsValid)
     {
         IUser user = MembershipRepository.GetUser(username, password);

         if (user != null)
         {
             FormsAuth.SetAuthCookie(username, rememberMe);

             if (!string.IsNullOrEmpty(returnUrl) && returnUrl.StartsWith("/"))
                 return Redirect(returnUrl);
             else
                 return RedirectToRoute("Home");
         }
         else
         {
             ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
         }
     }

     ViewData["rememberMe"] = rememberMe;

     return View();
}

As you can see from here, there is a lot of code within this method that makes it hard to follow/maintain since everything is put jammed together in the body of the action.  Here are some things that we can see immediately: 

  • Form Data Validation
  • Model Validation
  • Route Processing

Essentially, the controller is performing both control logic as well as domain/business logic, which clearly shows that it is violating the Single Responsibility Principal (SRP) and its Separation of Concerns (SoC).

The question here is How do we address these issues? Well, first by taking the a look at the pieces that make up the code and putting them in their correct "location".  To not get overwhelmed, let's first focus on Form Data Validation.

Now, let me first start by saying that Views and Models can be one of the hardest things to grok if you're new to the MV* patterns.  Why?  Well, as developers we sometimes take things too literal which makes things even worse.  So when we hear the words, View and Model we think that there's nothing in between.  Sigh...

So let's start by saying that a View is a representation (or snapshot) of the data that is contained by your Model.  Your Model is the representation of the real-world scenario your application is trying to capture.  Now, the ViewModel is a transformation/projection of the data captured from the View that adhere's to what is expected by the Model.  As you can see, each piece handles JUST one thing.  It shouldn't care what other pieces are doing

Having said that, let's focus on the concept of User Sign In within your application.  First, I will define that the pieces as follows:

  • View - the login screen - text boxes to capture username, password, etc.
  • ViewModel - a CredentialViewModel class - this represents the data from the view so it can be transformed/projected to the Model.
  • Model - a User class - this represents a real-world user in the system

Pretty straight forward, right?  It's about capture, projection and verification.  In my next post, we'll examine how we can refactor the action method and it's parameters into something that's easier to consume and understand.

Keep coding!

author: Javier G. Lozano | posted @ Tuesday, December 23, 2008 10:56 PM | Feedback (0)

Oxite


This past weekend some discussion sprung up around a new blog engine called Oxite.  This blog engine is put out by the MIX Online team and it's used to power their blog.

Now, I'm not going to rehash some of the statements made by other members of the community since there is no point in beating a dead horse.  However, if you want check them out I suggest that first see Rob Conery's thoughts on Oxite as well as Scott Koon with TLC for Oxite post.

The thing I do want to point out is that the team is listening to what the community is saying.  Erik Porter twitted me and Derik Whittaker a reply stating,

@lozanotek @DerikWhittaker Write code and send it in. Maybe upload a patch? We're definitely looking for the right community help!

Unfortunately, the way things are setup with the Microsoft Public License (Ms-PL) and some internal processes, they can't fully accept contributions to the code.  Again, I give the team HUGE kudos for asking for guidance.

As I stated on my comment in Rob's post,

I think one important thing to note is that Oxite serves as a good example of viewing an MVC implementation from a "WebForms state of mind".

So, for those of you coming from the WebForms world, as it currently stands, Oxite shows you some of the basic applications of the MVC framework but with some of the bad habits of WebForms.  By no means, I would call it a real-world example since there is no base for the statement to either prove it or disprove it.  I would say that Oxite is a step on the direction of fully understanding what ASP.NET MVC can provide to your applications.

I will commit to this though, as soon as the project starts accepting contributions, I will be more than happy to lend a hand in their efforts.

author: Javier G. Lozano | posted @ Monday, December 15, 2008 10:07 PM | Feedback (7)

MSDN Unleashed!


Instead of having our regularly scheduled IADNUG meeting, we're having and do an MSDN Unleashed Event at !  Here's the info on it:

Join us at our MSDN Unleashed events for the latest tips, tools and technical information you need to build powerful applications and engaging user experiences. We'll show you how SQL Server 2008 delivers new development capabilities, including support for Spatial Data types, a fresh storage mechanism and more. You'll also learn how to leverage the Silverlight platform to build next generation applications for consumers and business. Don't miss these free, live sessions near you.

Session 1: What's New in SQL Server 2008 for Developers

SQL Server 2008 adds numerous new capabilities for developers – from support for Spatial Data types to a storage mechanism for SQL BLOB data using the NTFS file system, and much, much more. The new release also delivers several improvements to development-related areas, from T-SQL to SQLCLR to XML. This presentation will provide a technical dive into the latest and greatest features you'll find in SQL Server 2008, while offering insight into how effectively apply them to your upcoming development projects.

Session 2: Build next generation applications with Silverlight 2.0

Silverlight provides a powerful platform for building the next generation of rich interactive applications on the Internet. In this session, we'll take a look at the programming model and tools that developers and designers can leverage to build these true next generation experiences for consumers and businesses, and demonstrate how to build a rich interactive application (RIA) using Silverlight and Microsoft.NET. We'll explore how to use Microsoft Visual Studio to create applications, and how to create UI using XAML markup and code, controls, and File I/O.

We'll also discuss networking, how to retrieve data from a Web service, and various other aspects of building Silverlight applications.

WHO SHOULD ATTEND?

Anyone who designs, develops, or debugs code. If you are an architect, developer or just enjoy curly braces, join us.

author: Javier G. Lozano | posted @ Wednesday, November 05, 2008 9:32 AM | Feedback (3)

Microsoft ArcReady


Not sure how many of you know about this upcoming event (tomorrow) 11/06/2008!  If you're going to be around the area, please come check it out!!

ArcReady

Professional Patterns on the Job

You're smart. You deliver. What more could your company want from you?  Why don't they come to you for the big technical decisions? Why won't they listen to your proposals? It seems like everyone has an agenda and they're doing everything they can to kill your great ideas.

Join us this quarter as we focus on the soft skills that architects need to master. Learning these skills will boost your emotional intelligence and help you become a more professional, well rounded contributor. You'll gain insight into the architect's role as leader,influencer, and business professional and learn how to leverage your position to become a positive force within your organization.

Session 1: Mastering the Soft Skills
In this session, we'll discuss key interpersonal skills and how they can affect your projects and career. We cover how to positively connect with humans, how to participate in and influence the business processes you support, and how to transcend your technical role and maximize your connections with all members of your organization.

Session 2: Organizational Dynamics
This session examines the dynamic nature of large organizations – their structures, decision making processes, and political landscapes. We'll discuss the goals of key business and technical decision makers and their influence on architects and software projects. We'll conclude with some strategies for maximizing the soft skills from Session 1 to ensure successful outcomes for your projects and career.

WHAT IS ARCREADY?

  • A forum for aspiring and practicing architects to discuss industry trends
  • An overview of Microsoft's roadmap as it relates to software architecture
  • A mechanism to solicit your feedback
  • An opportunity to showcase the work you do!

WHO SHOULD ATTEND?

Architects and Senior Developers who are interested in becoming an architect.

WHERE ARE THE EVENTS?

Events are held in 19 cities across Central Region.  To register for this event, please visit www.arcready.com.

WHAT TIME ARE THESE EVENTS?

      9:00am – 11:45am

author: Javier G. Lozano | posted @ Wednesday, November 05, 2008 9:27 AM | Feedback (0)

Iowa Code Camp v2!


That's right!  If you're free this Saturday and get to get some free content and a great way to interact with the developer community in Central and Eastern Iowa, come check out the Iowa Code Camp at the DMACC West Campus!

Here's more info:

Iowa .NET and CRIneta.org are hosting the second code camp to Iowa on November 8, 2008 at DMACC West inWest Des Moines.

You might be asking, what's a code camp? Well, here are some of the basic ideas:

  • Community driven
  • High quality
  • Its for and by developers
  • No cost (for attendees)
  • All about code, not PowerPoint presentations
  • Source code and slides must be available to share with people who attend
  • Never during work hours - usually on Saturday

What a code camp is not:

  • Corporate product placement
  • Marketing
  • Powerpoint Centric

Again, if you're free on Saturday, come check us out!

author: Javier G. Lozano | posted @ Tuesday, November 04, 2008 8:43 PM | Feedback (0)

Not At PDC - Presentation Content


Well, better late than never!

For those of you that attended my two talks for Not At PDC, a big thanks!  My apologies for rushing some of the content, but I under estimated my ability to squeeze the content into an hour!

For those of you wondering about where the content lives, please go to: http://jglozano.googlecode.com/svn/trunk/presentations.  Again, you'll need to use TortoiseSVN to check out the content.

If you have any questions,comments, ideas or would like to talk about software in general, please feel free to contact me!

author: Javier G. Lozano | posted @ Saturday, November 01, 2008 9:58 PM | Feedback (1)

Not At PDC


Can't make it to the Professional Developer's Conference (PDC) in LA?  Well, we've started a new group called NotAtPDC!  Chris Love is the genious behind this movement! Here's some info from him:

We are going to have live meeting sessions, links to Blogs, Podcasts and any other .NET related content featured this week. Right now we are trying to get things organized better. We will have a site live in the morning. If you want to schedule a session or something DM http://twitter.com/NotAtPDC.

Chris is in the process on getting a website up to aggregate some of the content that the community is sharing. If you want to join the facebook group, go here.

If you're interested in this movement, come join the fun!

author: Javier G. Lozano | posted @ Sunday, October 26, 2008 8:33 PM | Feedback (0)

Visual Studio Templates for MVC Views without Codebehind Files


For those of you doing MVC out there you've probably noticed that every time you create a new view within your project, the template that VS uses creates a both a .aspx.cs and a .aspx.designer.cs file for your view.  A group of mvps/insiders have been talking about this topic for a bit.  A small group of us feel that providing this file is a temptation that can lead to world of hurt.

To us, the this code behind file is a honeypot asking for bad practices.  The fact that you have a codebehind file and that you can put ANY type of code within it, easily negate the fact that you're using MVC.  Why?  A developer can easily put non-view code within this file, after all it is the codebehind for a webform.  Non-view specific code can range from db connections, LINQ queries, or even worse web service calls.  Fellow Insider/MVP Steven Smith had an excellent blog post entitled,

So Rule of Thumb #1 for ASP.NET MVC, DO NOT USE COBEHIND FILES IF YOU'RE USING THE WEBFORM VIEW ENGINE.

Having said that, you'll need tooling support to prevent you from going into these wicked ways.  So, what I've taken the liberty to change the ItemTemplates that ship with MVC Beta 1 and changed them to prevent the creation of a code behind for both Views and Master pages.  To get these templates, go to:

Here's what you need to do:

  • Make sure that VS is not loaded
  • For the item template zip files
      • MvcViewContentPageItemTemplateBeta.cs.zip
      • MvcViewMasterPageItemTemplateBeta.cs.zip
      • MvcViewPageItemTemplate.cs.zip
      • MvcViewPageItemTemplateBeta.cs.zip
    • Copy these files to these locations:
      • C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC\103
      • C:\Program Files\Microsoft ASP.NET\ASP.NET MVC Beta\Temp

 

  • For the itemtemplatecache_folders.zip file
    • Extract the contents (should be 4 folders of the previous 4 item template zip files).
    • Copy these folders to:
      • C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplatesCache\CSharp\Web\MVC\1033

After you've completed these steps you can get a codebehind-less MVC View within your project from these dialogs:

image

New Add View Dialog

image

Add New Item Dialog

If you have any questions or need help installing these new templates, please feel free to leave a comment!

author: Javier G. Lozano | posted @ Monday, October 20, 2008 4:23 PM | Feedback (9)

Thanks, VSLive Las Vegas and HDC Omaha '08!


For those of you that attended one or both at of my talks at VSLive Las Vegas or HDC Omaha 2008, I just want to say, thank you!  And for the VSLive folks, I do apologize for cutting my open source tools talk short by 10 minutes.  I had to jet out of the Mirage so I can make the plane back to the Midwest!

As promised, I upgraded my code to run with Beta 1 of the ASP.NET MVC Framework!  So, if you want to get the latest bits go to:

You will find my slide deck as well as all the necessary pieces to run my demos.  Please note that for the YABE and NHibernate demo you need SQL Server.

Again, thanks for taking the time to come listen to me.  If you have any questions for concerns don't hesitate to contact me: javier-at-lozanotek-dot-com or http://twitter.com/lozanotek

author: Javier G. Lozano | posted @ Sunday, October 19, 2008 7:05 PM | Feedback (0)

VSLive! NY and HDC Minneapolis Talks


Yeah, I know...been really, really quiet here.  Reason?  Busy with work, work and life.  Going to try to get back into the "frequent blogging" mood, I promise!!

Any way, for those of you that attended my talks at VSLive NY! and HDC Minneapolis, I just want to say, "Thanks!!"  The code as been updated slightly to help clarify some of the interactions between the different projects (and logic).  So, go check out the latest bits at   Please note that the PPT deck is also in that location for you guys to get.

Again, thanks for coming to the talks and I hope you enjoyed the material!

author: Javier G. Lozano | posted @ Thursday, October 02, 2008 8:05 PM | Feedback (0)

ASPInsiders Summit 2008


Last week I attended the Summit at the .  I must say that by Wednesday afternoon my head was ready to explode with the amount of content that I, along with another Insiders, parsed through!!  However, it was a great opportunity to provide feedback the teams that make up the ASP.NET Team.

Over all, it was a great way to experience the process in which MS takes customers feedback and prioritizes features for their products.  Sure, we all build products, but I must say that we don't do it at the scale that Microsoft does.  The impressive thing about this is the size of the team!  Now, I don't know the exact number but from the looks of it from the people coming in and out, the team is about ~30 people.  Pretty impressive number for such an awesome platform!

Now, I can't say much about what was discussed (since most of it is under NDA), but I can say this: The team is very passionate about delivering a great product and customer experience.  Every time you spoke with a member of the team, they were very attentive and always asked the "What would you like out of the product?" and "How would you do it?"...pretty awesome.

I must say that the highlights of the trip was spending time with the team (both framework and tooling) and get to know them both as individuals and peers.  Sure we talked shop, and lots and lots of it, but it was nice to hear about their personal lives for a change.  Now, the one thing I will say (over a series of more blog posts) is that I was enlightened on the perception that over ASP.NET developers have about the new MVC framework.  The main thing I hear from the group was "explain to me why/how..."  Now, all of these are valid questions anybody exploring a new technology/approach should always ask.  The interesting thing about these lines of questions is that it shows that we've (those proponents of MVC) have not been doing a good enough job explaining the .  From my point of view, this is totally our fault for focusing on the specifics rather than the abstractions.  This is something that I know was realized by the MVC Mafia (thanks for coming up the name!) and that we're working on changing.  So stay tuned!

Any way, back to the post...

As I said, it was a real pleasure for me to be a part of this summit.  I met a lot really cool people and I must say that I can't wait until Insiders09.  Also, I would like to thank those involved in putting it together, particularly !  You guys just rocked the event!!

author: Javier G. Lozano | posted @ Saturday, July 26, 2008 6:18 PM | Feedback (0)

267F Days Old


Wow, I can't believe I've added another 16D days to the stack...although at times it feels like 1DF1.  For you geeks out there, here's another representation of the day count:

  • Octal - 23177
  • Octal (byte) - 177
  • Binary - 10011001111111
  • Binary (byte) - 1111111

Well, now thinking about it...I'm actually only 267E days old since the day is not over yet.

Anyway, here's to good times (and hopefully more to come)!

author: Javier G. Lozano | posted @ Friday, July 04, 2008 4:00 PM | Feedback (1)

How did you get started in software development?


Well, I was tagged by Jeff earlier to talk about how I got started in software.  So, here's my stab at answering these questions...

How old were you when you started programming?

I was either 11/12 years old.  I got into it a little late since, well, I never had access to a computer when I was living in Mexico.  I knew what they were and I was intrigued by them, but to ask my parents to get me one was completely a ludicrous idea since they were 10x more expensive in Mexico.

What was your first language?

Apple BASIC and QBASIC

What was the first real program you wrote?

This answer all depends on how you define "real" program.  I wrote a pretty wicked "lemonade stand" game in Apple BASIC that would render the stand, a glass filling up with lemonade and the face of a happy customer.  I spent close to a month working on the "graphics" since I had draw them on a piece of paper with a grid to lay out the blocks that made up the images.  Oh the joyfulness of 10 PRINT "DO YOU WANT TO BUY SOME LEMONADE?"

The first "paid gig" was working on VB4 code on Win95 for a company that wrote software for utility companies.  The money I got paid there beat what I made on my paper route BY FAR.

If you knew then what you know now, would you have started programming?

Yes, totally.

If there is one thing you learned along the way that you would tell new developers, what would it be?

Make sure you do things with passion.  Even in your darkest day during the job, passion the thing that keeps you motivated and going forward.  Everything else (architecture, designs, practices, etc) is superficial.

What's the most fun you've ever had ... programming?

That's a though one 'cause there are so many different things that affect the "level of fun".  I would say that my most enjoyable times are either when a client or colleague has that "Eureka!" expression on their face when you work with them on a problem. That's always a sign that you've done your job correctly; specially when building business software.

Who am I calling out?

Nick Parker

Derik Whittaker

D'Arcy Lussier

Chris Sutton

author: Javier G. Lozano | posted @ Monday, June 23, 2008 4:06 PM | Feedback (1)

IronRuby Runs Rails!


Great job to the IronRuby team on getting !

IronRuby running unmodified Rails!

This just freakin' rocks!

author: Javier G. Lozano | posted @ Wednesday, May 28, 2008 7:00 PM | Feedback (11)

Spaghetti Code Podcast - Ruby, RoR and ASP.NET MVC


A couple of weeks back, I recorded a podcast with, our community MS Developer Evangelist, Jeff Brand for his .  I was informed by Jeff, today that he finally !  I had a heck of a time recording this podcast with Jeff, the hour just flew by!  If yo have the time, download the podcast and check it out!

Links:

author: Javier G. Lozano | posted @ Tuesday, May 27, 2008 9:00 PM | Feedback (1)

New Wrox Title: ASP.NET 3.5 Programmer's Reference


So, here's a little shameless self plug for a book that and I are writing...also, I'm using this blog post as a warm up for my writing this evening!

Yes, like I just mentioned, I'm co-authoring a book for with Bryan entitled, ASP.NET 3.5 Programmer's Reference.  The purpose of the book is to get you the novice/beginner introduced to the features of ASP.NET 3.5, and hopefully teach you a few tricks things along the way.  The book is due out in November, so that means that my summer (evenings) is pretty much booked up.  I must confess that Bryan is writing more than half (3-4 chapters more) of this 36 chapter venture.

So at this point, you might be wondering, why are you writing a book?  Well, I figured it might be fun and the mean time, I can help Bryan out with the title.  That's pretty much it!  I've always wanted to experience the writing of a book, so when Bryan presented this opportunity to me, I felt I was up to the challenge.

To help me manage the writing process, I've setup a project at so I can keep track of milestones, tasks and, of course, source code.

I will keep blogging about the progress of the book and let you guys know what sort of things I run into!  Stay tuned!

author: Javier G. Lozano | posted @ Tuesday, May 13, 2008 11:21 PM | Feedback (7)

How do we define community?


During lunch on Tuesday of this past week, raised an interesting discussion point by saying that he rarely sees MVPs that are enterprisie ... by that, MVPs that actually work for (day to day) for an enterprise).  Granted, he used to be one himself back when he worked for .  But as we looked around the group you could see that we were all trying to recollect if we knew of any other MVPs that are enterprisie.  Sadly, we didn't.

Now, the point of that discussion was not say that people in the enterprise cannot be MVPs, it is more to find out the reasons why there isn't a community of enterprisie developers.  We started to talk about some reasons as why people wouldn't/couldn't be members of a community.  Here's an example of these reasons:

  • Not having too much free time -- people do have lives outside work
  • Shutting off when the bell rings -- again, people do have lives outside work and IT
  • Not caring -- people go to work to just collect a paycheck
  • No valid channels to provide support/feedback -- do the forces behind the enterprise care about talking with other enterprises?

We explored some of these (and others) in somewhat detail to see if we could get a sense of the problem.  Later that evening during our product dinner, I posed the same question to my members of our table to see if we could get a different perspective. 

So now, I ask you, my three readers, are there channels or ways to reach to people in the enterprise?  If so, is there a problem with providing greater reach?  And if not, how can we create such channels?

If you work in the enterprise, I would love to hear your thoughts on this!

author: Javier G. Lozano | posted @ Monday, April 21, 2008 7:28 PM | Feedback (11)

MVP Summit Highlights


Well, I had a great time meeting old friends and making new ones at this year's summit.  There were so many things going on and so many people to see and talk to, that it's next to impossible to consume everything at once!  So, to keep things simple, here are of the highlights per day:

Sunday

Although, I was not there until late (way late), it was a lot fun hanging around the Westin's lobby and talk about how a chicken takes a dookie.  Yeah, that's right.  Keith Elder had the great intentions of recording a podcast that quickly degraded into different implementations of ICanLayEgg and ICanPoo.  Yeah, needless to say you had to be there.

Monday

By the far the impromptu IronRuby open space was the best!  Had a pretty small group (10+/-) of people talking about .  You knew you were in for a treat when asked, "Tell us where we suck."  From there the conversation turned into the number of specs needed to get IronRuby fully running and talking about getting RoR up and running by .  Great stuff!  Also, I had the please of finally meeting and talk about !  Jimmy had some great insights on his side project called Silverlight on Rails. The concept made my mind explode!!

Tuesday

I had a great time at the product dinner!  I sat next to my new MVP Lead, Suzanna Moran, , and .  We talked about how we define community, and how we can build community and of course, ASP.NET MVC!  The fun really begun when and I created the "Butch" an open source drink for the product dinner.  The drink for those of you wondering, is 1 part vodka, 1 part ice and 1 part citrus juices (lemon, limes, etc.) and 1 part grenadine.  The reason why its called the "Butch" is because it's both pink and manly at the same time since it's made with Beefeater Vodka.  Yeah...again, you had to be there!

From there, I had the pleasure of meeting ScottGu! I must say that it was pretty awesome moment  (yes, I sound like a little school girl). I thanked him for the work him and his team are doing to pushing out the best content and tools for .net developers.  I think the moment where I passed out during the our conversation was when he told me that he reads my blog and really likes the content.  The next thing I knew, I was at the Westin lobby standing next to .  Totally surreal.

At this time, it's close to 11 PM and the night is just staring.  From the Westin lobby, I wonder off to bar/restaurant place called The Palace where I had a few beers with , , , and .  I sat next to Jon and had a great time talking to him about his adventures with and developing .

Wednesday

By far both of the dynamic language sessions, "Why I Py?"  with Harry Pierson and "IronRuby" with John were pretty awesome.  After listening to Harry's talk, I should realized that I should give python more of a chance.  The only thing that I do not like about python is the requirement to use space as a scope boundary...that's it.  I know, I should stop whining and give it a chance.  Also, talking with Scott Bellware and Phil Haack about from IronRuby to CLR types was pretty cool.

The attendee party was pretty great too!  It was funny to see my wife get up and sing with 's wife.  Also, listening to sing and Keith was pretty awesome too.

Heading Home

Unfortunately, I left on Thursday morning so I was unable to make the rest of the festivities along with the ALT.NET Conference.  In all, I had a great time with everyone and look forward to the rest of the year and next year's summit!

author: Javier G. Lozano | posted @ Sunday, April 20, 2008 11:08 AM | Feedback (4)

Laptop Skin


I've been looking into getting a laptop skin for my for some time now.  I've been trying to find something I like and have tossed the idea of creating my own with the (I still might do this one!).  The one to me that seemed the coolest (and the one that people might know more) is an art piece called by .  Here's what the art work looks like:

The_Great_Wave_off_Kanagawa

While returning a movie over at at , I bumped into the and decided to get it.  Here's what it looks like (from their website):

Pretty cool, huh?

author: Javier G. Lozano | posted @ Friday, April 18, 2008 10:24 PM | Feedback (5)