BusinessRx Community

Dedicated to the advancement of software, technology and the people who devote their lives to it.

Welcome to BusinessRx Community Sign in | Join | Help
in Search

BusinessRx Reading List

These blog entries are written by industry experts and leaders. We consider this content to be a good read for any software developer or web technologist.

December 2007 - Posts

  • January MSDN Toolbox Column Online

    The January MSDN Magazine is now available online and includes the first of three Toolbox columns that I wrote (filling in for Scott Mitchell). I wanted to focus on open source tools and agile books as much as possible during this opportunity so for the first column I featured:

    • MbUnit - Which I have been a fan of for quite some time.
    • Rhino.Mocks - The best of the .NET mock frameworks in my opinion.
    • dotTrace - The one commercial tool for this column, and one of the few commercial tools that I swear by.
    • Continuous Integration - Cool to see a book focused just on CI, and from AW Fowler series to boot.

    Already saw some good feedback on the column, would love to hear what you think.

    -James

  • New Job with McKesson and Other News

    Its been a very long time since my last post, but here I am again at last.  I just started a new job with McKesson this week as an ASP.NET Architect, where I'll be working on internal tools to support sales and marketing.  McKesson is currently 18th on the Fortune 50 list, being the largest health-care company, and I'll be working in their Alpharetta, GA, office.  I'm very excited about this change, both for the short-run and long-term, and I'm calling this a birthday present to myself since I just turned 40.  I still believe Mimsware to be the best Atlanta-based consulting company, and I highly recommend them, but I decided I wanted a more permanent role.  And McKesson isn't just any company -- they are also big enough that I can make a career with them and still find opportunity for change if I desire.  Its also a pleasant drive for me, taking back-roads from Woodstock, GA, although its a big change for myself and my family to not work from home.

    So that explains this post, but what have I been doing since the last one?  I suppose the easiest explanation is to simply say that I've been living!  My focus has very much been my family, and much less on being a tech guru, which was only a coincidence due to having lots of time a few years ago.  My wife Jenny is still cancer-free, and now reconstructive surgery is done, but earlier this year there was a tough time dealing with a reconstructive surgery that didn't heal which led to a much bigger surgery than expected.  But she's fine now and back at her job as a nurse in a cardiac cath lab.  Meanwhile, my kids are growing -- Tori is 10 and still enjoys dancing, while Zack is 9 and enjoys video games, and both stay busy with friends.  We also got a Wii, which is finally a game system we all can play together -- and I count it as real exercise in air-conditioning with no allergens!  I got Mario and Sonic Olympics for my birthday and even got a little sore.

    So what about the latest MS technology and my own endeavors like my O/RM?  I never set out to spend time on forums or to create a popular O/R Mapper -- I simply had a lot of free time several years back that I used wisely.  I love learning new technology, and I like to build something real that is useful to myself as part of that process, which is how it all started out.  I then discovered that others also found things I did very useful, which encouraged me to do even more, but then my O/RM took on a life of its own.  I found that I was no longer just learning or making something for myself, instead I was adding features for others and doing a lot of support also.  So Brian DeMarzo has taken my O/RM open source, and I'm just going to once again play with the latest MS stuff, like Linq to Sql and MVC for ASP.NET.  I may yet build something I think is useful enough to share with others, or at least learn enough for a new post, but if I don't then that's OK too.

  • LINQ and the DTO Tax

    Jean-Paul Boodhoo's post on MappingEnumerable<T> reminds me how DTOs sometimes require an inordinate amount of effort for the simple jobs they perform. You need to define them, instantiate them, map them, groom them, and take them for walks twice a day. It always felt to me that the language should help to reduce the DTO tax, somehow.

    In JP's post, he is using the following interface to define a mapper responsible for transforming domain objects into data transfer objects (screen bound DTOs, I'm assuming).

    public interface IMapper<Input, Output>
    {
        Output MapFrom(Input input);
    }

    Where a simple implementation might look like:

    public class DepartmentMapper : IMapper<Department, DepartmentDisplayItemDTO>
    {
        
    public DepartmentDisplayItemDTO MapFrom(Department input)
        {
            
    return new DepartmentDisplayItemDTO()
                {
                    ID = input.ID,
                    Name = input.Name
                };
        }
    }

    LINQ takes some of the grunge work out of mapping DTOs. For example, if you aren't injecting a mapping strategy at runtime, LINQ can transform a Department object into a Department DTO in place:

    IEnumerable<Department> departments = departmentRepository.GetAllDepartments();
     
    return
        from d in departments
       
    select new DepartmentDisplayItemDTO() { ID = d.ID, Name = d.Name };

    Alternatively, when there is a mapper in play for more convoluted mapping logic:

    IEnumerable<Department> departments = departmentRepository.GetAllDepartments();
    return
      from d in departments
     
    select departmentDisplayItemDTOMapper.MapFrom(d);

    ... which is equivalent to:

    IEnumerable<Department> departments = departmentRepository.GetAllDepartments();

    return departments.Select(d => departmentDisplayItemDTOMapper.MapFrom(d));

    I think LINQ eliminates the need for JP's MappingEnumerable<T> (a DTO tax), while keeping the advantage of deferred execution (an item isn't mapped until it is enumerated).

  • Creating Silverlight Player Templates

    Pete Brown is a local guy with a great deal of Silverlight content on his blog, and some cool wallpaper downloads. Pete pointed to the Expression Encoder White Paper today. The document describes itself as providing the "best practices and methods for providing integrated and branded media player skins for Microsoft Silverlight".

    After a quick read, I'd say the document does a fine job describing how to build custom skins and templates for the Silverlight media player. The techniques described in the document will also work with the ASP.NET Futures <asp:Media> control. Both of those controls provide additional features (like the standard VCR controls) on top of the Silverlight <MediaElement/>.

    The document gets confusing, however, when it describes the class hierarchy behind the player. For instance:

    _Button

    Players generally require buttons. This is javascript functionality bound to XAML elements and handles mouse events and animations.

    The _Button class handles binding the events and animations to the XAML. The intention is for you to handle the events you are interested in.

    See the example above in "Roll your own controls" for details on how to implement your own buttons making use of _Button.

    Cognitive dissonance comes into play several times in the document when the text describes how to consume underscored type like _Button. By convention, ASP.NET AJAX prefixes private fields, methods, and types with an underscore. When adding a new button to the player that is not one of the "well known" buttons (like the PlayPauseButton), it feels like a hack to instantiate or derive from an underscored class.

    Personally, I've been a bit frustrated at the lack of extensibility in the player control provided by Expression. There are no public methods available to override the behavior of the Next, Previous, and VideoWindow button clicks, for example. I hope the ASP.NET Futures version of the control will flesh itself out a little more in the future.

  • Update on 22books

    I launched 22books six days ago now and wanted to blog a brief update. So far I have been pretty happy with the response, most people have complimented the UI, and most importantly lots of people have told how easy it is use. I submitted the site to a handful of web application directory style sites and blogs and that has driven a little bit of traffic, right around 2,500 visits. I plan on doing a post about what has worked and what hasn't from the promotion stand-point.

    I just pushed out an update to the site that allows you to assign a category to your list (like favorites, author list, etc). One of the categories was inspired by Ben Carey who created a list called "Books that change my life". Another user followed his example and I really liked the idea so I wanted to encourage more people to do it.

    I have a many more features planned (and need to update the site to Rails 2.0), but I am going to take some time off for the holidays (although I might work some after Christmas).

    -James

  • Disabling the Submit Button Until a CheckBox is Checked

    A little over a year ago I created two ASP.NET validation controls that are missing from the ASP.NET Toolbox: CheckBoxValidator and CheckBoxListValidator. As their names imply, these validation controls validate a single CheckBox (ensuring its either checked or unchecked, depending on a property setting) and ensures that a specified minimum number of options are checked from a CheckBoxList. For some reason, the built-in ASP.NET validation controls do not validate against CheckBoxes.

    I recently updated the CheckBoxValidator control so that a page developer can optionally associate a Button, LinkButton, or ImageButton with the validator. In such a case, the CheckBoxValidator injects client-side script so that the associated button is disabled when the CheckBox is in the inappropriate check state, and enabled otherwise. The following screen shot illustrates this concept. On the left, the CheckBox is unchecked so the Submit button is grayed out; on the right, the CheckBox has been checked so the Button has become enabled.

    You can read more about this enhancement at Disabling the Submit Button Until a CheckBox is Checked. The complete source code and a simple working demo is available here.

  • Inheritance and the Entity Framework

    Here is an excerpt of the schema for the top level of OdeToCode:

    The Community_ContentPages table carries all of the data needed by every type of content – like moderation flags, published date, and owner ID. Community_Articles carries just the extra information needed for a published article – like the article text itself.

    Inside the code, Article and Book classes derive from ContentPage. Inheritance simplifies the implementation, because a great deal of the business logic applies to all the different types of content objects. For instance, the moderation and approval rules apply to articles, book reviews, comments, images, and other entities that all derive from ContentPage.

    Mapping to Objects

    Inheritance mapping is one good litmus test for the capabilities of an ORM product. LINQ to SQL, for example, only handles one of the three common strategies for modeling inheritance in an RDBMS – the "table per class hierarchy" strategy, which doesn't help me in this scenario. Most full featured OR/M products, like NHibernate, support multiple strategies, including the "table per subclass" strategy I need.

    The Entity Framework documentation includes some pointers on table per subclass mapping (known as "table per type" or TPT in EF terminology). Although the EF designer is easy for getting tables and columns spit out into a mapping file, I found working with the designer a bit tedious. Trying to model inheritance using the designer created build errors, so I did most of the XML editing by hand. The key to TPT mapping is:

    • Use a BaseType attribute when defining EntityTypes in the conceptual schema.
    • Define a single Key column only on the base EntityType in the conceptual schema.
    • In the mapping specification, combine the EntityTypeMapping tags for all derived types into a single EntitySet:
    <EntityContainerMapping StorageEntityContainer="dbo"
              
    CdmEntityContainer="OdeToCodeEntityContext">
      <EntitySetMapping Name="ContentPages">
        <EntityTypeMapping
              
    TypeName="IsTypeOf(OdeToCode.Core.Entities.ContentPage)">
          ...
        
    </EntityTypeMapping>
        <EntityTypeMapping
              
    TypeName="IsTypeOf(OdeToCode.Core.Entities.Article)">
          ...
        
    </EntityTypeMapping>
      </EntitySetMapping>
    </
    EntityContainerMapping>


    Querying

    Once the XML work is done, it's relatively easy to pull out persisted entities.

    Given the following DTO:

    public class ArticleSummary
    {
        
    public int ID { get; set; }
        
    public string Title { get; set; }
    }

    I can use the following LINQ query to pull out only Article objects. The trick is the OfType() operator:

    IQueryable<ArticleSummary> articles =
       
    from article in context.ContentPages.OfType<Article>()
       
    select new ArticleSummary { ID = article.ID,
                                    Title = article.contentPage_title };

    Although I still have some reservations about EF, I'm warming up to the framework...

    *If the naming convention strikes you as odd, then remember the schema was designed to work in a shared hosting environment where a single database might need to support multiple applications. The Community prefix helps to avoid naming collisions. An equivalent design today could use schemas in SQL 2005.

  • December 16th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, VS, .NET, IIS7, WPF

    Here is the latest in my link-listing series.  Also check out my ASP.NET Tips, Tricks and Tutorials page for links to popular articles I've done myself in the past.

    ASP.NET

    ASP.NET AJAX

    ASP.NET MVC

    • PagedList<T> Support: Rob Conery posts a sample implementation of a pageable List<T> implementation that I showed in my original ASP.NET MVC demo at the Alt.net conference.

    Visual Studio

    • Spell Checker for Visual Studio: My team recently shipped a cool new Visual Studio add-in that provides spell checking support.  In addition to supporting spell checking within HTML files, it also supports spell checking within JavaScript, VB, C# and ASP.NET comments.  Works with both VS 2005 and VS 2008.

    • World of Warcraft for Visual Studio: A cool new add-on that enables support for building World of Warcraft game extensions using Visual Studio.  Definitely something to check out if you play World of Warcraft.

    • VS 2008 Color Schemes: Thomas Restrepo has posted some nice Visual Studio color scheme templates you can use to customize your text editor settings.

    Debugging .NET

    • Getting Started with WinDBG Par1 and Part2: Johan Berglin has an excellent set of posts that detail how you can use the WinDBG debugger to drill into a running ASP.NET application and analyze it to see what it is doing.  Microsoft Product Support uses this tool when helping debug deployed applications in production.  It is extremely powerful and something you might want to learn.

    • Automated .NET Hang Analysis: Tess Ferrandez from the ASP.NET Product Support team has a great blog post that describes an automated hang analysis tool she has written that uses WinDBG to pinpoint the root cause of common hangs with .NET applications.  Her blog is an excellent one to subscribe to - and is full of great debugging tips and tricks.

    IIS 7.0

    • Behavior Changes for ASP.NET applications running in Integrated Mode on IIS 7.0: Mike Volodarsky from the IIS team has a great blog post that details behavior changes for ASP.NET applications when they run in "integrated mode" on IIS 7.  "Integrated mode" enables ASP.NET developers to take advantage of much tighter integration with IIS - and enables a host of additional scenarios (richer URL rewriting, integrated authentication/authorization, etc).  If one of the behavior changes listed in Mike's document impacts your application, you can optionally change the application to run in "Classic Mode" - which maintains the same ASP.NET behavior as with IIS6.

    • Professional IIS 7 and ASP.NET Integrated Programming: Shahram Khosravi has recently written a great new book that describes how to take advantage of the new IIS7 "integrated mode" features with ASP.NET.  A great book to read if you are looking to take advantage of the new IIS7 features:

    WPF

    Hope this helps,

    Scott

    • New ASP.NET Dynamic Data Support

      The ASP.NET 3.5 Extensions CTP we shipped this past weekend contains a bunch of great new features.

      One of the cool new features is something we call "ASP.NET Dynamic Data Support".  In a nutshell this enables you to really quickly build data driven web-sites that work against a LINQ to SQL (and in the future LINQ to Entities) object model - and optionally allows you to-do this without having to build any pages manually.

      The best way to see this in action is to watch David Ebbo's awesome 17 minute screen-cast:

      You can also follow the steps below to easily get started and use the dynamic data support:

      Step 1: Create a ASP.NET Dynamic Data Site:

      Once you have the ASP.NET 3.5 Extensions CTP release installed, you can use VS 2008 or the free Visual Web Developer 2008 Express to create a new Web Site or Web Application Project that has the ASP.NET dynamic data support enabled:

      This will create a new web-site you can use that has some default template files in them, along with CSS style-sheets you can use to customize the look and feel of them:

      Step 2: Add a LINQ to SQL Data Model to Your Site

      LINQ to SQL is an O/RM (object relational mapper) that ships in .NET 3.5, and which allows you to model a relational database using .NET classes.  You can then query the database using LINQ, as well as update/insert/delete data from it.  LINQ to SQL fully supports transactions, views, and stored procedures.  It also provides an easy way to integrate data validation and business logic rules into your data model.

      The easiest way to get started with an ASP.NET Dynamic Data site is to add a new LINQ to SQL data model to your project (right-click->add new item->LINQ to SQL Classes item).  This will bring up the LINQ to SQL class designer.  Drag database tables from your server explorer to define a set of classes (with relationships) for your database schema:

      Step 3: Enable Dynamic Templates in Your Project:

      By default ASP.NET Dynamic Data projects provide built-in support for creating automatic "scaffolding" views of your LINQ to SQL and LINQ to Entities data models.  Dynamic Data projects include template pages and user controls that can automatically create built-in data browsing/editing/selection/deleting UI that is dynamically constructed at runtime based on the LINQ to SQL or LINQ to Entities data model you've added to your project.

      To enable this auto-scaffolding support, open the web.config file of your project, search for the "dynamicData" section within it, and set the "enableTemplates" attribute to "true":

      Note: this auto-scaffolding feature is currently turned off by default for security reasons (we want you to be explicit about turning it on). 

      Note: as you can see above, the ASP.NET dynamic data section provides optional URL mapping support that allows you to customize the URLs for your dynamic scaffold pages to be in whatever URL format you want.

      Step 4: Run Your Site

      Hit F5 to run your project.  You'll by default be taken to a default.aspx page that lists all of the table objects in your data model:

      Note: the default.aspx home-page is in the project - if you don't like how it looks just open it up and edit it however you want.

      Clicking on any of the table names in the list above will take you to a dynamic data page that lists the data within it:

      The default data view pages automatically create functional data navigation UI that includes built-in data paging and editing support (and are ASP.NET AJAX enabled):

      The data view pages automatically infer relationships between your related objects and provide automatic filtering support:

      The data view pages also automatically show relationships between your objects and allow users to easily navigate amongst them.  For example, notice how the Category column for products allows me to navigate to the category details for a specific product:

      The data view pages also enable automatic selection, editing and delete support.  Notice below how when in inline edit mode they automatically infer friendly foreign key names (allowing you to edit the "Category" and pick a name from a dropdownlist instead of having to specify a "CategoryID" integer):

      All of this works without having to create a single custom .aspx page or write any custom code.  All of the web UI is created dynamically off of your LINQ to SQL or LINQ to Entities data model.

      Step 5: Customizing the Site Further

      Having all of the above functionality work out of the box against your ORM data model is great for quickly getting your site up and running.  Once you get the basic site experience working, you can optionally go in and fully customize it - both at the data validation/business logic level as well as at the UI layer.

      You can add standard LINQ to SQL data model and business validation rules to your data model in order to enforce constraints.  The dynamic data pages will automatically work off of this logic, and provide appropriate error messages and validation UI based on them. 

      You can also optionally go in and customize the UI of any of the data pages you want.  Dynamic data projects allow you to customize the default look and feel of all data pages on the site, as well as customize the default look and feel of all column types used on the site.  You can customize both of these via the default template files added under the "/App_Shared" folder when you create a new dynamic data project:

      Simply edit any of the files above to customize the default data page views and/or default data column appearances. 

      You can also then optionally override the UI of specific data view pages by explicitly adding a .aspx page that maps to it in your project.  For example, I could override the default ListDetails behavior for Products by adding a \Products\ListDetails.aspx page to my project:

      You can then add any standard ASP.NET data control to the page.  You can also use the new dynamic data aware ASP.NET data controls that ship in the ASP.NET 3.5 Extensions CTP to the page.  These allow you to completely customize the look and feel of the UI - while still using the new dynamic meta-data provider to infer relationships and meta-data about your data model classes for default behavior.

      Learning More

      The above walk-through only touches on a few of the scenarios and capabilities you can enable with ASP.NET Dynamic Data Projects.  To learn more:

      1. Watch David's webcast
      2. Check out the ASP.NET Dynamic Data QuickStarts
      3. Subscribe to David Ebbo's, Scott Hunter's, and Marcin Dobosz's blogs
      4. Visit the ASP.NET Dynamic Data Forum to ask questions

      To learn more about LINQ to SQL and how you can use it to create data model classes, also check out my previous blog posts below:

      You can also watch the great LINQ and LINQ to SQL "How do I?" videos on the www.asp.net site here.

      Hope this helps,

      Scott

    • Announcing 22books

      If you have known me for very long you probably realized at some point that I have a ton of ideas and crazy plans, but I usually have a pretty hard time following through. This is most evident in the number of domain names and half-written projects I have laying around. Well, I think I may have finally broken myself of this habit. I followed through and got AutoTest.NET out, even if it still needs lots of work. I took over The Lounge, even though that was kind of cheating since I just had to install and configure existing code.

      200712121939

      Now I am ready to launch 22books, the rails side project I have been working on for a couple months. It's a pretty simple site that is centered around the creating and sharing of book lists. There are plenty of book sites out there, but 22books is different than most because I focused more on just book lists and less about cataloging all of your books.

      I approached this project with a couple goals. The first goal was to give people a place to easily create book lists, but the second goal was to create a large set of standard lists. Standard lists would be things like a complete list of Kurt Vonneguts works, or Booker Prize winnders, etc.

      I tried to make the site as simple and easy to use as possible, I will add more features in future releases, but I hope to keep the simplicity.

      Check it out and let me know what you think. I am going to blog this weekend about what tools/plugins I used to build it.

      -James

    • ALT.NET in Baltimore and D.C.

      Matthew makes the announcement in a blog post:

      So, you may ask yourself, there are already groups out in the DC area, such as CapArea.NET, RockNUG, CMAP, DC XP Users group among others. They are great user groups that put on a lot of great events that I have attended time and time again and at some point presented at one of them. It's my belief that this group can supplement them nicely and help each other out. Many of these groups spend a lot of time talking about the new things coming from Microsoft. That's a very good thing, but that's not what we're aiming for. The goal of this group is to form very active discussion groups and find new and better ways to develop software. This group practices the Open Space Technology and encourages people to bring topics to talk about.

      First meeting is this Thursday, Dec 13th.

      Join the mailing list, and watch for the roaming meeting to reach a location near you in the D.C. / Baltimore metropolitan area.

    • Taking over The Lounge

      If you ever look at my blog in a browser you might have noticed an ad on the right sidebar from The Lounge advertising network. The Lounge is an advertising network that was created by Kevin Fricovsky. About a week ago I talked Kevin into turning The Lounge over to me since he is going to be too busy in other ventures. Since then I have been working feverishly to get it all up and running on my servers and getting the publishers to switch over there code.

      If you haven't seen The Lounge before the basic idea is that we have rooms of publishers and advertisers can buy space in those rooms. Unlike conventional advertising we don't sell ads by the impression or click, but instead you buy 30 days of your ad being shown. If we have 9 publishers we could have up to 9 advertisers with each of their ads rotating on all 9 sites.

      I am pretty excited about this new opportunity and look forward to growing the .NET room as well as expanding out into new rooms.

      My current goal is to book up the current .NET room so if you work for a company that might be interested in advertising there please drop me a line!

      -James

    • Good Stuff #4

      Its so warm here it almost seems like a sin.

      -James

    • ASP.NET Version 3.5's Web.config File

      If you have had a chance to try out Visual Studio 2008, you likely have seen the rather bulky Web.config file Visual Studio generates when creating a new ASP.NET website or when converting an ASP.NET 2.0 website to 3.5. In one of Scott Guthrie's blog entries a commenter named Mike asked Scott for a rundown of the markup in the default Web.config file generated for version 3.5 ASP.NET applications.

      I went ahead and created such an article: Dissecting ASP.NET Version 3.5's Web.config File.

      Enjoy!

    • Good Stuff #3

      Busy day today, got ferret up and running which was very cool.

      -James

    • ASP.NET 3.5 Extensions CTP Preview Released

      Earlier today we released the first CTP preview of an "ASP.NET 3.5 Extensions" release that we've been working on (click here to read my previous post about our product roadmap).  This release brings additional runtime functionality to ASP.NET and .NET 3.5.  You can download it here (if you are using the MVC features also click here to download the MVC Toolkit extras).

      This first ASP.NET 3.5 Extensions preview release includes:

      • ASP.NET AJAX Improvements: New ASP.NET AJAX features in the ASP.NET 3.5 Extensions release include better browser history support (back/forward button integration, and server-side history management support), improved AJAX content linking support with permalinks, and additional JavaScript library improvements.
      • ASP.NET MVC: This model view controller (MVC) framework for ASP.NET provides a structured model that enables a clear separation of concerns within web applications, and makes it easier to unit test your code and support a TDD workflow. It also helps provide more control over the URLs you publish in your applications, and more control over the HTML that is emitted from them.
      • ASP.NET Dynamic Data Support: The ASP.NET 3.5 Extensions release delivers new features that enable faster creation of data driven web sites.  It provides a rich scaffolding framework, and will enable rapid data driven site development using both ASP.NET WebForms and ASP.NET MVC.
      • ASP.NET Silverlight Support: With the ASP.NET 3.5 Extensions release we'll deliver support for easily integrating Silverlight within your ASP.NET applications.  Included will be new controls that make it easy to integrate Silverlight video/media and interactive content within your sites.
      • ADO.NET Data Services: In parallel with the ASP.NET Extensions release we will also be releasing the ADO.NET Entity Framework.  This provides a modeling framework that enables developers to define a conceptual model of a database schema that closely aligns to a real world view of the information.  We will also be shipping a new set of data services (codename "Astoria") that make it easy to expose REST based API endpoints from within your ASP.NET applications.

      We will be publishing many blog posts and videos discussing the new features in the weeks and months ahead.  Click here to check out an initial set of Quickstart Samples that cover some of the new preview features. 

      Below you can find links to a few tutorial posts I've done (and a cool TDD one by Phil Haack) that cover the new ASP.NET MVC Framework option.  I'll be doing more posts on the non-MVC features in the extensions release in the weeks ahead as well:

      To ask questions or get help, please visit these forums on http://forums.asp.net

      Hope this helps,

      Scott

    • The Greatest Challenge in Software Development

      ... is choosing the right names.

      Local variables need names. Instance variables need names. Methods need names, too, as do classes, columns, delegates, events, files, forms, parameters, projects, products, services, styles, tables, and of course – namespaces. Namespaces are nothing but a name! So many names, and so few words to use.

      I was thinking about the amount of mental effort I expend in basic programming activities – like picking control structures (foreach versus do-while), or data structures (stacks versus lists), versus the amount of effort I expend to name all the abstractions in the simplest piece of software. Loops and structures are easy – naming requires a great deal of time and thought.

      After all these years of thinking about names, I still struggle to pick the perfect name. Naming is a skill I need to improve - because names are important. I can use all the right patterns, have 100% test coverage, exceed every performance requirement, and still feel like I've failed if the names produce a piece of software that looks amorphous carbon:

      Bad names kill good software by making the software un-maintainable.

      Here are some interesting reads on naming:

      I'd like to find more. Know of any others good ones?

    • ASP.NET 3.5 Extensions Preview is out

      (that's MVC)

      get it here.

      -James

    • ASP.NET MVC Framework (Part 4): Handling Form Edit and Post Scenarios

      The last few weeks I have been working on a series of blog posts that cover the new ASP.NET MVC Framework we are working on.  The ASP.NET MVC Framework is an optional approach you can use to structure your ASP.NET web applications to have a clear separation of concerns, and make it easier to unit test your code and support a TDD workflow.

      The first post in this series built a simple e-commerce product listing/browsing site.  It covered the high-level concepts behind MVC, and demonstrated how to create a new ASP.NET MVC project from scratch to implement and test this e-commerce product listing functionality.  The second post drilled deep into the URL routing architecture of the ASP.NET MVC framework, and discussed both how it worked as well as how you can handle more advanced URL routing scenarios with it.  The third post discussed how Controllers interact with Views, and specifically covered ways you can pass view data from a Controller to a View in order to render a response back to a client.

      In today's blog post I'm going to discuss approaches you can use to handle form input and post scenarios using the MVC framework, as well as talk about some of the HTML Helper extension methods you can use with it to make data editing scenarios easier.  Click here to download the source code for the completed application we are going to build below to explain these concepts.

      Form Input and Post Scenario

      To help illustrate some of the basics of how to handle form input and posting scenarios with the ASP.NET MVC Framework, we are going to build a simple product listing, product creation, and product editing scenario.  It will have three core end-user experiences:

      Product Listing By Category

      Users will be able to see a listing of all products within a particular product category by navigating to the /Products/Category/[CategoryID] URL:

      Add New Product

      Users will be able to add a new product to the store by clicking the "Add New Product" link above.  This takes them to the /Products/New URL - where they will be prompted to enter details about a new product to add:

      When they hit save, the product will be added to the database, and they will be redirected back to the product listing page.

      Edit Product

      On the product listing page users can click the "Edit" link next to each product.  This takes them to the /Products/Edit/[ProductID] URL - where they can change the product details and hit the Save button in order to update them in the database:

      Our Data Model

      We are going to use the SQL Server Northwind Sample Database to store our data.  We'll then use the LINQ to SQL object relational mapper (ORM) built-into .NET 3.5 to model the Product, Category, and Supplier objects that represent rows in our database tables. 

      We'll begin by right-clicking on our /Models sub-folder in our ASP.NET MVC project, and select "Add New Item" -> "LINQ to SQL Classes" to bring up the LINQ to SQL ORM designer and model our data objects:

      We'll then create a partial NorthwindDataContext class in our project and add some helper methods to it.  We are defining these helper methods for two reasons: 1) it avoids us embedding our LINQ queries directly in our Controller classes, and 2) it will enable us to more easily adapt our Controller to use dependency injection in the future.

      The NorthwindDataContext helper methods we'll add look like below:

      To learn more about LINQ and LINQ to SQL, please check out my LINQ to SQL series here.

      Building Our ProductsController

      We are going to implement all three of our core end-user browsing experiences using a single controller class - which we'll call "ProductsController" (right click on the "Controllers" sub folder and select "Add New Item" -> "MVC Controller" in order to create it:

      Our ProductsController class will handle URLs like /Products/Category/3, /Products/New, and /Products/Edit/5 by implementing "Category", "New", and "Edit" actions:

      Read Part 1 and Part 2 of my ASP.NET MVC Series to learn more about how these URLs are routed to the action methods on the ProductsController class.  For this sample we are going to use the default /[Controller]/[Action]/[Id] route mapping rule - which means we do not need to configure anything in order for the routing to happen.

      Our Controller actions will be using three View pages in order to render output.  The "List.aspx", "New.aspx", and "Edit.aspx" pages will live under the \Views\Products sub-folder, and be based on the Site.Master master page under \Views\Shared.

      Implementing Product Listing By Category

      The first part of the site that we'll implement will be the Product Listing URL (/Products/Category/[CategoryId]):

      We'll implement this functionality using the "Category" action on our ProductsController class.  We'll use our LINQ to SQL DataContext class, and the GetCategoryById helper method we added to it, to retrieve a Category object that represents the particular category indicated by the URL (for example: /Products/Category/3).  We'll then pass the Category object to the "List" view to render a response from it:

      When implementing our List view we'll first update our page's code-behind to derive from ViewPage<Category> so that our page's ViewData property will be typed to the Category object that was passed by our Controller (Part 3 discusses this more):

      We'll then implement our List.aspx like below:

      The above view renders the Category name at the top of the page, and then renders a bulleted list of the Products within the category. 

      Next to each product in the bulleted list is an "Edit" link.  We are using the Html.ActionLink helper method that I discussed in Part 2 to render a HTML hyperlink (for example: <a href="/Products/Edit/4">Edit</a>) that when pressed will navigate the user to the "Edit" action.  We are also then using the Html.ActionLink helper method again at the bottom of the page to render a <a href="/Products/New">Add New Product</a> link that when pressed will navigate the user to the "New" action.

      When we visit the /Products/Category/1 URL and do a view-source in the browser, you'll notice that our ASP.NET MVC application has emitted very clean HTML and URL markup:

      Implementing Add New Product (Part 1 - Background)

      Let's now implement the "Add New Product" form post functionality of our site.  We'll ultimately want users to see a screen like below when they visit the /Products/New URL:

      Form input and editing scenarios are typically handled in the ASP.NET MVC Framework by exposing two Action methods on a Controller class.  The first Controller Action method is responsible for sending down the HTML containing the initial form to display.  The second Controller action method is then responsible for handling any form submissions sent back from the browser.

      For example, for our "Add Product" screen above we could choose to implement it across two different ProductsController actions: one called "New" and one called "Create".  The /Products/New URL would be responsible for displaying an empty form with HTML textboxes and drop-down list controls to enter new product details.  The HTML <form> element on this page would then have its "action" attribute set to the /Products/Create URLThis means that when the user presses a form submit button on it, the form inputs will be sent to the "Create" action to process and update the database with.

      Implementing Add New Product (Part 2 - First Approach)

      Below is an initial implementation that we could use for our ProductsController. 

      Notice above that we now have two action methods involved in the product creation process - "New" and "Create".  The "New" action method simply displays a blank form to the user.  The "Create" action method is what processes the posted values from the form, creates a new Product in the database based on them, and then redirects the client to the category listing page for the product.

      The HTML form sent to the client is implemented in the "New.aspx" view called by the "New" action method.  An initial implementation of this (using textboxes for everything) would look like below:

      Note above how we are using a standard HTML <form> element on the page (not a form runat=server).  The form's "action" attribute is set to post to our "Create" action method on ProductsController.  The post will happen when the <input type="submit"> element at the bottom is pressed.  When this happens, the ASP.NET MVC Framework will automatically handle mapping the ProductName, CategoryID, SupplierID and UnitPrice values as method parameters to the "Create" action method on ProductsController:

      And now when we run the site we have basic product entry functionality working:

      Implementing Add New Product (Part 3 - Using HTML Helpers for Drop Down Lists)

      The product entry screen we created in the previous section works, but isn't very user friendly.  Specifically, it requires that the end user know the raw CategoryID and SupplierID numbers for the Product being entered.  We need to fix this by instead displaying an HTML dropdownlist that displays the human readable names.

      Our first step will be to modify our ProductsController to pass to the View two collections - one containing a list of available categories, the other a list of available suppliers.  We'll do this by creating a strongly typed ProductsNewViewData class that encapsulates these, and which we'll then pass to the View (you can learn about this in Part 3):

      We'll then update our "New" action method to populate these collections and pass them as the ViewData for the "New" view:

      Within our view we can then use these collections to generate HTML <select> dropdowns. 

      ASP.NET MVC HTML Helpers

      One approach we could use to generate our dropdowns would be to manually create our own <% %> for-loop containing if/else statements within the HTML.  This would give us total control over the HTML - but would make the HTML messy.

      A much cleaner approach that you can alternatively use is to take advantage of the "Html" helper property on the ViewPage base class.  This is a convenient object that exposes a set of HTML Helper UI methods that automate HTML UI generation.  For example, earlier in this post we used the Html.ActionLink helper method to generate <a href=""> elements:

      The HtmlHelper object (as well as the AjaxHelper object - which we'll talk about in a later tutorial) have been specifically designed to be easily extended using "Extension Methods" - which is a new language feature of VB and C# in the VS 2008 release.  What this means is that anyone can create their own custom helper methods for these objects and share them for you to use. 

      We'll have dozens of built-in HTML and AJAX helper methods in future previews of the ASP.NET MVC Framework.  In the first preview release only the "ActionLink" method is built-into System.Web.Extensions (the assembly where the core ASP.NET MVC framework is currently implemented).  We do, though, also have a separate "MVCToolkit" download that you can add to your project to obtain dozens more helper methods that you can use with the first preview release. 

      To install the MVCToolkit HTML Helper methods, simply add the MVCToolkit.dll assembly to your project references:

      Re-build your project.  And then the next time you type <%= Html. %> you'll see many, many more additional UI helpers that you can use:

      To build our HTML <select> dropdowns we could use the Html.Select() method.  Each method comes with overloaded method versions - all with full intellisense inside our views:

      We could update our "New" view to use the Html.Select options to display dropdownlists that use the CategoryID/SupplierID properties as the values and CategoryName/SupplierName as the display text using the code below:

      This will generate the appropriate <select> HTML markup for us at runtime:

      And give end-users an easier way to pick the Product Category and Supplier on our /Products/New screen:

      Note: because we are still posting a CategoryID and SupplierID value to the server, we do not need to update our ProductsController Create Action at all to support this new drop-downlist UI - it will just work.

      Implementing Add New Product (Part 4 - Cleaning Up Create with the UpdateFrom Method)

      Our ProductsController's "Create" Action method is responsible for handling the form posting of our "Add Product" scenario.   It currently handles incoming form parameters as arguments to the action method:

      This approach works fine - although for forms involving large amounts of values the method signatures on Actions can start to become a little hard to read.  The code above that sets all of the incoming parameter values to the new Product object is also a little long and monotonous.

      If you reference the MVCToolkit assembly, you can optionally take advantage of a useful Extension Method implemented within the System.Web.Mvc.BindingHelpers namespace that can help clean this up a little.  It is called "UpdateFrom" and can be used on any .NET object.  It takes a dictionary of values as an argument, and it will then automatically perform a property assignment on itself for any key that matches a public property on the object.

      For example, we could re-write our Create action method above to use the UpdateFrom method like so:

       

      Note: if you want to be more explicit for security reasons and only allow certain properties to be updated, you can also optionally pass a string array of the property names to update to the UpdateFrom method:

      Implement Edit Product Functionality (Part 1 - Background)

      Let's now implement the "Edit Product" functionality of our site.  We'll ultimately want users to see a screen like below when they visit the /Products/Edit/[ProductID] URL:

      Like the "Add New Product" form post example above, we are going to implement this form edit interaction using two ProductsController Actions that we'll call "Edit" and "Update": 

      "Edit" will display the product form.  "Update" will be used to handle the form's submit action.

      Implement Edit Product Functionality (Part 2 - Edit Action)

      We'll begin enabling our application's Edit functionality by implementing the ProductController's Edit action method.  When we created our product listing page at the beginning of this post, we built it so that the Edit action will take an id argument as part of the URL (for example: /Products/Edit/5):

      We'll want the Edit action method to retrieve the appropriate Product object from the database, as well as retrieve collections of the available Suppliers and Categories (so that we can implement dropdowns in our edit view).  We'll define a strongly typed view object to represent all of this using the ProductsEditViewData object below:

      We can then implement our Edit action method to populate this viewdata object and Render it with an "Edit" view:

      Implement Edit Product Functionality (Part 2 - Edit View)

      We can implement the "Edit.aspx" view page using the following approach:

      Note how we are using both the Html.TextBox and Html.Select helper methods in the sample above.  Both of these are extension methods from the MVCToolkit.dll assembly.

      Notice how the Html.Select helper method has an overloaded version that allows you to specify what the selected value is in the dropdownlist.  In the snippet below I'm indicating that I want the Category drop down item to be automatically selected based on the edit product's current CategoryID value:

      Lastly - notice how we are using the Url.Action() helper method to set the <form> element's "action" attribute:

      Both the Url.Action and Html.ActionLink helper methods use the ASP.NET MVC Framework's Routing Engine to generate URLs (read Part 2 for details on how URL generation works).  What this means is that if we change the routing rules for Edits in our site, we will not need to change any of the code in our Controller or View.  For example, we could re-map our URLs to use a more RESTful URL like /Products/1/Edit instead of /Products/Edit/1, and have the above Controller and View continue to work unmodified. 

      Implement Edit Product Functionality (Part 3 - Update Action)

      Our last step will be to implement the "Update" action method on our ProductController class: 

      Like our previous "Create" action method we'll take advantage of the "UpdateFrom" extension method to automatically populate our product object from the request.  Notice that rather then populate an empty product object though, we are using a pattern where we first retrieve the old values from the database, then apply the changes the user made to them, and then save them in the database. 

      Once the edit is made, we redirect back to the Product Listing page - and automatically set the /Products/Category/[CategoryID] to match the saved state of the Product we were working on.

      Summary

      Hopefully this post has helped provide some more details about how to handle Form Input and Post scenarios with the ASP.NET MVC Framework, as well as provided some context for how you can handle and structure common data entry and edit scenarios with it.

      Click here to download a .ZIP file that contains the source code for the completed application we built above.

      In future posts I'll cover how to handle validation and error recovery situations with form input and editing scenarios. I'll talk about some of the data and security scaffolding support built-in to enable rapid application creation.  I'll discuss how you can use ASP.NET AJAX to perform AJAX-enabled edits using the MVC framework.  And I'll drill deeper into how you can unit test and add dependency injection to your Controllers.

      Hope this helps,

      Scott

    • December 8th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, .NET, VS 2008

      Here is the latest in my link-listing series.  Also check out my ASP.NET Tips, Tricks and Tutorials page for links to popular articles I've done myself in the past.

      Several people have pinged me asking for the download location of the ASP.NET 3.5 Extensions Preview.  We were hoping to post it on the web Friday, but unfortunately found a late bug that we felt needed to be fixed.  The team is working this weekend to sign off on the new build.  We hope to be able to post it as soon as this is done - apologies for the delay.

      ASP.NET

      • Taking an ASP.NET Application Offline: Scott Mitchell has a good article on 4GuysFromRolla that discusses a few approaches you can use to temporarily take down ASP.NET applications for updates/maintenance. 

      ASP.NET AJAX

      • Sys.Debug in ASP.NET AJAX Framework: Roman Nikitin has a nice post that describes how to use the Sys.Debug feature of ASP.NET AJAX to easily instrument, debug and trace your AJAX applications. 

      ASP.NET MVC

      • TDD and Dependency Injection with ASP.NET MVC: Phil Haack from the ASP.NET team writes about how to use TDD (test driven development) with the new ASP.NET MVC Framework.  He uses StructureMap and RhinoMocks to enable the Dependency Injection and Mocking support.

      .NET

      • Want to See the .NET Framework Source Code?: We are shortly going to post instructions on how anyone can browse and debug into the .NET Framework source code.  If you want to help try this out before the general public and test our servers that will be supporting it please send email to: fxrefsrc@microsoft,com and we'll give you instructions on how to use it now.

      • Hidden Gems in Visual Basic 2008: Amanda Silver from the VB team has an awesome post that discusses some of the new hidden gems with Visual Basic in VS 2008.  I actually learned a few of them for the first time reading her article!  Highly recommended reading.

      • LINQ to Active Directory is Here: Bart De Smet from my team has been working on a cool LINQ to Active Directory provider (previously called LINQ to LDAP) in his spare time.  You can learn how to use it in his series here, as well as read about how he built it (and learn a lot about how to build LINQ providers).

      Visual Studio

      Hope this helps,

      Scott

    • Good Stuff #2

      Ok, found lots of cool stuff today so figured I would do another one. Almost all ruby/rails/mac stuff today.

      -James

    • Rails 2.0 is out

      The official announcement is over here with a good list of changes. I see lots of good things being added, but even better is that they are moving a lot of the fringe features (like the various acts_as_xxx plugins and commercial database adapters) out of the framework. Pruning out features is probably one of the more under-appreciated parts of creating new releases, I am glad to see the rails team is getting it right.

      -James

    • Can I Replace JavaScript (and everything else) With Volta?

      In my last post, I looked at using managed code in Silverlight as a replacement for JavaScript and offered the following code as an example:

      HtmlDocument document = HtmlPage.Document;
      HtmlElement select = document.GetElementByID("mySelect");

      for (int i = 0; i < 10; i++)
      {
          
      HtmlElement option = document.CreateElement("option");
          option.SetAttribute(
      "value", "foo" + i.ToString());
          option.SetAttribute(
      "innerHTML", "foo" + i.ToString());
          select.AppendChild(option);
      }

      In my opinion, the managed code API offers a sub-optimal experience relative to the plain and simple JavaScript that would implement the same functionality. To be fair, Silverlight's mission isn't to replace JavaScript, HTML, web browsers, and motherly love (as yet, I guess), but I wanted to explore the idea.

      In an ironic twist, Microsoft's Live Labs released a preview of Volta this week with the following key messages:

      • Volta automates certain low-level aspects of distributing applications across multiple tiers, allowing programmers to devote their creative energy to the distinguishing features of their applications.
      • Via declarative tier splitting, Volta lets developers postpone irreversible design decisions until the last responsible moment, making it faster and cheaper to change the architecture to accommodate evolving needs.
      • Through MSIL rewriting, Volta follows developer's declarations to turn a single-tiered application into a multi-tiered application, generating boilerplate code for communication and serialization.

      The first two bullet points make me uncomfortable. "Declarative tier splitting" sounds a lot like a movie I saw during the COM+ days. In that movie a hero by the name of "Location Transparency" was killed by 10 million chatty microbes from the Andromeda galaxy. It was a slow death, and a sad ending.

      Two things sparked my interest in Volta, however. Seeing Erik Meijer at the helm of Volta was one, and MSIL rewriting was the second. There are MSIL re-writing tools available today (see the profiling API and Mono.Cecil as examples), but mainstream MSIL re-writing can bring many benefits to the CLR. One only has to look into Java land where bytecode modifications yield interesting possibilities for aspect oriented programming, inversion of control scenarios, application optimizations, and more.

      The result was that I downloaded the new bits and gave Volta a spin. Volta can run client applications in the browser, so I continued the "how to kill JavaScript" bit by trying my C# code using the Volta programming model:

      Select mySelect = Document.GetById<Select>("mySelect");

      for (int i = 0; i < 10; i++)
      {
          mySelect.Add(
      new Option() { Value = "foo " + i.ToString(),
                                      Text =
      "foo "  + i.ToString()
                                     });
      }

      ... much closer to the model I was looking for, and it works in IE and FireFox, too.

      Wait! What about the Document.GetByID method? Is that a static method on a static class just waiting to plunge a knife into the heart of a unit test? No – it turns out Document is a property on the Volta Page class that implements an IJavaScriptObject interface (hooray!). You can almost taste the testability, except that Document is a read-only property (boo!). I hope that the MSIL re-writing in Volta will give us the ability to inject mock Documents for testing.

      It will be interesting to see how project Volta progresses.

    • Good Stuff #1

      Ok, call me an idiot. I am doing it again. If you have been reading this blog for awhile you might remember when I used to post the .NET Nightly on a regular basis. I have been thinking about doing another link style post, and what the heck, why not? This is the first one of those posts. These posts won't be .NET specific, but more about just whatever cool stuff I have come across that day.

      • seeed - a place to discuss the business of web applications.
      • 20 tools for web application development - good list, pretty close to my own. (which I will post one of these days) (via KevinF)
      • Google Chart API - looks interesting, but all the cool people are using flash charts now like these.
      • Microsoft Live Labs Volta - write a .NET client app and then post it to the web, or don't waste your time and just write a web application in the first place. (seriously, there have been 3rd party folks doing this for years)

      I am making no commitments, this might be the only one. :) I tried to get del.icio.us to just automatically post my links, but it doesn't seem to work with subText (or I have it configured wrong)

      -James

    • ASP.NET MVC Framework (Part 3): Passing ViewData from Controllers to Views

      The last few weeks I have been working on a series of blog posts that cover the new ASP.NET MVC Framework we are working on.  The ASP.NET MVC Framework is an optional approach you can use to structure your ASP.NET web applications to have a clear separation of concerns, and make it easier to unit test your code and support a TDD workflow.

      The first post in this series built a simple e-commerce product listing/browsing site.  It covered the high-level concepts behind MVC, and demonstrated how to create a new ASP.NET MVC project from scratch to implement and test this e-commerce product listing functionality.  The second post in this series drilled deep into the URL routing architecture of the ASP.NET MVC framework, and discussed both how it worked as well as how you can handle more advanced URL routing scenarios with it.

      In today's blog post I'm going to discuss how Controllers interact with Views, and specifically cover ways you can pass data from a Controller to a View in order to render a response back to a client.

      Quick Recap from Part 1

      In Part 1 of this series, we created an e-commerce site that implemented basic product listing/browsing support.  We implemented this site using the ASP.NET MVC Framework, which led us to naturally structure the code into distinct controller, model and view components.

      When a browser sends a HTTP request to our web site, the ASP.NET MVC Framework will use its URL routing engine to map the incoming request to an action method on a controller class to process it.  Controllers in a MVC based application are responsible for processing incoming requests, handling user input and interactions, and executing application logic based on them (retrieving and updating model data stored in a database, etc).

      When it comes time to render an HTML response back to the client, controllers typically work with "view" components - which are implemented as separate classes/templates from the controllers, and are intended to be focused entirely on encapsulating presentation logic. 

      Views should not contain any application logic or database retrieval code, instead all application/data logic should only be handled by the controller class.  The motivation behind this partitioning is to help enforce a clear separation of your application/data logic from your UI generation code.  This makes it easier to unit test your application/data logic in isolation from your UI rendering logic.

      Views should only render their output using the view-specific data passed to it by the Controller class.  In the ASP.NET MVC Framework we call this view-specific data "ViewData".  The rest of this blog post is going to cover some of the different approaches you can use to pass this "ViewData" from the Controller to the View to render.

      A Simple Product Listing Scenario

      To help illustrate some of the techniques we can use to pass ViewData from a Controller to a View, let's build a simple product listing page:

      We will use a CategoryID integer to filter the products that we want to display for the page.  Notice above how we are embedding the CategoryID as part of the URL (for example: /Products/Category/2 or /Products/Category/4).

      Our product listing page is then rendering two separate dynamic content elements. The first is the textual name of the category we are displaying (for example: "Condiments").  The second is an HTML <ul><li/></ul> list of product names.  I've circled both of these in red in the above screen-shot.

      Below we'll look at two different approaches we can use to implement a "ProductsController" class that processes the incoming request, retrieves the data necessary to handle it, and then passes this data to a "List" view to render it.  The first approach we'll examine passes the data using a late-bound dictionary object.  The second approach we'll examine passes it using a strongly-typed class.

      Approach 1: Passing ViewData using the Controller.ViewData Dictionary

      The Controller base class has a "ViewData" dictionary property that can be used to populate data that you want to pass to a View.  You add objects into the ViewData dictionary using a key/value pattern.

      Below is a ProductsController class with a "Category" action method that implements our product listing scenario above.  Notice how it is using the category's ID parameter to lookup the textual name of the category, as well as retrieve a list of the Products within that category.  It is storing both of these in the Controller.ViewData collection using a "CategoryName" and "Products" key:

       

      Our Category action above is then calling RenderView("List") to indicate which view template it wants to render.  When you call RenderView like this it will pass the ViewData dictionary to the View in order for it to render.

      Implementing Our View

      We will implement our List view using a List.aspx file that lives under the \Views\Products directory of our project.  This List.aspx page will inherit the layout of the Site.Master MasterPage under the \Views\Shared folder (right click within VS 2008 and select Add New Item->MVC View Content Page to wire up a master page when you create a new view page):

      When we create our List.aspx page using the MVC View Content Page template it derives not from the usual System.Web.UI.Page class, but rather from the System.Web.Mvc.ViewPage base class (which is a subclass of the existing Page class):

      The ViewPage base class provides us with a ViewData dictionary property that we can use within the view page to access the data objects that were added by the Controller.  We can then take these data objects and use them to render HTML output using either server controls, or by using <%= %> rendering code.

      Implementing Our View Using Server Controls

      Below is an example of how we could use the existing <asp:literal> and <asp:repeater> server controls to implement our HTML UI:

      We can bind the ViewData to these controls using the below code-behind class (note how we are using the ViewPage's ViewData dictionary to-do this):

      Note: Because we have no <form runat="server"> on the page, no view-state is ever emitted.  The above controls also don't automatically render any ID value - which means that you have total control over the HTML emitted.

      Implementing our View using <%= %> Code

      If you prefer to use inline rendering code to generate the output, you can accomplish the same result as above using the List.aspx below:

      Note: Because ViewData is typed as a dictionary containing "objects", we need to cast ViewData["Products"] to a List<Product> or an IEnumerable<Product> in order to use the foreach statement on it.  I am importing both the System.Collections.Generic and MyStore.Models namespaces on the page to avoid having to fully qualify the List<T> and Product types.

      Note: The use of the "var" keyword above is an example of using the new C# and VB "type inference" feature in VS 2008 (read here for my previous post on this).  Because we have cast ViewData["Products"] as a List<Product> we get full intellisense on the product variable within the List.aspx file:

      Approach 2: Passing ViewData using Strongly Typed Classes

      In addition to supporting a late-bound dictionary approach, the ASP.NET MVC Framework also enables you to pass strongly typed ViewData objects from your Controller to your View.  There are a couple of benefits of using this strongly typed approach:

      1. You avoid using strings to lookup objects, and get compile-time checking of both your Controller and View code
      2. You avoid the need to explicitly cast values from the ViewData object dictionary when using strongly-typed languages like C#
      3. You get automatic code intellisense against your ViewData object within both the markup and code-behind of your view page
      4. You can use code refactoring tools to help automate changes across your app and unit-test code base

      Below is a strongly typed "ProductsListViewData" class that encapsulates the data needed for the List.aspx view to render our product listing.  It has CategoryName and Products properties (implemented using the new C# automatic properties support):

      We can then update our ProductsController implementation to use this object to pass a strongly typed ViewData object to our view:

      Notice above how we are passing our strongly typed ProductsListViewData object to the View by adding it as an extra parameter to the RenderView() method.

      Using the View's ViewData Dictionary with a Strongly Typed ViewData Object

      The previous List.aspx view implementations we wrote will continue to work with our updated ProductsController - no code changes required.  This is because when a strongly typed ViewData object is passed to a View that derives from ViewPage, the ViewData dictionary will automatically use reflection against the properties of the strongly typed object to lookup values.  So code in our view like below:

      will automatically use reflection to retrieve the value from the CategoryName property of the strongly typed ProductsListViewData object we passed when calling the RenderView method.

      Using the ViewPage<T> Base Class to Strongly Type ViewData

      In addition to supporting a dictionary based ViewPage base class, the ASP.NET MVC Framework also ships with a generics based ViewPage<T> implementation.  If your View derives from ViewPage<T> - where T indicates the type of the ViewData class the Controller passes to the view - then the ViewData property will be strongly typed using this class type.

      For example, we could update our List.aspx.cs code-behind class to derive not from ViewPage, but from ViewPage<ProductsListViewData>:

      When we do this, the ViewData property on the page will change from being a dictionary to being of type ProductsListViewData.  This means that instead of using string-based dictionary lookups to retrieve data, we can now use strongly typed properties:

      We can then use either a sever-control approach, or a <%= %> rendering approach to render HTML based on this ViewData.

      Implementing Our ViewPage<T> Implementation Using Server Controls

      Below is an example of how we could use the <asp:literal> and <asp:repeater> server controls to implement our HTML UI.  This is the exact same markup that we used when our List.aspx page derived from ViewPage:

      Below is what the code-behind now looks like.  Note how because we are deriving from ViewPage<ProductsListViewData> we can access the properties directly - and we don't need to cast anything (we'll also get refactoring tool support anytime we decide to rename one of the properties):

      Implementing our ViewPage<T> implementation using <%= %> Code

      If you prefer to use inline rendering code to generate the output, you can accomplish the same result as above using the List.aspx below:

      Using the ViewPage<T> approach we now no longer need to use string lookups of the ViewData.  Even more importantly, notice above how we no longer need to cast any of the properties - since they are strongly typed.  This means we can write foreach (var product in ViewData.Products) and not have to cast Products.  We also get full intellisense on the product variable within the loop:

      Summary

      Hopefully the above post helps provide some more details about how Controllers pass data to a View in order to render a response to a client.  You can use either a late-bound dictionary, or a strongly-typed approach to accomplish this.

      The first time you try and build an MVC application you will likely find the concept of splitting up and separating your application controller logic from your UI generation code a little strange.  It will probably take some dedicated app-building time before you become comfortable and orient your mind-set around the idea of processing a request, executing all of the application logic for it, packaging up the viewdata required to build a UI response, and then handing it off to a separate view page to render it.  Important: If this model doesn't feel comfortable to you then don't use it - the MVC approach is purely optional, and we don't think it is something everyone will want to use. 

      The benefit and goal behind this application partitioning, though, is that it enables you to run and test your application and data logic in isolation from your UI rendering code.  This makes it much easier to develop comprehensive unit tests for your application, as well as to use a TDD (test driven development) workflow as you build your applications.  In later blog posts I'll drill in deeper into this more, as well as discuss best practices you can use to easily test your code.

      Hope this helps,

      Scott

    • ASP.NET MVC Framework (Part 2): URL Routing

      Last month I blogged the first in a series of posts I'm going to write that cover the new ASP.NET MVC Framework we are working on.  The first post in this series built a simple e-commerce product listing/browsing scenario.  It covered the high-level concepts behind MVC, and demonstrated how to create a new ASP.NET MVC project from scratch to implement and test this e-commerce product listing functionality.

      In today's blog post I'm going to drill deeper into the routing architecture of the ASP.NET MVC Framework, and discuss some of the cool ways you can use it for more advanced scenarios in your application.

      Quick Recap from Part 1

      In Part 1 of this series, we created an e-commerce site that exposed three types of URLs:

      URL Format Behavior URL Example
      /Products/Categories Browse all Product Categories /Products/Categories
      /Products/List/Category List Products within a Category /Products/List/Beverages
      /Products/Detail/ProductID Show Details about a Specific Product /Products/Detail/34

      We handled these URLs by creating a "ProductsController" class like below:

      Once the above class was added to our application, the ASP.NET MVC Framework automatically handled routing the incoming URLs to the appropriate action method on our controller to process.

      In today's blog post we are going to drill into exactly how this URL mapping happened, as well as explore more advanced routing scenarios we can take advantage of with the ASP.NET MVC Framework.  I'll also demonstrate how you can easily unit test URL routing scenarios. 

      What does the ASP.NET MVC URL Routing System do?

      The ASP.NET MVC framework includes a flexible URL routing system that enables you to define URL mapping rules within your applications.  The routing system has two main purposes:

      1. Map incoming URLs to the application and route them so that the right Controller and Action method executes to process them
      2. Construct outgoing URLs that can be used to call back to Controllers/Actions (for example: form posts, <a href=""> links, and AJAX calls)

      Having the ability to use URL mapping rules to handle both incoming and outgoing URL scenarios adds a lot of flexibility to application code.  It means that if we want to later change the URL structure of our application (for example: rename /Products to /Catalog), we could do so by modifying one set of mapping rules at the application level - and not require changing any code within our Controllers or View templates.

      Default ASP.NET MVC URL Routing Rules

      By default when you use Visual Studio to create a new project using the "ASP.NET MVC Web Application" template it adds an ASP.NET Application class to the project.  This is implemented within the Global.asax code-behind:

      The ASP.NET Application class enables developers to handle application startup/shutdown and global error handling logic. 

      The default ASP.NET MVC Project Template automatically adds an Application_Start method to the class and registers two URL Routing rules with it:

      The first routing rule above indicates that the ASP.NET MVC framework should by default map URLs to Controllers using a "[controller]/[action]/[id]" format when determining which Controller class to instantiate, and which Action method to invoke (along with which parameters should be passed in). 

      This default routing rule is why a URL request for /Products/Detail/3 in our e-commerce browsing sample from Part 1 automatically invokes the Detail method on our ProductsController class and passes in 3 as the id method argument value:

      The second routing rule above is added to special-case the root "Default.aspx" URL in our application (which is sometimes passed by web servers in place of "/" when handling requests for the root URL of an application).  This rule ensures that requests for either the root "/Default.aspx" or "/" to our application are handled by the "Index()" action on the "HomeController" class (which is a controller automatically added by Visual Studio when we created a new application using the "ASP.NET MVC Web Application" project template).

      Understanding Route Instances

      Routing rules are registered by adding Route instances into the System.Web.Mvc.RouteTable's Routes collection.

      The Route class defines a number of properties that you can use to configure the mapping rules.  You can set these properties using either "traditional" .NET 2.0 property assignments:

      Or by taking advantage of the new object initializer feature in the VS 2008 C# and VB compilers to set the properties more tersely:

       

      The "Url" property on the Route class defines the Url matching rule that should be used to evaluate if a route rule applies to a particular incoming request.  It also defines how the URL should be tokenized for parameters.  Replaceable parameters within the URL are defined using a [ParamName] syntax.  As we'll see later, we aren't restricted to a fixed set of "well known" parameter names - you can have any number of arbitrary parameters you want within the URL.  For example, I could use a Url rule of "/Blogs/[Username]/Archive/[Year]/[Month]/[Day]/[Title]" to tokenize incoming URLs to blog posts - and have the MVC framework automatically parse and pass UserName, Year, Month, Day and Title parameters to my Controller's action method.

      The "Defaults" property on the Route class defines a dictionary of default values to use in the event that the incoming URL doesn't include one of the parameter values specified.  For example, in the above URL mapping examples we are defining two default URL parameter values - one for "[action]" and one for "[id]".  This means that if a URL for /Products/ is received by the application, the routing system will by default use "Index" as the name of the action on the ProductsController to execute.  Likewise, if /Products/List/ was specified, then a null string value would be used for the "ID" parameter.

      The "RouteHandler" property on the Route class defines the IRouteHandler instance that should be used to process the request after the URL is tokenized and the appropriate routing rule to use is determined.  In the above examples we are indicating that we want to use the System.Web.Mvc.MvcRounteHandler class to process the URLs we have configured.  The reason for this extra step is that we want to make sure that the URL routing system can be used for both MVC and non-MVC requests.  Having this IRouteHandler interface means we will be able to cleanly use it for non-MVC requests as well (such as standard WebForms, Astoria REST support, etc).

      There is also a "Validation" property on the Route class that we'll look at a little later in this post.  This property allows us to specify pre-conditions that need to be met for a particular routing rule to match.  For example, we could indicate that a routing rule should only apply for a specific HTTP verb (allowing us to easily map REST commands), or we could use a regular expression on arguments to filter whether a routing rule should match.

      Note: In the first public MVC preview the Route class isn't extensible (instead it is a data class).  For the next preview release we are looking to make it extensible and enable developers to add scenario specific route classes (for example: a RestRoute sub-class) to cleanly add additional semantics and functionality. 

      Route Rules Evaluation

      When an incoming URL is received by an ASP.NET MVC Web Application, the MVC framework evaluates the routing rules in the RouteTable.Routes collection to determine the appropriate Controller to handle the request.

      The MVC framework chooses the Controller to use by evaluating the RouteTable rules in the order that they have been registered.  The incoming URL is tested against each Route rule to see if it matches - and if a Route rule matches then that rule (and its associated RouteHandler) is the one that is used to process the request (and all subsequent rules are ignored).  This means that you want to typically structure your routing Rules in a "most specific to least specific" order.

      Routing Scenario: Custom Search URL

      Let's walk through using some custom routing rules in a real world scenario.  We'll do this by implementing search functionality for our e-commerce site.

      We'll start by adding a new SearchController class to our project:

      We'll then define two Action methods within our SearchController class.  The Index() action method will be used to present a search page that has a TextBox for a user to enter and submit a search term.  The Results() action will be used to handle the form submission from it, perform the search against our database, and then display the results back to the user:

       

      Using the default /[controller]/[action]/[id] URL route mapping rule, we could "out of the box" use URLs like below to invoke our SearchController actions:

      Scenario URL Action Method
      Search Form: /Search/ Index
      Search Results: /Search/Results?query=Beverages Results
        /Search/Results?query=ASP.NET Results

      Note that the reason the root /Search URL by default maps to the Index() action method is because the /[controller]/[action]/[id] route definition added by default when Visual Studio creates a new project sets "Index" as the default action on Controllers (via the "Defaults" property):

      While URLs like /Search/Results?query=Beverages are perfectly functional, we might decide we want slightly "prettier" URLs for our search results.  Specifically we might want to get rid of the "Results" action name from the URL, and pass in the search query as part of the URL instead of using a QueryString argument.  For example:

      Scenario URL Action Method
      Search Form: /Search/ Index
      Search Results: /Search/Beverages Results
        /Search/ASP.NET Results

      We could enable these "prettier" search result URLs by adding two custom URL Route mapping rules before the default /[controller]/[action]/[id] rule like below:

      With the first two rules we are now explicitly specifying the Controller and Action parameters for /Search/ URLs.  We are indicating that "/Search" should always be handled by the "Index" action on the SearchController.  Any URL with a sub-URL hierarchy (/Search/Foo, /Search/Bar, etc) is now always handled by the "Results" action on the SearchController. 

      The second routing rule above indicates that anything beyond the /Search/ prefix should be treated as a parameter called "[query]" that will then be passed as a method parameter to our Results action method on SearchController:

      Most likely we will also want to enable paginated search results (where we only show 10 search query results at a time).  We could do this via a querystring argument (for example: /Search/Beverages?page=2) or we could optionally embed the page index number as part of the URL as well (for example: /Search/Beverages/2).  To support this later option all we'd need to-do is add an extra optional parameter to our 2nd routing rule:

      Notice above how the new URL rule match is now "Search/[query]/[page]".  We've also configured the default page index to be 1 in cases where it is not included in the URL (this is done via the anonymous type passed as the "Defaults" property value).

      We can then update our SearchController.Results action method to take this page parameter as a method argument:

       

      And with that we now have "pretty URL" searching for our site (all that remains is to implement the search algorithm - which I will leave as an exercise to the reader <g>).

      Validation Pre-Conditions for Routing Rules

      As I mentioned earlier in this post, the Route class has a "Validation" property that allows you to add validation pre-condition rules that must be true (in addition to the URL filter) for a route rule to match.  The ASP.NET MVC Framework allows you to use regular expressions to validate each parameter argument in the URL, as well as allows you to evaluate HTTP headers (to route URLs differently based on HTTP verbs). 

      Below is a custom validation rule we could enable for URLs like "/Products/Detail/43".  It specifies that the ID argument must be a number (no strings allowed), and that it must be between 1 and 8 characters long:

      If we pass in a URL like /Products/Detail/12 to our application, the above routing rule will be valid.  If we pass in /Products/Detail/abc or /Products/Detail/23232323232 it will not match.

      Constructing Outgoing URLs from the Routing System

      Earlier in this blog post I said that the URL routing system in the ASP.NET MVC Framework was responsible for two things:

      1. Mapping incoming URLs to Controllers/Actions to handle
      2. Helping construct outgoing URLs that can be used to later call back to Controllers/Actions (for example: form posts, <a href=""> links, and AJAX calls)

      The URL routing system has a number of helper methods and classes that make it easy to dynamically look up and construct URLs at runtime (you can also lookup URLs by working with the RouteTable's Route's collection directly).

      Html.ActionLink

      In Part 1 of this blog series I briefly discussed the Html.ActionLink() view helper method.  It can be used within views and allows you to dynamically generate <a href=""> hyperlinks.  What is cool is that it generates these URLs using the URL mapping rules defined in the MVC Routing System.  For example, the two Html.ActionLink calls below:

      automatically pick up the special Search results route rule we configured earlier in this post, and the "href" attribute they generate automatically reflect this:

      In particular note above how the second call to Html.ActionLink automatically mapped the "page" parameter as part of the URL (and note how the first call omitted the page parameter value - since it knew a default value would be provided on the server side). 

      Url.Action

      In addition to using Html.ActionLink, ASP.NET MVC also has a Url.Action() view helper method.  This generates raw string URLs - which you can then use however you want.  For example, the code snippet below:

      would use the URL routing system to return the below raw URL (not wrapped in a <a href=""> element):

      Controller.RedirectToAction

      ASP.NET MVC also supports a Controller.RedirectToAction() helper method that you can use within controllers to perform redirects (where the URLs are computed using the URL routing system).

      For example when the below code is invoked within a controller:

       

      It internally generates a call to Response.Redirect("/Search/Beverages")

      DRY

      The beauty of all of the above helper methods is that they enable us to avoid having to hard-code in URL paths within our Controller and View Logic.  If at a later point we decide to change the search URL route mapping rule back from "/Search/[query]/[page]" to "/Search/Results/[query]/[page]" or /Search/Results?query=[query]&page=[page]" we can easily do so by editing it in one place (our route registration code).  We don't need to change any code within our views or controllers to pick up the new URL (this maintaining the "DRY principle").

      Constructing Outgoing URLs from the Routing System (using Lambda BLOCKED EXPRESSION

      The previous URL helper examples took advantage of the new anonymous type support that VB and C# now support with VS 2008.  In the examples above we are using anonymous types to effectively pass a sequence of name/value pairs to use to help map the URLs (you can think of this as a cleaner way to generate dictionaries).

      In addition to passing parameters in a dynamic way using anonymous types, the ASP.NET MVC framework also supports the ability to create action routes using a strongly-typed mechanism that provides compile-time checking and intellisense for the URL helpers.  It does this using Generic types and the new VB and C# support for Lambda Expressions. 

      For example, the below anonymous type ActionLink call:

      Can also be written as:

      In addition to being slightly terser to write, this second option has the benefit of being type-safe, which means that you get compile-time checking of the expression as well as Visual Studio code intellisense (you can also use refactoring tools with it):

      Notice above how we can use intellisense to pick the Action method on the SearchController we want to use - and how the parameters are strongly-typed.  The generated URLs are all driven off of the ASP.NET MVC URL Routing system.

      You might be wondering - how the heck does this work?  If you remember eight months ago when I blogged about Lambda Expressions, I talked about how Lambda expressions could be compiled both as a code delegate, as well as to an expression tree object which can be used at runtime to analyze the Lambda expression.  With the Html.ActionLink<T> helper method we using this expression tree option and are analyzing the lambda at runtime to look up the action method it invokes as well as the parameters types, names and values that are being specified in the expression.  We can use these with the MVC Url Routing system to return the appropriate URL and associated HTML. 

      Important: When using this Lambda Expression approach we never actually execute the Controller action.  For example, the below code does not invoke the "Results" action method on our SearchController:

      Instead it just returns this HTML hyperlink:

      When this hyperlink is clicked by an end-user it will then send back a http request to the server that will invoke the SearchController's Results action method.

      Unit Testing Routes

      One of the core design principles of the ASP.NET MVC Framework is enabling great testing support.  Like the rest of the MVC framework, you can easily unit test routes and route matching rules.  The MVC Routing system can be instantiated and run independent of ASP.NET - which means you can load and unit test route patterns within any unit test library (no need to start up a web-server) and using any unit test framework (NUnit, MBUnit, MSTest, etc).

      Although you can unit test an ASP.NET MVC Application's global RouteTable mapping collection directly within your unit tests, in general it is usually a bad idea to have unit tests ever change or rely on global state.  A better pattern that you can use is to structure your route registration logic into a RegisterRoutes() helper method like below that works against a RouteCollection that is passed in as an argument (note: we will probably make this the default VS template pattern with the next preview update):

      You can then write unit tests that create their own RouteCollection instance and call the Application's RegisterRoutes() helper to register the application's route rules within it.  You can then simulate requests to the application and verify that the correct controller and actions are registered for them - without having to worry about any side-effects:

      Summary

      Hopefully this post provides some more details about how the ASP.NET MVC Routing architecture works, and how you can use it to customize the structure and layout of the URLs you publish within your ASP.NET MVC applications. 

      By default when you create a new ASP.NET MVC Web Application it will pre-define a default /[controller]/[action]/[id] routing rule that you can use (without having to manually configure or enable anything yourself).  This should enable you to build many applications without ever having to register your own custom routing rules.  But hopefully the above post has demonstrated that if you do want to custom structure your own URL formats it isn't hard to-do - and that the MVC framework provides a lot of power and flexibility in doing this.

      Hope this helps,

      Scott

    • ASP.NET AJAX Control Toolkit and Web Deployment Project Releases for VS 2008

      This week my team released updates of the ASP.NET AJAX Control Toolkit as well as the Visual Studio Web Deployment project packager.  Both of these updates are designed to work with VS 2008 and .NET 3.5.

      ASP.NET AJAX Control Toolkit

      The ASP.NET AJAX Control Toolkit is a free download and contains more than 40 additional AJAX controls and components that work on top of the core ASP.NET AJAX functionality now built-into .NET 3.5 (and available as a separate download for ASP.NET 2.0).  In addition to having Microsoft developers contribute, the project also has dozens of non-Microsoft contributors adding great features and controls. 

      The ASP.NET AJAX Control Toolkit update shipped this week fixes some issues that people were running into when using the control toolkit's extender controls with the VS 2008 Web designer.  The only change made was to adjust the version string number of the control toolkit assemblies (David Anson has more details of the change here).  I'd definitely recommend downloading the update if you are using VS 2008 or Visual Web Developer 2008 Express.

      You can also find a steady stream of articles about ASP.NET AJAX and the ASP.NET AJAX Control Toolkit via my Link Listing series (in particular check my post here for a dedicated ASP.NET AJAX link post).  Also read my previous post on using ASP.NET AJAX Control Extenders in VS 2008 to learn more about the integrated design-time support that you now get with the ASP.NET AJAX Control Toolkit in VS 2008 and Visual Web Developer 2008 Express. 

      Lastly, check out the great ASP.NET AJAX videos on the www.asp.net site here and here.

      Visual Studio 2008 Web Deployment Project Support

      Late last night my team also posted the VS 2008 Web Deployment project download option for VS 2008.  Web Deployment projects can be used with either the "Web Site" or "Web Application Project" options built-into VS 2008, and provide a few additional build, packaging and deployment options for you to use.  You can read an old tutorial post of mine here to learn more about they work.

      This week's VS 2008 Web Deployment Project download supports all of the existing features provided by the VS 2005 web deployment download.  It also adds additional support for:

      • Easily migrating VS 2005 Web Deployment Projects to VS 2008 Web Deployment Projects
      • Replacing output only if web deployment builds succeed
      • IIS7 Support

      You can learn more about this week's download here and download it directly here.  We are calling this week's download the "December CTP" so that we can incorporate feedback on the new features.  We are then going to ship the final release on the web next month.

      Hope this helps,

      Scott

    This Blog

    Syndication

    Powered by Community Server, by Telligent Systems
    '