Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 21 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
21
Dung lượng
376,4 KB
Nội dung
264 Microsoft Visual Studio 2010: A Beginner’s Guide Listing 9-5 shows that the Application_Start event invokes a method named RegisterRoutes, passing the Routes property of the RouteTable class. The Routes property is a static RouteCollection, meaning that there is only one copy for the entire application, and it will hold multiple routes. When the application starts, this collection will be empty and the RegisterRoutes method will populate the collection with routes for this application. Routing works by pattern matching, which you can see through the two statements in the RegisterRoutes method: IgnoreRoute and MapRoute. IgnoreRoute is useful for situations where you want to let IIS request the exact URL. In this case, it is any file with the *.axd extension, regardless of parameters. The MapRoute method shows a common pattern for matching URLs to controllers, actions, and parameters. The first parameter is the name of the route. The second parameter describes the pattern, where each pattern match is defined between curly braces. Based on the URL, http://localhost:1042/Home/About, the pattern, {controller}/{action}/ {id}, matches Home to {controller} and About to {action}; there is no match for {id}. Therefore, ASP.NET MVC will append “Controller” to the URL segment that matches {controller}, meaning that the Controller name to instantiate is HomeController. About is the method inside of HomeController to invoke. Since About doesn’t have parameters, supplying the {id} is unnecessary. The third parameter for MapRoute specifies default values, where the key matches the pattern parameter and the value assigned to the key is what ASP.NET MVC uses when it doesn’t find a pattern match with the URL. Here are a couple of examples: ● http://localhost:1042 invokes the Index method of HomeController because no Controller or action matches and the defaults are Home for {controller} and Index for {action}. ● http://localhost:1042/Home invokes the Index method of HomeController because no action was specified and the default value for {action} is Index. You can create your own custom route by using the MapRoute method and specifying other default values for the parameters. Building a Customer Management Application Now, we’ll pull together the ASP.NET MVC concepts you’ve learned and describe how to build a very simple application that displays, adds, modifies, and deletes customers. In so doing, you’ll see how to build up a Model that supports customers, how to create a custom Controller with actions for managing customers, and how to create multiple views to handle interaction with the users as they work with customers. Chapter 9: Creating Web Applications with ASP.NET MVC 265 Creating a Repository A common pattern for working with data is to build a repository that is responsible for all data-related operations. This is another way to promote separation of concerns so that you isolate logic into specific parts of an application, resulting in easier code to work with. A repository is a class that performs create, read, update, and delete (CRUD) operations on a specific data type. Listing 9-6 shows a repository for working with customer objects. You can create this class by right-clicking the Models folder and selecting Add | Class, and name the class CustomerRepository. The code also assumes that you’ve created a LINQ to SQL *.dbml, named MyShop, with a Customer entity for the Customers table in MyShop, which is the database created in Chapter 7. Listing 9-6 A repository for working with customer data C#: using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MyShopCS.Models { public class CustomerRepository { private MyShopDataContext m_ctx = new MyShopDataContext(); public int InsertCustomer(Customer cust) { m_ctx.Customers.InsertOnSubmit(cust); m_ctx.SubmitChanges(); return cust.CustomerID; } public void UpdateCustomer(Customer cust) { var currentCust = (from currCust in m_ctx.Customers where currCust.CustomerID == cust.CustomerID select currCust) .SingleOrDefault(); if (currentCust != null) 266 Microsoft Visual Studio 2010: A Beginner’s Guide { currentCust.Age = cust.Age; currentCust.Birthday = cust.Birthday; currentCust.Income = cust.Income; currentCust.Name = cust.Name; } m_ctx.SubmitChanges(); } public Customer GetCustomer(int custID) { return (from cust in m_ctx.Customers where cust.CustomerID == custID select cust) .SingleOrDefault(); } public List<Customer> GetCustomers() { return (from cust in m_ctx.Customers select cust) .ToList(); } public void DeleteCustomer(int custID) { var customer = (from cust in m_ctx.Customers where cust.CustomerID == custID select cust) .SingleOrDefault(); m_ctx.Customers.DeleteOnSubmit(customer); m_ctx.SubmitChanges(); } } } VB: Public Class CustomerRepository Private m_ctx As New MyShopDataContext Chapter 9: Creating Web Applications with ASP.NET MVC 267 Public Function InsertCustomer( ByVal cust As Customer) As Integer m_ctx.Customers.InsertOnSubmit(cust) m_ctx.SubmitChanges() Return cust.CustomerID End Function Public Sub UpdateCustomer(ByVal cust As Customer) Dim currentCust = (From currCust In m_ctx.Customers Where currCust.CustomerID = cust.CustomerID Select currCust).SingleOrDefault() If Not currentCust Is Nothing Then With currentCust .Age = cust.Age .Birthday = cust.Birthday .Income = cust.Income .Name = cust.Name End With m_ctx.SubmitChanges() End If End Sub Public Function GetCustomer(ByVal custID As Integer) As Customer Dim customer = (From cust In m_ctx.Customers Where cust.CustomerID = custID Select cust).SingleOrDefault() Return customer End Function Public Function GetCustomers() As List(Of Customer) Dim customers = 268 Microsoft Visual Studio 2010: A Beginner’s Guide (From cust In m_ctx.Customers Select cust).ToList() Return customers End Function Public Sub DeleteCustomer(ByVal custID As Integer) Dim customer = (From cust In m_ctx.Customers Where cust.CustomerID = custID Select cust).SingleOrDefault() m_ctx.Customers.DeleteOnSubmit(customer) m_ctx.SubmitChanges() End Sub End Class You can have more methods in a repository for doing whatever is required with data for the application, but the items in Listing 9-6 are typical. The LINQ to SQL operations are consistent with the material covered in Chapter 7, so there’s no need to repeat the same material here. The purpose of the repository is to give the Controller an object to work with for getting data without filling up Controller methods with data access logic. Let’s see how the Controller works with this repository next. Creating a Customer Controller Right-click the Controllers folder, select Add | Controller, or press CTRL-M, press CTRL- C, and name the file CustomerController. Check the box for “Add action methods for Create, Update, and Details scenarios” as shown in Figure 9-4. Figure 9-4 Creating a new Controller Chapter 9: Creating Web Applications with ASP.NET MVC 269 This will create a new Controller with several methods for working with Customer data. Listing 9-1 already showed what a Controller looks like, and this is no different, except that it contains more action methods. The following sections explain how to perform various operations on customer data. Displaying a Customer List The first thing to do with customers is to display a list that will serve as a starting point for other operations. Listing 9-7 shows the Index action method of the CustomerController and how it gets a list of customers to display. The code uses the CustomerRepository, created in the preceding section. For C#, you need to add a using directive at the top of the file for the MyShopCS.Models namespace. Listing 9-7 A Controller for displaying a list C#: public ActionResult Index() { var customers = new CustomerRepository() .GetCustomers(); return View(customers); } VB: Function Index() As ActionResult Dim custRep As New CustomerRepository Dim customers As List(Of Customer) customers = custRep.GetCustomers() Return View(customers) End Function Listing 9-7 shows how the Index method uses the CustomerRepository to get the list of customers. You need to pass that list to the View for display. To create the View, right-click anywhere in the Index method and select Add View, which will display the Add View window, shown in Figure 9-5. The name of the View is Index, corresponding to the name of the action method invoking the View. Naming the View after the action method is the default behavior, but 270 Microsoft Visual Studio 2010: A Beginner’s Guide you can name the View anything you want. If the View you need to display is named differently than the action method, you can use the following View method overload: View("SomeOtherViewName", customers); We want to use a strongly typed View, meaning that you will have IDE support for referencing the properties of your own object when working in the V iew. The selected object is Customer, which is already defined as a LINQ to SQL entity, which is the same type returned by the call to the GetCustomers method in CustomerRepository. The purpose of this View is to display a list of customers, so we’ll select List as View content. This will prepopulate the View with a template for displaying customers. You’ll be able to modify the screen as you like. Additionally, if you prefer to write your own code to populate the screen, you can select the Empty option for V iew content and then code the View manually yourself. Selecting List is a quick way to get started. You learned about MasterPages earlier in this chapter, and you have the option of selecting a MasterPage of your choice and specifying which ContentPlaceHolder your code will render in. Click Add to generate the View shown in Listing 9-8. Figure 9-5 The Add View window Chapter 9: Creating Web Applications with ASP.NET MVC 271 Listing 9-8 A Customer List View <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc .ViewPage<IEnumerable<MyShopCS.Models.Customer>>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Index </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Index</h2> <table> <tr> <th></th> <th> CustomerID </th> <th> Name </th> <th> Age </th> <th> Birthday </th> <th> Income </th> </tr> <% foreach (var item in Model) { %> <tr> <td> <%= Html.ActionLink("Edit", "Edit", new { id=item.CustomerID }) %> | <%= Html.ActionLink("Details", "Details", new { id=item.CustomerID })%> </td> 272 Microsoft Visual Studio 2010: A Beginner’s Guide <td> <%= Html.Encode(item.CustomerID) %> </td> <td> <%= Html.Encode(item.Name) %> </td> <td> <%= Html.Encode(item.Age) %> </td> <td> <%= Html.Encode(String.Format("{0:g}", item.Birthday)) %> </td> <td> <%= Html.Encode(String.Format("{0:F}", item.Income)) %> </td> </tr> <% } %> </table> <p> <%= Html.ActionLink("Create New", "Create") %> </p> </asp:Content> Listing 9-8 organizes the list of Customers in a table. The tr tags are rows, th are header cells, and td are content cells. After specifying the header row, the foreach loop iterates on the Model to render each content row. If you recall from Listing 9-7, the Index action method called View with a List<Customer> (List(Of Customer) in VB). When creating the View, we specified the object type as Customer, which means that the reference to Model in the foreach statement is to List<Customer> and item contains a Customer object. For each cell being rendered, item is the current Customer and the property for that cell is referenced by the property of Customer that should display. What is particularly important about displaying the data is that each cell uses the Html.Encode helper method instead of displaying the data directly. This is a best practice for best security to ensure that any data displayed is not treated as HTML markup or accidentally runs JavaScript that you didn’t intend. You see, a malicious hacker could add JavaScript during data entry and when you display that field, the browser would try to run the JavaScript code, which Chapter 9: Creating Web Applications with ASP.NET MVC 273 would be bad. Using Html.Encode prevents this from happening. The other Html helper methods, such as ActionLink, already encode output, so you should use Html.Encode whenever one of the other helpers isn’t used. Notice that the code for the foreach loop is enclosed in <% and %> symbols so that it is treated as code and not markup. Next, you’ll want to be able to navigate to the Customer List page from the main menu, so open your MasterPage, Site.Master, and add the Customers ActionLink like this: <ul id="menu"> <li><%= Html.ActionLink("Customers", "Index", "Customer")%></li> <li><%= Html.ActionLink("Home", "Index", "Home")%></li> <li><%= Html.ActionLink("About", "About", "Home")%></li> </ul> The parameters to the new ActionLink, from left to right, indicate that the text for the anchor will be Customers, and ASP.NET will invoke the Index action method on the CustomerController class when the user clicks the link. Figure 9-6 shows what the Customer list looks like when the program runs. Figure 9-6 Showing a list of objects [...]...274 Microsoft Visual Studio 2010: A Beginner’s Guide As shown in Figure 9-6, the Customer tab appears first on the list, and clicking it shows the list of Customers In addition to the content you see in the list, there are... "Name", "Name is required.") End If Dim custRep As New CustomerRepository custRep.InsertCustomer(cust) Return RedirectToAction("Index") Catch Return View() End Try End Function 275 276 Microsoft Visual Studio 2010: A Beginner’s Guide In the HTTP protocol, there are different types of verbs for the operation being conducted Listing 9-9 demonstrates two of these verbs, get and post A get is typically associated... Html.TextBoxFor(model => model.Name) %> model.Name) %> model.Age) %> 277 278 Microsoft Visual Studio 2010: A Beginner’s Guide model.Age) %> model.Age) %> . 264 Microsoft Visual Studio 2010: A Beginner’s Guide Listing 9-5 shows that the Application_Start event invokes a method. cust.CustomerID select currCust) .SingleOrDefault(); if (currentCust != null) 266 Microsoft Visual Studio 2010: A Beginner’s Guide { currentCust.Age = cust.Age; currentCust.Birthday = cust.Birthday;. Public Function GetCustomers() As List(Of Customer) Dim customers = 268 Microsoft Visual Studio 2010: A Beginner’s Guide (From cust In m_ctx.Customers Select cust).ToList() Return