Condividi tramite


Passaggio di dati a pagine master di visualizzazione (VB)

di Microsoft

Scarica il PDF

L'obiettivo di questa esercitazione è spiegare come passare i dati da un controller a una pagina master di visualizzazione. Vengono esaminate due strategie per passare i dati a una pagina master di visualizzazione. In primo luogo, viene illustrata una soluzione semplice che comporta un'applicazione difficile da gestire. Si esaminerà quindi una soluzione molto migliore che richiede un po' di lavoro iniziale, ma comporta un'applicazione molto più gestibile.

Passaggio di dati alle pagine master di visualizzazione

L'obiettivo di questa esercitazione è spiegare come passare i dati da un controller a una pagina master di visualizzazione. Vengono esaminate due strategie per passare i dati a una pagina master di visualizzazione. In primo luogo, viene illustrata una soluzione semplice che comporta un'applicazione difficile da gestire. Si esaminerà quindi una soluzione molto migliore che richiede un po' di lavoro iniziale, ma comporta un'applicazione molto più gestibile.

Problema

Si supponga di creare un'applicazione di database di film e di voler visualizzare l'elenco delle categorie di film in ogni pagina dell'applicazione (vedere la figura 1). Si supponga, inoltre, che l'elenco delle categorie di film sia archiviato in una tabella di database. In tal caso, sarebbe opportuno recuperare le categorie dal database ed eseguire il rendering dell'elenco delle categorie di film all'interno di una pagina master di visualizzazione.

Visualizzazione di categorie di film in una pagina master di visualizzazione

Figura 01: Visualizzazione di categorie di film in una pagina master di visualizzazione (fare clic per visualizzare l'immagine a dimensione intera)

Ecco il problema. Come si recupera l'elenco delle categorie di film nella pagina master? È allettante chiamare direttamente i metodi delle classi del modello nella pagina master. In altre parole, è possibile includere il codice per recuperare i dati dal database direttamente nella pagina master. Tuttavia, ignorare i controller MVC per accedere al database viola la separazione pulita dei problemi che è uno dei principali vantaggi della creazione di un'applicazione MVC.

In un'applicazione MVC si vuole che tutte le interazioni tra le visualizzazioni MVC e il modello MVC vengano gestite dai controller MVC. Questa separazione dei problemi comporta un'applicazione più gestibile, adattabile e testabile.

In un'applicazione MVC, tutti i dati passati a una visualizzazione, inclusa una pagina master di visualizzazione, devono essere passati a una visualizzazione da un'azione del controller. Inoltre, i dati devono essere passati sfruttando i dati di visualizzazione. Nella parte restante di questa esercitazione, esamino due metodi per passare i dati di visualizzazione a una pagina master di visualizzazione.

Soluzione semplice

Si inizierà con la soluzione più semplice per passare i dati di visualizzazione da un controller a una pagina master di visualizzazione. La soluzione più semplice consiste nel passare i dati di visualizzazione per la pagina master in ogni azione del controller.

Prendere in considerazione il controller nell'elenco 1. Espone due azioni denominate Index() e Details(). Il Index() metodo di azione restituisce ogni filmato nella tabella di database Movies. Il Details() metodo di azione restituisce ogni filmato in una determinata categoria di film.

Elenco 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

Si noti che sia le azioni che le Index()Details() azioni aggiungono due elementi per visualizzare i dati. L'azione Index() aggiunge due chiavi: categorie e film. La chiave categories rappresenta l'elenco delle categorie di film visualizzate dalla pagina master della visualizzazione. La chiave movies rappresenta l'elenco dei film visualizzati dalla pagina Di visualizzazione Indice.

L'azione Details() aggiunge anche due chiavi denominate categorie e film. La chiave delle categorie, ancora una volta, rappresenta l'elenco delle categorie di film visualizzate dalla pagina master di visualizzazione. La chiave movies rappresenta l'elenco di film in una determinata categoria visualizzata dalla pagina Visualizzazione Dettagli (vedere la figura 2).

Visualizzazione Dettagli

Figura 02: Visualizzazione Dettagli (fare clic per visualizzare l'immagine a dimensione intera)

La vista Indice è contenuta nell'elenco 2. Scorre semplicemente l'elenco di film rappresentati dall'elemento film nei dati di visualizzazione.

Elenco 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>

La pagina master di visualizzazione è contenuta nell'elenco 3. La pagina master di visualizzazione esegue l'iterazione ed esegue il rendering di tutte le categorie di film rappresentate dall'elemento categorie dai dati di visualizzazione.

Listato 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>

Tutti i dati vengono passati alla visualizzazione e alla pagina master di visualizzazione tramite i dati di visualizzazione. Questo è il modo corretto per passare i dati alla pagina master.

Allora, cosa c'è di sbagliato con questa soluzione? Il problema è che questa soluzione viola il principio DRY (Don't Repeat Yourself). Ogni azione controller deve aggiungere lo stesso elenco di categorie di film per visualizzare i dati. La presenza di codice duplicato nell'applicazione rende l'applicazione molto più difficile da gestire, adattare e modificare.

La buona soluzione

In questa sezione viene esaminata una soluzione alternativa e migliore per passare i dati da un'azione del controller a una pagina master di visualizzazione. Invece di aggiungere le categorie di film per la pagina master in ogni azione controller, le categorie di film vengono aggiunte ai dati di visualizzazione una sola volta. Tutti i dati di visualizzazione utilizzati dalla pagina master di visualizzazione vengono aggiunti in un controller applicazione.

La classe ApplicationController è contenuta nell'elenco 4.

La classe ApplicationController è contenuta nell'elenco 4.

Elenco 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

Esistono tre aspetti da notare sul controller dell'applicazione nell'elenco 4. Si noti innanzitutto che la classe eredita dalla classe System.Web.Mvc.Controller di base. Il controller applicazione è una classe controller.

In secondo luogo, si noti che la classe controller Application è una classe MustInherit. Una classe MustInherit è una classe che deve essere implementata da una classe concreta. Poiché il controller applicazione è una classe MustInherit, non è possibile richiamare direttamente alcun metodo definito nella classe . Se si tenta di richiamare direttamente la classe Application, verrà visualizzato un messaggio di errore Resource Cannot Be Found .If you attempt to invoke the Application class then you'll get a Resource Cannot Be Found error message.

In terzo luogo, si noti che il controller dell'applicazione contiene un costruttore che aggiunge l'elenco di categorie di film per visualizzare i dati. Ogni classe controller che eredita dal controller applicazione chiama automaticamente il costruttore del controller applicazione. Ogni volta che si chiama un'azione su qualsiasi controller che eredita dal controller dell'applicazione, le categorie di film vengono incluse automaticamente nei dati di visualizzazione.

Il controller Movies nell'elenco 5 eredita dal controller dell'applicazione.

Elenco 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

Il controller Movies, proprio come il controller Home illustrato nella sezione precedente, espone due metodi di azione denominati Index() e Details(). Si noti che l'elenco delle categorie di film visualizzate dalla pagina master di visualizzazione non viene aggiunto per visualizzare i Index() dati nel metodo o Details() . Poiché il controller Movies eredita dal controller dell'applicazione, l'elenco delle categorie di film viene aggiunto automaticamente per visualizzare i dati.

Si noti che questa soluzione per aggiungere dati di visualizzazione per una pagina master di visualizzazione non viola il principio DRY (Don't Repeat Yourself). Il codice per l'aggiunta dell'elenco di categorie di film per visualizzare i dati è contenuto in una sola posizione: il costruttore per il controller dell'applicazione.

Riepilogo

In questa esercitazione sono stati illustrati due approcci per passare i dati di visualizzazione da un controller a una pagina master di visualizzazione. In primo luogo, abbiamo esaminato un approccio semplice, ma difficile da mantenere. Nella prima sezione è stato illustrato come aggiungere dati di visualizzazione per una pagina master di visualizzazione in ogni azione del controller nell'applicazione. Abbiamo concluso che questo è stato un approccio errato perché viola il principio DRY (Don't Repeat Yourself).

Successivamente, è stata esaminata una strategia molto migliore per l'aggiunta di dati richiesti da una pagina master di visualizzazione per visualizzare i dati. Invece di aggiungere i dati di visualizzazione in ogni azione del controller, i dati di visualizzazione sono stati aggiunti una sola volta all'interno di un controller dell'applicazione. In questo modo, è possibile evitare il codice duplicato quando si passano dati a una pagina master di visualizzazione in un'applicazione MVC ASP.NET.