Поделиться через


Передача данных на эталонные страницы представлений (VB)

от Корпорации Майкрософт

Загрузить PDF-файл

Цель этого руководства — объяснить, как передать данные из контроллера в представление master страницу. Мы рассмотрим две стратегии передачи данных на страницу представления master. Во-первых, мы обсудим простое решение, которое приводит к сложному в обслуживании приложению. Далее мы рассмотрим гораздо лучшее решение, которое требует немного больше начальной работы, но приводит к гораздо более удобному приложению.

Передача данных для просмотра главных страниц

Цель этого руководства — объяснить, как передать данные из контроллера в представление master страницу. Мы рассмотрим две стратегии передачи данных на страницу представления master. Во-первых, мы обсудим простое решение, которое приводит к сложному в обслуживании приложению. Далее мы рассмотрим гораздо лучшее решение, которое требует немного больше начальной работы, но приводит к гораздо более удобному приложению.

Проблема

Представьте, что вы создаете приложение базы данных фильмов и хотите отобразить список категорий фильмов на каждой странице приложения (см. рис. 1). Кроме того, представьте, что список категорий фильмов хранится в таблице базы данных. В этом случае имеет смысл извлечь категории из базы данных и отобразить список категорий фильмов в представлении master странице.

Отображение категорий фильмов на странице представления master

Рис. 01. Отображение категорий фильмов в представлении master странице (щелкните для просмотра полноразмерного изображения)

Вот в чем проблема. Как получить список категорий фильмов на странице master? Заманчиво вызывать методы классов модели на странице master напрямую. Иными словами, заманчиво включить код для получения данных из базы данных прямо на странице master. Однако обход контроллеров MVC для доступа к базе данных приведет к нарушению четкого разделения проблем, что является одним из основных преимуществ создания приложения MVC.

В приложении MVC требуется, чтобы контроллеры MVC обрабатывали все взаимодействия между представлениями MVC и моделью MVC. Такое разделение задач приводит к более гибкому, адаптируемому и проверяемому приложению.

В приложении MVC все данные, передаваемые в представление, включая представление master страницу, должны передаваться в представление с помощью действия контроллера. Кроме того, данные следует передавать, используя преимущества просмотра данных. В оставшейся части этого руководства мы рассмотрим два метода передачи данных представления в представление master страницу.

Простое решение

Начнем с самого простого решения для передачи данных представления с контроллера на страницу представления master. Самым простым решением является передача данных представления для страницы master в каждом действии контроллера.

Рассмотрим контроллер, приведенный в листинге 1. Он предоставляет два действия с именами Index() и Details(). Метод Index() action возвращает каждый фильм в таблице базы данных Movies. Метод Details() действия возвращает каждый фильм в определенной категории фильмов.

Листинг 1 — Controllers\HomeController.vb

<HandleError()> _
Public Class HomeController
     Inherits System.Web.Mvc.Controller

     Private _dataContext As New MovieDataContext()

     ''' <summary>

     ''' Show list of all movies
     ''' </summary>
     Function Index()
          ViewData("categories") = From c In _dataContext.MovieCategories _
                    Select c
          ViewData("movies") = From m In _dataContext.Movies _
                    Select m
          Return View()
     End Function

     ''' <summary>
     ''' Show list of movies in a category
     ''' </summary>

     Function Details(ByVal id As Integer)
          ViewData("categories") = From c In _dataContext.MovieCategories _
                    Select c
          ViewData("movies") = From m In _dataContext.Movies _
                    Where m.CategoryId = id _
                    Select m
          Return View()
     End Function

End Class

Обратите внимание, что Index() действия и Details() добавляют два элемента для просмотра данных. Действие Index() добавляет два ключа: категории и фильмы. Ключ категорий представляет список категорий фильмов, отображаемых на странице представления master. Ключ movies представляет список фильмов, отображаемых на странице Представления индекса.

Действие Details() также добавляет два ключа с именами категорий и фильмов. Ключ категорий еще раз представляет список категорий фильмов, отображаемых на странице представления master. Ключ movies представляет список фильмов в определенной категории, отображаемый на странице представления сведений (см. рис. 2).

Представление

Рис. 02. Представление сведений (щелкните, чтобы просмотреть полноразмерное изображение)

Представление индексов содержится в листинге 2. Он просто выполняет итерацию по списку фильмов, представленных элементом movies в данных просмотра.

Листинг 2 — Views\Home\Index.aspx

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>

<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">

<ul>

<%  For Each m In ViewData("movies")%>

     <li><%= m.Title %></li>

<% Next%>
</ul>

</asp:Content>

Страница представления master содержится в листинге 3. Страница представления master выполняет итерацию и отрисовывает все категории фильмов, представленные элементом категорий из данных представления.

Листинг 3 . Views\Shared\Site.master

<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site.Master.vb" Inherits="MvcApplication1.Site" %>

<%@ Import Namespace="MvcApplication1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">

     <title></title>
     <asp:ContentPlaceHolder ID="head" runat="server">
     </asp:ContentPlaceHolder>
</head>
<body>
     <div>

          <h1>My Movie Website</h1>

          <% For Each c In ViewData("categories")%>

               <%=Html.ActionLink(c.Name, "Details", New With {.id = c.Id})%> 

          <% Next%>


          <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">

          </asp:ContentPlaceHolder>
     </div>
</body>
</html>

Все данные передаются в представление и master страницу представления через данные представления. Это правильный способ передачи данных на страницу master.

Так что же не так с этим решением? Проблема в том, что это решение нарушает принцип DRY (не повторяй себя). Каждое действие контроллера должно добавлять один и тот же список категорий фильмов для просмотра данных. Дублирование кода в приложении значительно усложняет обслуживание, адаптацию и изменение приложения.

Хорошее решение

В этом разделе мы рассмотрим альтернативное и лучшее решение для передачи данных из действия контроллера в представление master страницу. Вместо добавления категорий фильмов для страницы master в каждом действии контроллера мы добавляем категории фильмов в данные представления только один раз. Все данные представления, используемые страницей master представления, добавляются в контроллер приложения.

Класс ApplicationController содержится в листинге 4.

Класс ApplicationController содержится в листинге 4.

Листинг 4. Controllers\ApplicationController.vb

Public MustInherit Class ApplicationController
     Inherits System.Web.Mvc.Controller

     Private _dataContext As New MovieDataContext()

     Public ReadOnly Property DataContext() As MovieDataContext
          Get

               Return _dataContext
          End Get
     End Property


     Sub New()
          ViewData("categories") = From c In DataContext.MovieCategories _
                    Select c
     End Sub

End Class

В листинге 4 следует обратить внимание на три аспекта контроллера приложений. Во-первых, обратите внимание, что класс наследуется от базового класса System.Web.Mvc.Controller. Контроллер приложения — это класс контроллера.

Во-вторых, обратите внимание, что классом контроллера приложения является класс MustInherit. Класс MustInherit — это класс, который должен быть реализован конкретным классом. Так как контроллер приложения является классом MustInherit, нельзя напрямую вызывать никакие методы, определенные в классе . Если вы попытаетесь вызвать класс Application напрямую, появится сообщение об ошибке Resource Cannot Be Found (Ресурс не найден).

В-третьих, обратите внимание, что контроллер приложения содержит конструктор, который добавляет список категорий фильмов для просмотра данных. Каждый класс контроллера, наследующий от контроллера приложения, автоматически вызывает конструктор контроллера приложения. Всякий раз, когда вы вызываете какое-либо действие для любого контроллера, наследуемого от контроллера приложения, категории фильмов включаются в данные представления автоматически.

Контроллер Movies в листинге 5 наследуется от контроллера приложения.

Листинг 5 — Controllers\MoviesController.vb

<HandleError()> _
Public Class MoviesController
     Inherits ApplicationController

     ''' <summary>
     ''' Show list of all movies
     ''' </summary>
     Function Index()
          ViewData("movies") = From m In DataContext.Movies _
                    Select m
          Return View()

      End Function

     ''' <summary>
     ''' Show list of movies in a category
     ''' </summary>
     Function Details(ByVal id As Integer)
          ViewData("movies") = From m In DataContext.Movies _
                    Where m.CategoryId = id _
                    Select m
          Return View()
     End Function

End Class

Контроллер Movies, как и контроллер Home, описанный в предыдущем разделе, предоставляет два метода действий с именами Index() и Details(). Обратите внимание, что список категорий фильмов, отображаемый на странице представления master, не добавляется для просмотра данных в методе Index() или Details() . Так как контроллер Movies наследуется от контроллера приложения, список категорий фильмов добавляется для автоматического просмотра данных.

Обратите внимание, что это решение для добавления данных представления для страницы представления master не нарушает принцип DRY (не повторяйся). Код для добавления списка категорий фильмов для просмотра данных содержится только в одном расположении: конструкторе для контроллера приложения.

Итоги

В этом руководстве мы рассмотрели два подхода к передаче данных представления с контроллера на страницу представления master. Во-первых, мы рассмотрели простой, но труднодоступный подход. В первом разделе мы обсудили, как добавить данные представления для master страницы представления в каждом действии контроллера в приложении. Мы пришли к выводу, что это плохой подход, поскольку он нарушает принцип DRY (не повторяй себя).

Далее мы рассмотрели гораздо более эффективную стратегию добавления данных, необходимых для просмотра master страницы представления. Вместо добавления данных представления в каждом действии контроллера мы добавили данные представления только один раз в контроллере приложения. Это позволяет избежать дублирования кода при передаче данных на страницу представления master в приложении ASP.NET MVC.