Book Image

ASP.NET MVC 2 Cookbook

Book Image

ASP.NET MVC 2 Cookbook

Overview of this book

ASP.NET MVC, one of the latest web development platforms from Microsoft, brings the power of MVC programming to ASP.NET development. It simplifies the task of application development and maintenance for developers. However, ASP.NET MVC is filled with so many features that developers end up looking for solutions to the many problems that are encountered in their routine development tasks.ASP.NET MVC 2 Cookbook will provide solutions for the very specific problems that are encountered while developing applications with the ASP.NET MVC platform. It consists of many recipes containing step-by-step instructions that guide developers to effectively use the wide array of tools and features of ASP.NET MVC platform for web development ASP.NET MVC Cookbook is a collection of recipes that will help you to perform your routine development tasks with ease using the ASP.NET MVC platform. In this book you will be walked through the solution to several specific web application development problems. Each recipe will walk you through the creation of a web application, setting up any Visual Studio project requirements, adding in any external tools, and finally the programming steps needed to solve the problem. The focus of the book is to describe the solution from start to finish. The book starts off with recipes that demonstrate how to work effectively with views and controllers – two of the most important ingredients of the ASP.NET MVC framework. It then gradually moves on to cover many advanced routing techniques. Considering the importance of having a consistent structure to the site, the book contains recipes to show how to build a consistent UI and control its look with master pages. It also contains a chapter that is packed with many recipes that demonstrate how to gain control of data within a view. As the book progresses through some exciting recipes on performing complex tasks with forms, you will discover how easy it is to work with forms to jazz up the look of your web site. Building large applications with ease is one of the prime features of the MVC model. Therefore, this book also focuses on tools and features that make building large applications easier to manage. As data plays an important role in the MVC architecture, there are ample recipes dedicated to cover data validation, access, and storage techniques. Finally, the book demonstrates how to enhance the user experience of your visitors by controlling the data at the application, session, caching, and cookie level. By the end of this book, you will have explored a wide array of tools and features available with the ASP.NET MVC platform
Table of Contents (16 chapters)
ASP.NET MVC 2 Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface

Using a partial view to segment view code


Oftentimes, you will encounter a scenario where your view starts to get a bit overwhelming. This might happen in the case of a shopping cart where you are displaying the items in a customer's cart, along with suggested products, products from their wish list, and various other items pertaining to a customer's order. In order to simplify a complex view of this nature, you might choose to put individual concerns of the larger view into separate partial views to keep the code of your view segments nice and small. You can then reassemble the partial views into one complex view.

How to do it...

  1. 1. Start by creating a new MVC application.

  2. 2. Then we will create a quick (simple) object model that will contain a Cart, Address, Product, Account, OrderHeader, and LineItem, which we will use to populate a cart display page.

    Models/Cart.cs:

    public class Cart
    {
    public OrderHeader Header { get; set; }
    public List<LineItem> Items { get; set; }
    public double Total
    {
    get { return Items.Sum(i => i.SubTotal); }
    }
    }
    

    Models/Address.cs:

    public class Address
    {
    public string Street1 { get; set; }
    public string Street2 { get; set; }
    public string City { get; set; }
    public int Zip { get; set; }
    public string State { get; set; }
    }
    

    Models/Product.cs:

    public class Product
    {
    public double Price { get; set; }
    public string Name { get; set; }
    public double Tax { get; set; }
    }
    

    Models/Account.cs:

    public class Account
    {
    public string Username { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    }
    

    Models/OrderHeader.cs:

    public class OrderHeader
    {
    public Account Account { get; set; }
    public Address Billing { get; set; }
    public Address Shipping { get; set; }
    }
    

    Models/LineItem.cs:

    public class LineItem
    {
    public Product Product { get; set; }
    public int Quantity { get; set; }
    public double SubTotal
    {
    get
    {
    return ((Product.Price * Product.Tax) + Product.Price) * Quantity;
    }
    }
    }
    
  3. 3. With this model created, we are now ready to create some fake data. We will do this by creating a CartFactory class, which we will use to generate the data and create a fully populated instance of our Cart object. We will create a GetCart method where we will create an instance of all the classes that we need to display in our cart.

    Models/CartFactory.cs:

    public Cart GetCart()
    {
    Cart c = new Cart();
    c.Header = new OrderHeader();
    c.Header.Account = new Account()
    {
    Email = "[email protected]",
    FirstName = "Andrew",
    LastName = "Siemer",
    Username = "asiemer"
    };
    c.Header.Billing = new Address()
    {
    City = "Lancaster",
    State = "CA",
    Street1 = "Some Street",
    Street2 = "Apt 2",
    Zip = 93536
    };
    c.Header.Shipping = new Address()
    {
    City = "Fresno",
    State = "CA",
    Street1 = "This street",
    Street2 = "Front step",
    Zip = 93536
    };
    List<LineItem> items = new List<LineItem>();
    for (int i = 0; i < 10; i++)
    {
    Product p = new Product();
    p.Name = "Product " + i;
    p.Price = 2*i;
    p.Tax = .0875;
    LineItem li = new LineItem();
    li.Product = p;
    li.Quantity = i;
    items.Add(li);
    }
    c.Items = items;
    return c;
    }
    
  4. 4. Now that we have our model and a factory class to generate the data that we need, we are ready to start creating the partial views we need. While we could manually create views for each of our objects, there is a much quicker way—we can create actions in our HomeController that returns an instance of an object from which we can generate a View. By doing this, we can quickly generate the markup that is required to display each of our Cart classes. To do this, open up the HomeController and add an Address() ActionResult. In this method, we will return a new instance of Address.

    Controllers/HomeController.cs:

    public ActionResult Address()
    {
    return View(new Address());
    }
    
  5. 5. Then we can generate a new partial Address details view that is strongly typed, based on the Address model.

    Views/Home/Address.ascx:

    <fieldset>
    <legend><%: ViewData["AddressType"] %></legend>
    <div class="display-label">Street1</div>
    <div class="display-field"><%: Model.Street1 %></div>
    <div class="display-label">Street2</div>
    <div class="display-field"><%: Model.Street2 %></div>
    <div class="display-label">City</div>
    <div class="display-field"><%: Model.City %></div>
    <div class="display-label">State</div>
    <div class="display-field"><%: Model.State %></div>
    <div class="display-label">Zip</div>
    <div class="display-field"><%: Model.Zip %></div>
    </fieldset>
    
  6. 6. Now we can do the same thing for a list of Cart items. We will add an action called Items in the HomeController that returns a List<LineItem>.

    Controllers/HomeController.cs:

    public ActionResult Items()
    {
    return View(new List<LineItem>());
    }
    
  7. 7. Then we can generate another strongly typed partial view called Items that will be based on an enumerable list of LineItem. We will also add a couple of columns to the generated view to display the name and price.

    Views/Home/Items.aspx:

    <table style="width:600px;">
    <tr>
    <th></th>
    <th>
    Name
    </th>
    <th>
    Price
    </th>
    <th>
    Quantity
    </th>
    <th>
    Sub Total
    </th>
    </tr>
    <% foreach (var item in Model) { %>
    <tr>
    <td>
    Delete
    </td>
    <td>
    <%: item.Product.Name %>
    </td>
    <td>
    <%: String.Format("{0:C}", item.Product.Price) %>
    </td>
    <td>
    <%: item.Quantity %>
    </td>
    <td>
    <%: String.Format("{0:C}", item.SubTotal) %>
    </td>
    </tr>
    <% } %>
    </table>
    
  8. 8. With our partial views created and the ability to get a populated Cart class, we are now ready to display our shopping cart and all of its complexity. We will start by adding another ActionResult called DisplayCart. This result will return a new instance of a Cart, which we will get from our CartFactory class that we created earlier.

    Controllers/HomeController.cs:

    public ActionResult DisplayCart()
    {
    Cart c = new CartFactory().GetCart();
    return View(c);
    }
    
  9. 9. Then we can generate a strongly typed empty view called DisplayCart. Inside of this view we will display the user's first and last name, as well as their e-mail address. We will then load the Address partial view and pass in the billing address. Next we will load the Address partial view and pass in the shipping address. The last view we will load is the Items partial view, which we will pass in the collection of LineItems. At the end of this view, we will display the total cost of the shopping cart.

    Views/Home/DisplayCart.aspx:

    <h2>Display Cart</h2>
    <div>
    <%: Model.Header.Account.FirstName %>
    <%: Model.Header.Account.LastName %><br />
    <%: Model.Header.Account.Email %>
    </div><br />
    <table style="width:600px">
    <tr>
    <td>
    <% Html.RenderPartial("Address", Model.Header.Billing, new ViewDataDictionary() {new KeyValuePair<string, object>("AddressType", "Billing")}); %>
    </td>
    <td>
    <% Html.RenderPartial("Address", Model.Header.Shipping, new ViewDataDictionary() {new KeyValuePair<string, object>("AddressType", "Shipping")}); %>
    </td>
    </tr>
    </table>
    <% Html.RenderPartial("Items", Model.Items); %>
    <br />
    <div>
    <b>Total:</b> <%: String.Format("{0:C}", Model.Total ) %>
    <div>
    
  10. 10. You are now ready to run the application. You can then navigate to the /Home/DisplayCart view, where you should see something of this nature:

How it works...

While this recipe appears to be complex at first, it really isn't. I had to create some complexity to be able to appropriately demonstrate how and why we would use the RenderPartial method. As you can see, moving the complexity of our display logic into partial views not only allows us to reduce the amount of code we maintain in one file, but it also provides us with the opportunity to reuse our code (as seen by using the Address partial view for two different address instances).