The most basic way to pass data from the controller into the view is through the use of magic strings and a convenient dictionary called ViewData
. In this recipe, we will see how to use this easy, but dangerous, duo to shuttle data out to the far edges of our presentation layer. We will then take a quick look at why the use of magic strings and the ViewData
container put us in a fragile state and should be kept away from, if at all possible.
Note
Magic Strings? A magic string is a string that represents an object or a block of code within your source. An example of this is when referencing an action or controller name in a link. As the name of the action is string-based, refactoring the action method name might get missed in the string references. This is usually thought to be a brittle way of pointing at your code. For that reason, not using magic strings, when possible, is considered to be a more stable manner of programming in MVC (or any other framework for that matter).
The most important part of any of these recipes is to create an ASP.NET MVC 2 web application. Once that is created, we will need to do two more things—create a Product
class, and get NBuilder up and running.
The Product
class will be quite simple. We will create a new Product.cs
file and place it in the Models
folder of your MVC application.
Models/Product.cs:
public class Product { public string Sku { get; set; } public string ProductName { get; set; } public string Description { get; set; } public double Cost { get; set; } }
Getting NBuilder installed is almost as simple as the creation of the Product
class. Go to NBuilder.org/Download and download the latest version of NBuilder (I am using 2.1.9 currently). Then extract the FizzWare.NBuilder.dll
into your MVC application's bin
directory. Then add a reference to that DLL (right-click on the project, add reference, browse, and locate the FizzWare.NBuilder.dll
file in the bin
directory). That's it!
1. The first step for us to get a product displayed on a page is to create a new view page. To do this, open the
Views
folder and then open thehome
folder. Right-click on thehome
folder and select Add | View. When the Add View window pops up, enter Product in the View name box. Then click on Add.2. Once we have our new view page in place, we need to open the Home controller and add a new
Product
action so that we can handle requests for ourProduct
view. To do this, open theControllers
folder and then open theHomeController.cs
file. Just inside the class, you can create your newProduct
action method.Controllers/HomeController.cs:
public class HomeController : Controller { public ActionResult Product() { return View(); } public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); } ... }
3. Now hit F5 to verify that your
Product
action is correctly wired to yourProduct
view.If you see the Debugging Not Enabled pop-up, go ahead and click on OK!
4. Then add
Home/Product
to the end of the URL. Your URL should look something like this:http://localhost:63241/Home/Product
.Note
The port number in your URL is most likely different from the one you see here, as they are dynamically generated by default.
5. Now let's quickly wire up a product and throw it out to the view. To start, you can close the browser window. Click on the square icon in Visual Studio to stop the debugging process. Then go back to your home controller and
Product
action. Add theseusing
statements to the top of yourHomeController.cs
file.Controllers/HomeController.cs:
using FizzWare.NBuilder; using WorkingWithTheView.Models ; WorkingWithTheView.Models;
6. Then in your
Product
action you can add this line.Controllers/HomeController.cs:
public ActionResult Product() { ViewData["ProductName"] = Builder<Product> .CreateNew() .Build() .ProductName; return View(); }
7. With this code in place you can now switch to your
Views/Home/Product.aspx
file. In here, all you need to do is render theProductName
to the view. Add this code to your view.... <h2>Product</h2> <%= ViewData["ProductName"] %> ...
8. Now you should be able to hit F5 again and see the generated product name rendered in the view.
In this recipe, we created a Product
view that renders a Products
name. This was done by adding a new product view file to the Views/Home
folder. We then added a corresponding Product
action to the Home controller. The MVC framework automatically maps any requests to /Home/Product
to a Product
action on the Home controller, which then routes the user to a Product
view if no other view is specified. With that completed, we used NBuilder to generate an instance of a Product
. The Name
property of this Product
instance is used to populate the ViewData
dictionary. The ViewData
dictionary is provided by the MVC framework as a mechanism to pass data from the controller down to the view. In the view, we were then able to access the data and render it in one fell swoop by using the shorthand for Response.Write <%= %>
.
In the beginning of this section, I had mentioned that we would use magic strings and ViewData
to shuttle data from the controller to the view. As we saw earlier, the ViewData
dictionary is a collection that is used as a sort of data-transfer object to shuttle data between an action in a controller down to the view. However, you may still be wondering what a magic string is. A magic string is not really magic. This is more a name that says by using this string (ProductName
, for example) I expect you to go off and figure out what I really want. This is not magical in any way.
And this is where the fragility part of the conversation comes into play. If you reference something like Product.ProductName
in all sorts of ViewData
dictionary calls, you will find that everything works magically as expected. But then one day you will need to use a cool tool such as ReSharper to refactor Product.ProductName
to just Product.Name
. Refactoring tools don't always parse magic strings (though some do). While the tool that you used to refactor the ProductName
property to just Name
will pick up all strongly typed instances of that property, it may not find the magic strings. This will effectively break your code in such a way that you might end up with a handful of runtime errors that can be quite difficult to locate. We will cover the solution to this problem in the Creating a strongly typed view recipe.