Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Sunday, February 28, 2021

Recorded Presentation: ASP.NET MVC for Absolute Beginners - Your Secret Decoder Ring

ASP.NET MVC has a lot of conventions around routing, controllers, actions, views, and parameters. Coding-by-convention has both good and bad parts. A good part is that it can be fairly light in configuration. A bad part is that it is easy to get lost if you don't know the conventions.

In January, I had the opportunity to share with the Central Ohio .NET Developer's Group (Meetup link).

Video link:  

In this presentation, we create a new MVC project and look at the default routes, controllers, and views to get an initial understanding of some of the conventions. With that information, we can take the next steps of adding our own code -- collecting parameters and generate mazes.

The parameter collection lets us pick a maze size, the color, and a maze-generation algorithm to use.


Clicking the "Generate Maze" buttons gets us a result:


If this sounds interesting, take a look at the GitHub repo with the code and the video on YouTube:



Happy Coding!

Wednesday, August 26, 2020

CodeTour and Visual Studio Code

I've been experimenting with CodeTour, an extension for Visual Studio Code that allows you to annotate code and create a "tour" through a project.

My initial reaction is that this can be an effective education tool. 

But after using it a bit more, I can also see it as a way to document code. It sits somewhere between large comment blocks in the code and having a separate document with details. Lots of things to think about.

CodeTour in Action

If you want to see a CodeTour in action, just install the extension from the Visual Studio Marketplace (CodeTour) and grab this repository from GitHub: ASP.NET MVC Conventions. When you open the repo for the first time, it will ask if you want to run the CodeTour.


Otherwise, you can use the "CodeTour" section in the Visual Studio Code Explorer.


From there, you will be guided through a tour of ASP.NET MVC conventions based on the default template.

You can also expand the tree and jump to specific steps:



Features

There are quite a few features that I used here. 

Annotating a Line of Code
The most basic is to point to a line of code and provide some information about it.


Here we have a pop-up in the middle of the editor that allows you to provide some more information. The content is Markdown, so you can use various types of formatting.

The arrow buttons at the top of the box let you move from step to step (there are keyboard shortcuts for navigating as well).

Annotating a Block of Code
In addition to pointing to a line, you can also annotate a block of code with a highlight.


Shell and Visual Studio Code Commands
Some of the cooler features allow you to put in shell commands to run from the terminal and also commands that run from the Visual Studio Code command palette.


This has a link for "dotnet run" which will execute in the terminal (this starts the web application).

The second link will open a browser to http://localhost:5000. But instead of being just a link (which prompts whether you really want to open it), this uses a Visual Studio Code command to open the URL (so there is no extra prompt).

Here's a clip of both links in action.


Here's what the Markdown looks like:


The shell command is prefixed with ">> ". This will run that command in the terminal.

The bottom line is similar to a standard Markdown link, with the text in square brackets and the target in parentheses. But instead of having "http:", the target has "command:". 

The details for this are in the documentation under "Command links": https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour.

As a side note, I used a non-breaking space ( ) in the non-link version of the URL (the line between the clickable bits). This prevents the Markdown interpreter from automatically creating a link out of this.

Content Steps
Another feature I used is a "Content Step". This provides a block of Markdown that is not associated with a specific block of code. I used this for the introductory steps and the summary step.

Directory Steps
Sometimes we want to point at a folder rather than a code file. A "Directory Step", will open up the Visual Studio Code Explorer to a relevant folder, and you can provide annotations for that. In this case, I pointed out several of the ASP.NET folders, including "Controllers", "Views" and "Shared".

Other Features
There are some other features that I haven't used yet. You can check out what's possible in the documentation: https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour.

Wrap Up

This is interesting from an education and training perspective. In this case, I was able to take an article (The Secret Code: ASP.NET MVC Conventions) that points to a GitHub repo, and turn it into something more interactive that walks through the repo.

But this is also interesting from a documentation perspective. This could be used as a way to annotate a code base so that when a new developer comes on, they can be led through the relevant points. It can also be seen as in-line documentation for areas where we don't want to pollute our code with large comment blocks, but want something a bit better than a separate document that has all of the relevant information. This can give us an "in between" where the documentation is available with the code, but it is not directly mixed in with the code.

Take a look, and see what you can do with it.

Happy Coding!

Tuesday, February 18, 2020

The Secret Code: ASP.NET MVC Conventions

ASP.NET MVC is filled with hidden conventions: put a controller or view in a certain place and give it a special name, and it magically works. If you know the conventions, you can quickly get an application up and running. But if you don't know the secret code, all is lost.

Today, we'll look at some of the conventions used in the ASP.NET Core MVC standard template:
  • File Naming and Locations
  • Basic Routing
  • Views and Layout
This will be just enough to get you started. Once you have the basic idea, you can find lots of articles that dig into each topic. Stephen Haunts (@stephenhaunts / https://stephenhaunts.com/) and Shawn Wildermuth (@ShawnWildermuth / http://wildermuth.com/) are both good resources for deeper dives.

The code for this project is on GitHub: jeremybytes/mvc-conventions-aspnet. However, the code is from the standard ASP.NET Core MVC project template, so you can create a new project locally and see the same thing (at least with the "current" .NET Core 3.1 templates). I will use Visual Studio Code to explore the files and run the project, but you can use the editor/IDE of your choice.

New ASP.NET Core MVC Project
We'll start by creating a new ASP.NET Core MVC project. I'll use the command-line for this in PowerShell (but these commands are the same from cmd.exe or bash).

From the command line, type dotnet new mvc -n "mvc-conventions'


"dotnet new" indicates we want to create a new project, "mvc" is the template for an ASP.NET Core MVC project. The "-n "mvc-conventions"" says we want to use the name "mvc-conventions" for the project.

This creates a folder called "mvc-conventions" with our new project.


Running the Application
The template has enough code for us to run. From the command line, type "dotnet run" to start the web application. Note: be sure that you are in the "mvc-conventions" folder.


Notice that the application says it is listening at "https://localhost:5001" and "http://localhost:5000". By default, the website forwards http calls to https, so if we navigate to either of these locations, we'll end up at the https location.

Note: If you do not have a localhost developer certificate set up, you may get browser warnings when going to the https site. Take a look at this article from Scott Hanselman for how to fix this: Developing locally with ASP.NET Core under HTTPS, SSL, and Self-Signed Certs.

Here's the site in the browser:


The template site only has a couple of features. The above is the "Home" screen. We can also navigate to the "Privacy" screen by clicking one of the "Privacy" links.


The Project Files
Let's take a closer look at the generated code. I have Visual Studio Code installed. To open Visual Studio Code at the current folder, we can use "code ." on the command line.


When the project opens, you will get a popup asking to add required assets. Go ahead and click "Yes" to this. This creates a ".vscode" folder that has some settings to make things easier to run and debug from within Visual Studio Code.

Here is the structure that was created (also available from the GitHub project):


The items we'll concentrate on today are the "Controllers" folder, the "Views" folder, and the "Startup.cs" file.

A Quick Overview of MVC
Before going further, we should get a quick overview of what MVC is. MVC stands for Model-View-Controller, and it is a common application UI pattern.

The Model is the data/logic of the application. This application doesn't really have that since we're dealing with just a couple of hard-coded pages.

The Controller is responsible for interacting with the Model and then displaying a View.

The View is the UI. This is what the user sees in the browser.

This is a highly-simplified description of the elements. In the case of ASP.NET MVC, we will call an action on a controller. That action will perform some type of work (often interacting with the model) and determine what view to send back to the user.

We'll walk through this by looking at a route.

The Default Route
Routing is how we turn URLs into actions. This is a very large topic. For today, we'll just look at the default route that we get with the template.

The default route is set up in the Startup.cs file at the root level of our project (from the Startup.cs file on GitHub):


We'll break this down a little bit.

First, the pattern "{controller}/{action}/{id}" says that we're trying to parse a controller, an action, and an id from the URL.

Convention: The default route pattern is [Controller Name] / [Action Name] / [ID (optional parameter)].

So if we have a sample URL of "https://localhost:5001/Home/Index/2", we would use the "Home" controller by calling the "Index" action on it, and pass in an "id" parameter of "2".

The pattern in the code is a little more complex than what I just showed. That is because there are some default values set up. If a "controller" is not provided, then by default we use the "Home" controller. In addition, if an "action" is not provided, by default we use the "Index" action.

The "?" on the "id" specifies that this is optional. So if it is not provided, then there's no harm done.

With the defaults, that means that if we navigate to "https://localhost:5001", then it will try to call use the "Index" action on the "Home" controller (since those are the defaults).

The Controller and Action
Now that we know what controller and action to use, how does the system find it? That's where some of the conventions come in.

Convention: Controllers are located in the "Controllers" folder.

Controllers are located in the "Controllers" folder. Here's that folder in our project (you can also look at the Controllers folder on GitHub):


This has one file: HomeController.cs. Here is the code for the "HomeController" class with some of the methods collapsed (from the HomeController.cs file):


Convention: Controllers are named with the suffix "Controller".

Due to the naming conventions, if our routing is looking for the "Home" controller, it will look for a class named "HomeController". The naming of our controllers is important if we want ASP.NET Core MVC to be able to find them automatically.

So we've found the controller, what about the action "Index"?

When looking for an action, we're really looking for a function of the same name on the controller.

Convention: An Action is a function with the same name in the Controller class.

For the "Index" action, we would look for an "Index" function on the controller. In addition, the method should return an "IActionResult". We won't get into what all the valid values are for "IActionResult". Today we'll just concentrate on Views.

Here is the "Index" method on the controller (from the HomeController.cs file):


Generally, an action will perform some type of work, such as get data from the model or process form data. In this case, we only return a View without passing anything programmatically.

The next question is "How do we find the View?"

The View
As you might imagine, there are conventions around how views are named and located (just as with controllers).

Here are the views in the project (from the Views folder on GitHub -- you'll have to drill down to see all the files):



Convention: Views are in the "Views" folder with sub-folders based on the Controller name.

Under the "Views" folder in our project, we have a "Home" folder. These are the views that are associated with the HomeController. In that folder, we have 2 files, "Index.cshtml" and "Privacy.cshtml".

Convention: Views are named after the corresponding Action in the Controller.

The Views correspond to 2 of the actions on the HomeController: Index and Privacy.

So when the "Index" action returns "View()", it uses the "Index.cshtml" file in the "Home" folder under "Views".

Technical note: these conventions are based on how the ASP.NET MVC infrastructure searches for views. First, it looks in the "Views" subfolder that matches the Controller name. If it cannot find a matching view there, then it looks in the "Shared" subfolder. As you dive deeper into ASP.NET MVC, you can read articles that go into this in more detail.

Here's the code for the "Index" view (from the Index.cshtml file):


This has the code that is unique to this page, but it is incomplete. It's just a "div", not a complete web page. (We'll get back to what the "@" section means in just a bit.)

The rest of the page is part of a shared layout.

The Layout
If we look at the "Views" folder again, we see that there is also a "Shared" sub-folder.


This contains views that are not particular to any controller (such as the "Error" view). But it also has the "_Layout.cshtml" file. This is what fills in the rest of the page that we see in the browser.

Here is part of the content from the layout (from the _Layout.cshtml file):


This file has the markup for the headers and footers of the page (including the menus). It also brings in style sheets and Bootstrap.

Injecting the Body of the View
The important bit for us is the code "@RenderBody()".

In .cshtml files, the "@" means "there's some C# code coming!" 

The extension of the file (cshtml) indicates that it is a mixture of C# (cs) and HTML (html).

So when we have "@RenderBody()", this is an indication that the "RenderBody" method should be run. "RenderBody" is an included helper method, and this is what puts the custom view markup into the page.

So in our case, the "div" that is in the Index.cshtml file ends up inside the "main" tag from the layout file.

Other Injected Values
The layout is not limited to "@RenderBody()". The custom views can also provide data to the layout through ViewData.

Let's go back to the Index View for a moment (from the Index.cshtml file):


Notice the "@" section at the top of the page. As we saw earlier, this indicates a section of C# code. In this case, it is blocked by curly braces; everything inside the braces is considered the C# code. "ViewData" is a dictionary that lets us set up name/value pairs. In this case, we have the "Title" for the page.

In the header section of the layout page, we can see how this is used (from the _Layout.cshtml file):


Notice that inside the "title" tag of the page head, there is "@ViewData["Title"]". Again, the "@" indicates that this is C# code. This takes the value from the Index.cshtml ViewData and puts it in here.

So when we view the page, we can see the page title set in the browser tab:


The value is "Home Page - mvc_conventions".

Note: Our pages do not need to use _Layout.cshtml. We can have some pages use the layout and some pages that don't. Or we can eliminate the layout completely. If you're interested, you can find articles that talk about this in more detail.

Routing to Other Actions
If we click on one of the "Privacy" links, we can see the route to that page:


The URL is "https://localhost:5001/Home/Privacy". Based on what we've seen, we should be able to figure out where this goes.

If we go back to the default route: Controller / Action / Optional ID, we can translate this URL to using the "Privacy" action on the "Home" controller.

The "Privacy" action translates into the "Privacy()" function on the controller (from the HomeController.cs file):


This returns a view just like the Index action.

But instead of using the "Index.cshtml" file, it uses the "Privacy.cshtml" file. Here is the code for that (from the Privacy.cshtml file):


This has ViewData specified with a title as well. The layout puts this into the "title" tag of the page. But the Privacy View also uses it in an "h1" tag on the page itself.

Using ViewData is one way to get data from the Controller to a View, but that's outside the scope of what we're looking at today.

Adding Your Own Pages
With an understanding of the conventions that are part of ASP.NET MVC, we can add our own pages fairly easily. If we wanted to add a page with a catalog of products, we would create a class called "CatalogController" and put it in the "Controllers" folder.

Then in the "CatalogController" class, we could add an "Index" method that calls into the Model to get a list of products from a database, and return that data along with the View.

To create the view, we can add an "Index.cshtml" file to a newly created "Catalog" folder under "Views".

If we follow the naming conventions, then we do not have to do anything special to wire the page up. The conventions take care of all of that for us. We would just access it with "https://locahost:5001/Catalog" (remembering that "Index" is the default action).

We could even take this a step further and create a "Product" action that takes an "id" parameter. This could get a product from the Model based on the id and then display it in a custom View. This could be accessed with "https://localhost:5001/Catalog/Product/24". And if the default routes don't work for us, we can create custom routes as well.

These are the conventions I used to make the web front end for my maze generation project. You can read more about that and dive into some basics about parameters here: Building a Web Front-End to Show Mazes in ASP.NET Core MVC.

Wrap Up
ASP.NET Core MVC (as well as ASP.NET MVC on .NET Framework) have a lot of conventions. This saves us from writing a lot of configuration code to wire things together. But we do need to be aware of the conventions in order for our pages to work properly.

Summary of Conventions:
  • The default route pattern is [Controller Name] / [Action Name] / [ID (optional parameter)].
  • Controllers are located in the "Controllers" folder.
  • Controllers are named with the suffix "Controller".
  • An Action is a function with the same name in the Controller class.
  • Views are in the "Views" folder with sub-folders based on the Controller name.
  • Views are named after the corresponding Action in the Controller.
Other Stuff:
  • In .cshtml files, the "@" means "there's some C# code coming!"
With these conventions in hand, it is easier to understand what is happening in existing ASP.NET MVC web projects that you need to modify. And it is also a good starting point to take a deeper dive into all things MVC.

Happy Coding!

Tuesday, August 13, 2013

Book Review: Pro ASP.NET MVC 4

It's been a while since my last book review, and there are a couple of reasons for that. First, I've been really busy this summer (between speaking engagements and producing 2 Pluralsight courses). And second, because I picked a 700 page book as my next read: Pro ASP.NET MVC 4 by Adam Freeman (Amazon link). The good news is that this was a very good read.

Two Parts
I really like the layout of this book.  It's split into two primary parts.

Part 1 covers the first 300 pages: Introducing ASP.NET MVC 4.  After some introductory chapters (about the MVC pattern, the Razor view engine, and some other tools), Freeman leads us through the process of building an on-line store. During each of these steps, more and more features are explored through the code. This includes things like strongly-typed views, controllers and actions, routing, dependency injection, validation, and security.

These are all "just enough" explanation to get the application to do what we need it to do. This seems like a very relevant example, and I found it helpful to follow along (sometimes typing things in and sometimes just going through the code for the completed project -- although I'll admit to having a run-in with Entity Framework not behaving as I expected it to).

Part 2 is the rest of the book and dives into the details. This makes for an excellent reference and covers pretty much all of the topics: URL Routing, Controllers, Actions, Filters, Views, Helper Methods, Model Binding, Model Validation, and Bundles.

Each of these chapters starts out by looking at the standard "in-the-box" functionality and then goes on to show how you can either customize the behavior or completely replace it with your own objects. Another thing I like is relevant warnings. For example, there may be a section that shows how to put validation into the Controller, but then emphasizes that it probably doesn't belong there; it really belongs in the Model itself or through custom model binding (in order to preserve the separation of concerns recommended by the MVC pattern).

Some Complaints (not mine)
I want to address some complaints that have shown up in some reviews.  But first, we need a little history. I own Pro ASP.NET MVC 2 Framework by Steven Sanderson. This is the 2nd edition of this same book.

[Editor's Note: I actually did a review of this book in 2011: Book Review: Pro ASP.NET MVC 2 Framework]

Next comes, Pro ASP.NET MVC 3 Framework by Steven Sanderson and Adam Freeman. This is the 3rd edition (which I do not have). There were some complaints that the 2nd and 3rd editions had much of the same material and didn't really show the differences in the versions. Personally, I don't have a problem with that. I see this as a reference for whatever current version is referred to. There are other references to see "What's New in MVC 3" or whatever.

Pro ASP.NET MVC 4 by Adam Freeman (the book we're looking at here) is the 4th edition. This has a lot of duplicated information from previous editions (the Sports Store example is the same example as was used in the MVC 2 book, but with some obvious updates for the new features). As mentioned above, I don't see the duplication as a drawback -- this is a 700 page reference book.

A Few Quirks
With that said, there are a few quirks to the book that are minorly distracting. This is to be expected in any technical book of this size; however, since this is the 4th edition, I would have hoped that more of these would be worked out.

One strange thing is that it looks like there was a search-and-replace done for several words to facilitate the diagrams and code samples.  For example, in Chapter 16, there is a sentence with the phrase "...which isn't suiTable 16-for all action methods."  I'm sure this should read "...which isn't suitable for all action methods", but the word "table" was replaced with "Table 16-".  This also happened with "figure" as in "... you can conFigure 17-the settings of the default factory..."

Another quirk has to do with the history of the book. As mentioned above, the 3rd edition was co-authored by Adam Freeman and Steven Sanderson. A few vestiges still exist in the 4th edition. For example, there are a few places that say, "We both agree that..." which seems a little strange if you don't know the history of the book. In addition, other books by both Freeman and Sanderson are referenced for more details. Again, it seems a little strange based on the "voice" of the author.

But none of these items would keep me from recommending this book.

Wrap Up
Pro ASP.NET MVC 4 is a complete reference of the MVC framework. I really like the practical walk-through example that takes up Part 1 of the book. And I also like the deeper dives into each feature that is covered in Part 2. It's nice to know that I can replace the view engine if I really want to (although I really don't see that happening for me).

I'm a big fan of ASP.NET MVC (especially since I spent so much time working/fighting with WebForms). It's nice to see that many of the features (such as URL Routing and Script Bundling) are making their way into the base ASP.NET libraries so that we can use them regardless of how we build our websites.

In the near future, I need to revamp my website. ASP.NET MVC is definitely a contender technology. But I may simply use it as a framework to deploy a mainly HTML/JavaScript site. We'll see what happens. One of the big challenges is to create some "pretty" URLs without breaking any of the existing links that I have scattered across the internet.

But back on topic, if you need a reference for ASP.NET MVC, I would definitely recommend this book.

Happy Coding!

Sunday, March 18, 2012

Book Review: Programming Razor

Programming Razor by Jess Chadwick (O'Reilly) is a short book at only 99 pages, but it is long enough to provide the information that I was looking for.  The book covers using Razor (a web templating syntax) with ASP.NET MVC and WebMatrix.  My background: I've done some ASP.NET MVC programming (with the Web Forms view engine) and wanted to get started using the Razor view engine.  Note: I got this book for "free" as a user group raffle prize, so I did not pay the cover price (just the price of the raffle tickets).

This book assumes that you are familiar with the development environments (WebMatrix and ASP.NET MVC).  It only covers how Razor can be used with these tools and does not give you an introduction to the tools themselves.  Again, this is what I was looking for -- how to use Razor syntax.

The parts I found most interesting were in the introduction.  This chapter shows how you (as the developer) mix HTML markup with C# (or VB) code to create your web pages.  The introduction describes how the Razor parser figures out which parts are markup and which parts are code.  It also shows how to give the Razor parser hints on differentiating the markup and code in areas that may be ambiguous.  This really gave me the information that I needed to move forward with Razor.

The next two chapters were about using Razor with WebMatrix to build a blog.  Fortunately, I had just attended a user group where Alice Pang presented WebMatrix (Alice is a WebMatrix Technical Evangelist for Microsoft).  Before that session, I really didn't know what WebMatrix was for or how to use it.  If you are interested in WebMatrix, Alice's blog is a great place to get started: http://blogs.msdn.com/b/alicerp/.

With that said, unfortunately, the examples in Programming Razor are a bit of a mess.  I tried to follow along with the blog sample in WebMatrix and ran into some issues once the database portions hit.  The book does not give enough information about the database fields; it shows a screenshot of the table column definitions, but not the details.  This table definition has 5 columns (all of them non-nullable), yet the SQL in the code only populates 3 of the columns.  There is a separate code-snippet that shows how to make sure one of the other columns is populated, but this is never incorporated into the main code samples.  I was hoping to be able to follow the code samples to build a working (simple) app but was unable to.  I also had some build issues here; if I was more familiar with WebMatrix, I may have been able to troubleshoot my way out of this.  After this bit of frustration, I did not try to follow any further code samples.

The next chapter is about using Razor with ASP.NET MVC 3.  This chapter walked through the steps of building blog pages similar to the WebMatrix sample.  I came across some inconsistencies in the code samples in this chapter as well.  For example, there were simple code blocks described and the sample would include code that was not described until the following section.  Although I did not follow along with the code samples, I could see the inconsistencies that cropped up.

The final two chapters cover the Razor API and Advanced Techniques.  I must admit that I sort of skimmed through these chapters.  I was more interested in the basics of Razor which were described in the previous chapters, and not so much on how I can pre-compile my templates or extend the default Razor view classes.

So, overall, I did get the information that I was looking for from Programming Razor, however, I am very disappointed with the quality of the code samples.  Had I paid full price for this ($19.99), I would have been rather upset.  With that said, had I gotten the book for $7 or $8, I probably would have been satisfied with the value.  I think the book does have value, and I hope that there is a version with more consistent sample code available in the future.

Happy Coding!

Monday, January 3, 2011

Book Review: Pro ASP.NET MVC 2 Framework

I just finished reading Pro ASP.NET MVC 2 Framework by Steven Sanderson (Apress).  What I found was a good introduction to ASP.NET MVC as well as a deeper dive into the majority of the features.

This is labeled as "Intermediate to Advanced".  It assumes that you are familiar with C# and .NET, but it doesn't expect you to be an ASP.NET WebForms programmer.  If you are familiar with web technologies (HTML, CSS, Javascript), then you should be just fine.  And although this is covering the 2nd version of the ASP.NET MVC framework, it does not assume that you have any prior knowledge of version 1.

There are several things I liked about this book.  First, it is very approachable.  The tone is inviting and easy to understand.  Next, the code samples are thorough.  Since ASP.NET MVC 2 can be used with either .NET 3.5 or .NET 4.0, it shows how to use the framework in either environment, and the differences are pointed out where the environments vary.  Finally, the overall organization makes you want to read more.

Part 1 includes an introduction to ASP.NET MVC 2 and a sample application showing a real-world (although simplified) implementation of the framework.  Since the MVC pattern lends itself to unit testing and test-driven development (TDD), the book also shows a few useful techniques including using dependency injection and mocking with unit testing.  And to keep things more accessible, Sanderson uses free tools (such as NTest) for the examples since not all versions of Visual Studio include unit testing.

Part 2 takes all of the features that were introduced in Part 1 and goes into them in detail.  This includes all of the core features of ASP.NET MVC including Routing, Controllers, Actions, Views, and Models.  But going beyond just a description of using what's "in the box", the book also talks about how you can extend the framework yourself, such as by creating custom controller classes, filters, or even your own view engine.  In addition, it gives a number of helpful techniques for putting together user interfaces including a trip into the world of AJAX and jQuery.

Part 3 covers some of the nitty-gritty details including Security and Deployment.  This is where the world of ASP.NET MVC and WebForms starts to overlap.  And this last part also goes through many of the features of the standard ASP.NET platform that you will want to make use of in your MVC applications.

Unlike my previous review of an ASP.NET MVC book, I highly recommend this book.  The quality of the book is very high.  There are few errors (no book is perfect) and the code samples are well done and complete.  I have become a big fan of ASP.NET MVC.  Although it is not the "best" or "only" way to write web applications, it is a great tool to have in the toolbox.  I can think of a number of applications from my past that would have been much more elegant using ASP.NET MVC.

If you are curious and want to get started in the technology, Pro ASP.NET MVC2 Framework is a great way to go.  Part 1 will give you a taste of the feature; Part 2 will take you through each one in depth; and Part 3 will show how MVC integrates with the rest of the ASP.NET framework.

Happy Coding!

Thursday, April 29, 2010

More Thoughts on ASP.NET MVC

I've had two months to work with ASP.NET MVC since my last post on the topic.  Since then, I've worked through two projects and have picked up some good experience.  There are plenty of pros and cons (more pros in my opinion).  Let's take a look at how it differs from other .NET web technologies.

Routing
ASP.NET MVC is more than just Model-View-Controller pattern (the MVC which lends its name).  One of the key features is routing.  With routing, a URL does not point to a physical resource on the server.  Instead, it contains information that allows the Controller to instantiate the appropriate Model and send the data to a specific View.  You're probably familiar with the pattern.  Let's take a look at the URL for my previous post: http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html.

The first part is (http://jeremybytes.blogspot.com) points to the server.  The next part (2010) would normally be parsed as a physical path (file folder) on the server.  But instead, it is a parameter that references the year of the post.  The same is true of the "02" portion (the original post is from February 2010).  The final part is the name of the article.  Now, I can't tell you what lies behind the blogspot link or how it is parsed, but I'm pretty sure that there are no physical directories that refer to the year and month of my posts.

You use this same type of routing in the ASP.NET MVC world.  The default is for a URL to take the form of {controller}/{action}/{id}, but you can alter this default implementation however you like.  As an example: http://www.example.com/sales/customer/217.  This would call the "Sales" controller and ask for Customer #217.

As mentioned previously, this is an "action-first" or "resource-first" model (as opposed to WebForms "page-first" model).  I say "action" or "resource" because that will depend on what you are doing.  In the above example, we are requesting a specific Customer resource.  But we could just as well be requesting an action, such as "UpdateCustomer".

This strikes me as very REST-ful, although that is a topic for another time.  The good news for those who like the idea of routing but aren't ready to dive into the rest of ASP.NET MVC: Routing is included in ASP.NET 4.0 (it's actually also available somewhat in 3.5 but requires some extra work).

ASP.NET MVC vs. WebForms: Repeaters
I spent 3 years developing WebForms apps, so I've tried quite a few different techniques for displaying data.  The control I ended up liking best is the Repeater.  This gives me the most flexibility in laying out my data.  But it does have one severe limitation: you cannot nest Repeaters.

The idea of a Repeater is that it will loop through your data set and "repeat" a specified section for each record.  This is fine for single level lists, but it gets more complex when you have parent-child relationships.

Let's say that I have data that includes Category, Sub-Category, and Details.  I only want to display the Category label at the top of each Category (not on each record).  The same is true for Sub-Category.  But since I can't nest Repeaters, that means that I must include Category, Sub-Category, and Detail in every single one of my records (flattened data rather than a hierarchy).  Then, to get the display that I want, I hook into the Event that runs before displaying each record.  In that event handler, I check to see if the current Category is the same as the Category of the previous record.  If so, then I suppress (hide) the Category display.  Same for Sub-Category.  This creates quite a bit of messy, conditional code.

ASP.NET MVC handles this situation entirely different.  You are much closer to the metal.  So, if I wanted to implement the above scenario, it's quite a bit more elegant.  In the View, I simply have a foreach loop that goes through all of the Categories and displays the Category header.  Inside there, I have a nested loop that goes through the Sub-Categories and displays that.  And inside there, I have a nested loop that goes through the details.  This means that I can have a much more natural structure to my data (Model) with a parent-child-grandchild relationship.  Add some LINQy goodness, and you have an easily understandable solution without the messy conditionals.

ASP.NET MVC vs. WebForms: File Size
Yes, file size is still important -- just take a look at how prominent smart phones and other mobile devices are becoming.  I took an existing WebForms application and converted it to ASP.NET MVC.  This was a proof-of-concept so I could try out the technologies.  Since the existing application had a well-defined business layer and clear separation from the UI, it was easy to put the ASP.NET MVC front end in place.

Here's what I found: a particular page on the WebForms apps that was 24KB was only 9KB in the ASP.NET MVC version!

I know your initial reaction: just turn off ViewState, moron.  But ViewState was turned off.  The WebForms page is so much bigger because it uses server-generated names for all of the controls.  This can look like "ctl00_mainRepeater_headerLabel_001".  When you multiply this by the number of controls for each record and the number of records in the data set, it all adds up.

Conversely, the majority of the ASP.NET MVC output is text -- the equivalent of using a Response.Write instead of using a server-side control.  When you look at the output (view source in the browser), it looks like hand-coded HTML rather than machine-generated code.  This will vary depending on how you code up your Views, of course.  My experience is that the output is pretty straight forward compared to WebForms output.

ASP.NET MVC vs. Silverlight
I won't really get into this debate.  Both technologies have their uses and benefits.  I was recently listening to .NET Rocks! and heard about a "challenge" that took place at the Visual Studio 2010 Launch Event.  Apparently Phil Haack (and team) and Rocky Lhotka (and team) were tasked with creating an application in ASP.NET MVC and Silverlight, respectively.  I have a great deal of respect for both of these guys, so I'll just leave that discussion there.

After using Silverlight myself, I was determined that I would never create another WebForms app again (the programming style is just so much more natural).  But there is a problem (mentioned above): mobile users.

The reason that I started using ASP.NET MVC is because I needed to create a solution for Blackberry users.  And I'm not talking about the shiny-new Blackberry Bolds.  I'm talking about (relatively) old devices with browsers that are a step above WAP.  Obviously, Silverlight was not an option.  ASP.NET MVC, however, allowed me to put together a clean and efficient application.

One Last Thing: Parameters
There are a number of things I like about ASP.NET MVC, but I'll wrap up with one item: Action parameters.  The ASP.NET MVC framework does everything it can to automatically pull in the parameters for you.

Let's say that I have an Action (method) like this: UpdateCustomer(int Id, string firstName, string lastName).  When this method gets called, the framework tries to populate the parameters from the following locations:
  • Routing Parameters: These are the parameters that appear as part of the URL "path", such as the "217" in the Customer example above.
  • Query String: These are additional parameters that are part of the URL query string.  These are separated from the rest of the URL with a question mark and take the form name=value (separated by ampersands).
  • Form Data: These are pulled from fields that are posted back in a form.
  • Post Parameters: These are the parameters provided as part of a POST (not necessarily part of a form).
  • Header Information: These items can be pulled from the request header.
If the framework can find matching, case-insensitive names that match the parameter names, it will pass them through to your method.  There's something about this that strikes me as very cool -- anything that makes my life easier is good.

Wrap Up
I've grown to like ASP.NET MVC.  At a later date, I'll put together a case study with my actual code to give you a better idea of exactly how the technology works.  For now, we'll just stay with what we've discussed so far.

ASP.NET MVC 2 is now shipping as part of Visual Studio 2010.  I've only taken a cursory look at it, but it seems to have added some good features to make views even easier and cleaner to generate.  Plus, having it included in Visual Studio means that other members of your team will also have it available without having to install the bits separately.  If you're doing web programming, this is definitely something to look into.

Happy Coding!

Monday, March 1, 2010

Book Review: ASP.NET MVC Framework Unleashed

I just finished reading ASP.NET MVC Framework Unleased by Stephen Walther.  It was an extremely fast read: I finished it in a little under two weeks.  Unfortunately, I was able to finish it so quickly because it contained very little information.  I was rather disappointed by the content.  I really don't like giving bad reviews, but I feel like I should get my thoughts down for other folks who may be interested in this topic.  Please note, this is a review of the book itself, not the underlying ASP.NET MVC technology.

Beginner, Intermediate, or Advanced?
My biggest problem with Unleashed is that it cannot decide what level it is targeted at.  The cover lists it as "User Level: Intermediate-Advanced," but the actual content seems to jump from one level to another.  For example, there are step-by-step instructions on configuring and using the ASP.NET Membership Database (ASPNETDB.mdf).  I would consider this to be "beginner" level content.  For the majority of real-world applications, you will not use the ASPNETDB.mdf database for your user authentication / authorization, instead going for a more robust security model such as implementing a custom MembershipProvider.  This is not covered, however.

But the text does not qualify as Intermediate or Advanced as there is very little actual content.  The majority of the book is code samples.  Code samples are generally a good thing, but the code samples here are full-files.  This means that when looking at the various elements (such as Views and Controllers), you end up seeing the same "boiler-plate" code over and over again.  Many times there are only a few unique lines of code in a 30 line listing.  In addition, descriptions of the code samples are limited to a paragraph or two with no in-depth description of the concepts at hand.  This is combined with listings in both C# and VB (again, not necessarily a bad thing).  I often felt like I was "skimming" a 30 page chapter in just 10 minutes or so due to the use of code samples and lack of description.

As a final example, there are 2 chapters devoted to AJAX and jQuery.  In the introduction to the book, the author assumes that the reader is familiar with HTML and .NET (either C# or VB).  However, it does not mention AJAX or jQuery as pre-requisites.  AJAX is used much differently in ASP.NET MVC than it is in Web Forms, yet there is no discussion of those differences.  There is just a handful of samples with little explanation.

Lack of Focus
Another problem is the lack of focus.  ASP.NET MVC has many unique features, but many of the concepts are shared with ASP.NET Web Forms and the .NET framework at large.  I wanted the book to focus on the concepts that differ from non-ASP.NET MVC applications, but there was a lot of overlap.

To expand on the example above (the Membership database), the security concepts (users, roles, principles, etc.) are the same as ASP.NET Web Forms applications, but there were several large sections dedicated to authentication.  And as noted above, this was only at the "beginner" level and did not touch on intermediate or advanced topics.

As another example, Unleashed spends a lot of time with the Entity Framework.  There are step-by-step instructions on creating a SQL Express database and setting up Entity Framework entities.  In addition, it also spends a bit of time talking about the Repository pattern and Service layers of the application.  These all related to the "M" (Model) of MVC.  But the point of the "M" is that you can implement your model in an infinite number of ways.  Again, this may be appropriate for a "beginner" level book, but it should go beyond merely mentioning other options if it is trying to be something more.

Ironically, I think that the topic covered best by this book is Test Driven Development (TDD).  Throughout the text, there is a focus on the "Red / Green / Refactor" methodology of TDD.  And the final part of the book (6 chapters on building a sample application) is a very good walkthrough of using the test-first method to fulfill the use cases.  Had this book been called Test Driven Development with ASP.NET MVC, I would probably give this book a much better review.

Summary
Ultimately, the only reason that I was able to follow this book is because I went through ASP.NET MVC training.  But the reason that I purchased the book was so that I could have a reference with more detail.  As an example, I was looking for details on HTML Helpers, both the helpers "in the box" and custom helpers.  The book has a few mentions of the existing helpers, but does not go into any detail on the options and parameters available.  As for creating custom helpers, there is an example of it, but nothing much beyond the sample code.

I really don't like giving bad reviews.  I realize that putting any technical book together is a lot of work.  However, technical books are also my life-blood.  They are my primary source of in-depth learning.  In addition, they are quite expensive.  I do have enough information to complete my project (which was the primary goal of training + book), but I'm still looking for a good reference book.  Since ASP.NET MVC version 2 is just around the corner (releasing with .NET 4.0 in April), I'll probably hold out before purchasing another.

In working with ASP.NET MVC, I'm becoming a fan of it.  So, I'll be posting more about the technology topic in the future.  I'll also keep you informed of other useful resources that I run across.

[Update: I have found a good book on this topic: Pro ASP.NET MVC 4 by Adam Freeman. You can see my review here: Book Review: Pro ASP.NET MVC 4.]

Happy Coding!

Tuesday, February 23, 2010

New to Me: ASP.NET MVC

ASP.NET MVC was New 18 Months Ago
I first heard about ASP.NET MVC in October 2008 (at the VSLive! conference).  Scott Hanselman gave a keynote that presented an overview and announced the beta release.  At that point, it looked interesting, but with all of the new technologies that have been thrown at us over the last several years, I couldn't devote any time to look into it.  Plus, I was comfortable with WebForms, having spent the previous 3 years developing fairly significant web apps.

So, here we are a year and a half later.  I was struggling with a project at work.  I knew that I could accomplish the task with WebForms, but all of my UI designs that I had worked through on the whiteboard seemed to come out as a mess.  I had a nagging feeling that ASP.NET MVC was the solution to this problem.  I took some time to look into it some more, and it turns out that it was the right direction.

Why ASP.NET MVC was the Answer
My main problem is that I needed to present data to the user in a different format depending on the record type.  And I wouldn't know the record type until run time.  ASP.NET WebForms is a "page first" model.  This means that the user requests a particular page (through a URL).  The page is then processed on the server which then presents the output to the user.  ASP.NET MVC is an "action first" model.  This means that instead of requesting a physical page, the user requests an action (also through a URL).  This action is processed by a Controller.  In my situation, the Controller can instantiate the Model (from my business layer) and then, based on the record type, can present the specific View (aspx page) that is appropriate.

So, I've taken a crash course in ASP.NET MVC.  After going through some on-line training and working through a simple test app, I'm convinced that this is the right solution for this particular project.  The design is much cleaner and will be easier to maintain.

Resources
I was fortunate enough to win a 1-year subscription to the Pluralsight OnDemand! library.  In the library is a 10 hour on-line course for ASP.NET MVC, and I took a couple of days last week to go through it.  This was an excellent resource.  (If you are interested in trying Pluralsight OnDemand! yourself, just stop by the website; they offer 7-day trial subscriptions if you drop them a note.)

In addition, I picked up "ASP.NET MVC Framework Unleashed" by Stephen Walther as a printed reference.  I'm still working my way through the book, but I've found a lot of useful information so far.

More to Come
Stay tuned for more to come.  My project at work is still in progress.  I'll have a lot of learnings from it (as I do with most of my projects).  When I run across interesting items, good tips, and pitfalls, I'll be sure to post them here.

Happy Coding!