Presentación de ASP.NET Web Pages: creación de un diseño coherente

por Tom FitzMacken

En este tutorial se muestra cómo usar diseños para crear una búsqueda coherente de las páginas de un sitio que utiliza ASP.NET Web Pages. Se supone que ha completado la serie mediante Eliminación de datos de bases de datos en ASP.NET Web Pages.

Temas que se abordarán:

  • Qué es una página de diseño.
  • Cómo combinar páginas de diseño con contenido dinámico.
  • Cómo pasar valores a una página de diseño.

Acerca de los diseños

Las páginas que ha creado hasta ahora han sido páginas completas e independientes. Todas pertenecen al mismo sitio, pero no tienen elementos comunes ni un aspecto estándar.

La mayoría de los sitios tienen una apariencia y un diseño coherentes. Por ejemplo, si va al sitio Microsoft.com/web y lo examina, verá que las páginas siguen un diseño general y un tema visual:

Microsoft.com/web site page showing the layout of the header, navigation area, content area, and footer

Una manera ineficaz de crear este diseño sería definir un encabezado, una barra de navegación y un pie de página por separado en cada una de las páginas. Duplicaría el mismo marcado cada vez. Si desea cambiar algo (por ejemplo, actualizar el pie de página), tendría que cambiar cada página por separado.

Aquí es donde entran en juego las páginas de diseño. En ASP.NET Web Pages, puede definir una página de diseño que proporcione un contenedor general para las páginas del sitio. Por ejemplo, la página de diseño puede contener encabezado, área de navegación y pie de página. La página de diseño incluye un marcador de posición donde va el contenido principal.

A continuación, puede definir páginas de contenido individuales que contengan el marcado y el código solo para esa página. Las páginas de contenido no tienen que ser páginas HTML completas; ni siquiera tienen que tener un elemento <body>. También tienen una línea de código que indica a ASP.NET en qué página de diseño desea mostrar el contenido. Esta es una imagen que muestra aproximadamente cómo funciona esta relación:

Conceptual diagram that shows two content pages and a layout page into which they fit

Esta interacción es fácil de entender cuando la ve en acción. En este tutorial cambiará las páginas de películas para que utilicen un diseño.

Incorporación de una página de diseño

Para empezar, creará una página de diseño que define un diseño de página típico con encabezado, pie de página y área para el contenido principal. En el sitio WebPagesMovies, agregue una página CSHTML denominada _Layout.cshtml.

El carácter de subrayado inicial (_) es significativo. Si el nombre de una página comienza por un carácter de subrayado, ASP.NET no enviará directamente esa página al explorador. Esta convención le permite definir páginas necesarias para el sitio, pero que los usuarios no deben poder solicitar directamente.

Reemplace el contenido de la página por lo siguiente:

<!DOCTYPE html>
<html>
  <head>
    <title>My Movie Site</title>
    <link href="~/Styles/Movies.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <div id="container">
        <div id="header">
          <h1>My Movie Site</h1>
        </div>
        <div id="main">
          @RenderBody()
        </div>
        <div id="footer">
          &copy; @DateTime.Now.Year My Movie Site
        </div>
    </div>
  </body>
</html>

Como puede ver, este marcado es simplemente HTML que utiliza elementos <div> para definir tres secciones en la página más otro elemento <div> para contener las tres secciones. El pie de página incluye un poco de código de Razor: @DateTime.Now.Year, que representará el año actual en esa ubicación de la página.

Observe que hay un vínculo a una hoja de estilos denominada Movies.css. La hoja de estilos es donde se definirán los detalles del diseño físico de los elementos. Va a crearla en un momento.

La única característica inusual de esta página _Layout.cshtml es la línea @Render.Body(). Es el marcador de posición donde irá el contenido cuando este diseño se combine con otra página.

Incorporación de un archivo .css

La manera preferida de definir la disposición real (es decir, la apariencia) de los elementos de la página es usar reglas de hojas de estilos CSS. Por lo tanto, creará un archivo .css que incluya las reglas para el nuevo diseño.

En WebMatrix, seleccione la raíz del sitio. A continuación, en la pestaña Archivos de la cinta de opciones, haga clic en la flecha situada debajo del botón Nuevo y luego en Nueva carpeta.

The 'New Folder' option under New in the ribbon.

Asigne el nombre Styles a la nueva carpeta.

Naming the new folder 'Styles'

En la nueva carpeta Styles, cree un archivo denominado Movies.css.

Creating a new Movies.css file

Reemplace el contenido del nuevo archivo .css por lo siguiente:

html{ height:100%; margin:0; padding:0; }

body {
  height:60%;
  font-family:'Trebuchet MS',  'Arial', 'Helvetica', 'sans-serif';
  font-size:10pt;
  background-color: LightGray;
  line-height:1.6em;
}

h1{ font-size:1.6em; }
h2{ font-size:1.4em; }

#container{
   min-height:100%;
   position:relative;
   left:10%;
}

#header{
  padding:8px;
  width:80%;
  background-color:#4b6c9e;
  color:White;
}

#main{
  width:80%;
  padding: 8px;
  padding-bottom:4em;
  background-color:White;
}

#footer{
  width:80%;
  height:2em;
  padding:8px;
  margin-top:-2em;
  background-color:LightGray;
}

.head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
.grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
.alt { background-color: #E8E8E8; color: #000; }
.selected {background-color:Yellow;}
span.caption {width:100px;}
span.dataDisplay {font-weight:bold;}

No contaremos mucho sobre estas reglas CSS, excepto para tener en cuenta dos cosas. Una es que además de establecer fuentes y tamaños, las reglas usan el posicionamiento absoluto para establecer la ubicación del encabezado, pie de página y área de contenido principal. Si no está familiarizado con el posicionamiento en CSS, puede leer el tutorial CSS Positioning en el sitio de W3Schools.

La otra que hay que tener en cuenta es que, en la parte inferior, hemos copiado las reglas de estilo definidas originalmente de forma individual en el archivo Movies.cshtml. Estas reglas se han utilizado en el tutorial Introducción a la visualización de datos mediante ASP.NET Web Pages para hacer que el asistente WebGrid represente marcado que ha agregado franjas a la tabla. (Si va a utilizar un archivo .css para las definiciones de estilo, también puede colocar en él las reglas de estilo para todo el sitio.)

Actualización del archivo Movies para usar el diseño

Ya puede actualizar los archivos existentes en el sitio para usar el nuevo diseño. Abra el archivo Movies.cshtml. En la parte superior, como primera línea de código, agregue lo siguiente:

Layout = "~/_Layout.cshtml";

La página comienza ahora de esta forma:

@{
    Layout = "~/_Layout.cshtml";

    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    // Etc.

Esta única línea de código indica a ASP.NET que, cuando se ejecute la página Movies, se debe combinar con el archivo _Layout.cshtml.

Como el archivo Movies.cshtml ahora usa una página de diseño, puede quitar el marcado de la página Movies.cshtm de la que se encarga el archivo _Layout.cshtml. Quite las etiquetas <!DOCTYPE>, <html> y <body> de apertura y cierre. Quite todo el elemento <head> y su contenido, que incluye las reglas de estilo de la cuadrícula, ya que ahora tiene esas reglas en un archivo .css. Mientras esté en él, cambie el elemento existente <h1> por un elemento <h2>; ya tiene un elemento <h1> en la página de diseño. Cambie el texto <h2> por "Enumerar películas".

Normalmente no tendría que realizar estos cambios en una página de contenido. Al iniciar el sitio con una página de diseño, se crean páginas de contenido sin todos estos elementos para empezar. Sin embargo, en este caso, va a convertir una página independiente en una que use un diseño, por lo que vamos a hacer un poco de limpieza.

Cuando haya terminado, la página Movies.cshtml tendrá el siguiente aspecto:

@{
    Layout = "~/_Layout.cshtml";

    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    if(!Request.QueryString["searchTitle"].IsEmpty() ) {
      selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
      searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
  <h2>List Movies</h2>
  <form method="get">
    <div>
      <label for="searchGenre">Genre to look for:</label>
      <input type="text" name="searchGenre"
         value="@Request.QueryString["searchGenre"]" />
      <input type="Submit" value="Search Genre" /><br/>
      (Leave blank to list all movies.)<br/>
    </div>
    <div>
       <label for="SearchTitle">Movie title contains the following:</label>
       <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
       <input type="Submit" value="Search Title" /><br/>
    </div>
  </form>
  <div>
    @grid.GetHtml(
        tableStyle: "grid",
        headerStyle: "head",
        alternatingRowStyle: "alt",
        columns: grid.Columns(
            grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
            grid.Column("Title"),
            grid.Column("Genre"),
            grid.Column("Year"),
            grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
       )
    )
  </div>
  <p><a href="~/AddMovie">Add a movie</a></p>

Prueba del diseño

Ahora puede ver el aspecto del diseño. En WebMatrix, haga clic con el botón derecho en la página Movies.cshtml y seleccione Iniciar en el explorador. Cuando el explorador muestra la página, es similar a esta otra:

Movies page rendered using a layout

ASP.NET ha combinado el contenido de la página Movies.cshtml con la página _Layout.cshtml justo donde está el método RenderBody. Y, por supuesto, la página _Layout.cshtml hace referencia a un archivo .css que define el aspecto de la página.

Actualización de la página AddMovie para utilizar el diseño

La ventaja real de los diseños es que puede usarlos para todas las páginas del sitio. Abra la página AddMovie.cshtml.

Es posible que recuerde que la página AddMovie.cshtml originalmente tenía algunas reglas CSS en ella para definir la apariencia de los mensajes de error de validación. Puesto que tiene un archivo .css para el sitio ahora, puede mover esas reglas al archivo .css. Quítelas del archivo AddMovie.cshtml y agréguelas a la parte inferior del archivo Movies.css. Está moviendo las reglas siguientes:

.field-validation-error {
  font-weight:bold;
  color:red;
  background-color:yellow;
 }
.validation-summary-errors{
  border:2px dashed red;
  color:red;
  background-color:yellow;
  font-weight:bold;
  margin:12px;
}

Ahora realice los mismos tipos de cambios en AddMovie.cshtml que ha hecho para Movies.cshtml: agregue Layout="~/_Layout.cshtml; y quite el marcado HTML que ahora es superfluo. Cambie el elemento <h1> por <h2>. Cuando haya terminado, la página tendrá el aspecto de este ejemplo:

@{
    Layout = "~/_Layout.cshtml";
    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");

    var title = "";
    var genre = "";
    var year = "";

    if(IsPost){
        if(Validation.IsValid()){
            title = Request.Form["title"];
            genre = Request.Form["genre"];
            year = Request.Form["year"];

            var db = Database.Open("WebPagesMovies");
            var insertCommand =
                "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
            db.Execute(insertCommand, title, genre, year);
            Response.Redirect("~/Movies");
        }
    }
}
  <h2>Add a Movie</h2>
    @Html.ValidationSummary()
 <form method="post">
  <fieldset>
    <legend>Movie Information</legend>
    <p><label for="title">Title:</label>
      <input type="text" name="title" value="@Request.Form["title"]" />
      @Html.ValidationMessage("title")
    </p>

    <p><label for="genre">Genre:</label>
      <input type="text" name="genre" value="@Request.Form["genre"]" />
      @Html.ValidationMessage("genre")
    </p>

    <p><label for="year">Year:</label>
      <input type="text" name="year" value="@Request.Form["year"]" />
      @Html.ValidationMessage("year")
    </p>

    <p><input type="submit" name="buttonSubmit" value="Add Movie" /></p>
  </fieldset>
  </form>

Ejecute la página. Ahora se parece a esta ilustración:

'Add Movies' page rendered using a layout

Desea realizar cambios similares en las páginas del sitio: EditMovie.cshtml y DeleteMovie.cshtml. Sin embargo, antes de hacerlo, puede realizar otro cambio en el diseño para que sea un poco más flexible.

Pasar información de título a la página diseño

La página _Layout.cshtml creada tiene un elemento <title> establecido en "My Movie Site". La mayoría de los exploradores muestran el contenido de este elemento como texto en una pestaña:

The page's <title> element displayed in a browser tab

Esta información de título es genérica. Supongamos que desea que el texto del título sea más específico en la página actual. (Los motores de búsqueda también utilizan el texto del título para determinar de qué trata la página.) Puede pasar información desde una página de contenido como Movies.cshtml o AddMovie.cshtml a la página de diseño y usar luego esa información para personalizar lo que representa la página de diseño.

Vuelva a abrir la página Movies.cshtml. En el código de la parte superior, agregue la siguiente línea:

Page.Title = "List Movies";

El objeto Page está disponible en todas las páginas .cshtml y es para este propósito, es decir, compartir información entre una página y su diseño.

Abra la página _Layout.cshtml. Cambie el elemento <title> para que tenga el aspecto de este marcado:

<title>@Page.Title</title>

Este código representa lo que se encuentra en la propiedad Page.Title justo en esa ubicación de la página.

Ejecute la página Movies.cshtml. Esta vez, la pestaña del explorador muestra lo que ha pasado como valor de Page.Title:

A browser tab showing the title created dynamically

Si lo desea, vea en el explorador el código fuente de la página. Puede ver que el elemento <title> se representa como <title>List Movies</title>.

Sugerencia

Objeto Page

Una característica útil de Page es que es un objeto dinámico: la propiedad Title no es un nombre fijo o reservado. Puede usar cualquier nombre para un valor del objeto Page. Por ejemplo, podría haber pasado fácilmente el título mediante una propiedad denominada Page.CurrentName o Page.MyPage. La única restricción es que el nombre tiene que seguir las reglas normales de las propiedades que se pueden denominar. (Por ejemplo, el nombre no puede contener un espacio.)

Puede pasar cualquier número de valores mediante el objeto Page. Si desea pasar información de películas a la página de diseño, puede pasar valores mediante algo similar a Page.MovieTitle, Page.Genre y Page.MovieYear. (O cualquier otro nombre que haya inventado para almacenar la información.) El único requisito, que probablemente sea obvio, es que tiene que usar los mismos nombres en la página de contenido y la página de diseño.

La información que se pasa mediante el objeto Page no se limita solo al texto que se va a mostrar en la página de diseño. Puede pasar un valor a la página de diseño, y luego el código de la página de diseño puede usar el valor para decidir si desea mostrar una sección de la página, qué archivo .css se va a utilizar, etc. Los valores que se pasan en el objeto Page son como cualquier otro valor que utilice en el código. Es solo que los valores se originan en la página de contenido y se pasan a la página de diseño.

Abra la página AddMovie.cshtml y agregue una línea a la parte superior del código que proporciona un título para la página AddMovie.cshtml:

Page.Title = "Add a Movie";

Ejecute la página AddMovie.cshtml. Verá el nuevo título allí:

A browser tab showing the 'Add Movies' title created dynamically

Actualización de las páginas restantes para usar el diseño

Ahora puede finalizar las páginas restantes del sitio para que utilicen el nuevo diseño. Abra EditMovie.cshtml y DeleteMovie.cshtml uno por uno y realice los mismos cambios en cada uno.

Agregue la línea de código que vincula a la página de diseño:

Layout = "~/_Layout.cshtml";

Agregue una línea para establecer el título de la página:

Page.Title = "Edit a Movie";

O bien

Page.Title = "Delete a Movie";

Quite todo el marcado HTML superfluo, básicamente, deje solo los bits que están dentro del elemento <body> (además del bloque de código en la parte superior).

Cambie el elemento <h1> para que sea un elemento <h2>.

Cuando haya realizado estos cambios, pruebe cada uno de ellos y asegúrese de que se muestren correctamente y de que el título sea correcto.

Reflexiones finales sobre las páginas de diseño

En este tutorial ha creado una página _Layout.cshtml y ha usado el método RenderBody para combinar contenido de otra página. Este es el patrón básico para usar diseños en Web Pages.

Las páginas de diseño tienen características adicionales que no hemos tratado aquí. Por ejemplo, puede anidar páginas de diseño: una página de diseño puede hacer referencia a otra. Los diseños anidados pueden ser útiles si está trabajando con subsecciones de un sitio que requiera diseños diferentes. También puede utilizar métodos adicionales (por ejemplo, RenderSection) para configurar secciones denominadas en la página de diseño.

La combinación de páginas de diseño y archivos .css resulta eficaz. Como verá en la siguiente serie de tutoriales, en WebMatrix puede crear un sitio basado en una plantilla, que proporciona un sitio que tiene funcionalidad precompilada en él. Las plantillas hacen un buen uso de páginas de diseño y CSS para crear sitios que tienen una apariencia excelente y características como menús. Esta es una captura de pantalla de la página principal de un sitio basado en una plantilla, en la que se muestran las características que utilizan páginas de diseño y CSS:

Layout created by WebMatrix site template showing the header, navigation area, content area, optional section, and login links

Lista completa de la página de películas (actualizada para usar una página de diseño)

@{
    Layout = "~/_Layout.cshtml";
    Page.Title = "List Movies";

    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    if(!Request.QueryString["searchTitle"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
        searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}

<h2>List Movies</h2>
    <form method="get">
      <div>
        <label for="searchGenre">Genre to look for:</label>
        <input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
        <input type="Submit" value="Search Genre" /><br/>
        (Leave blank to list all movies.)<br/>
      </div>

      <div>
        <label for="SearchTitle">Movie title contains the following:</label>
        <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
        <input type="Submit" value="Search Title" /><br/>
      </div>
    </form>

<div>
    @grid.GetHtml(
        tableStyle: "grid",
        headerStyle: "head",
        alternatingRowStyle: "alt",
        columns: grid.Columns(
    grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
    grid.Column("Title"),
    grid.Column("Genre"),
    grid.Column("Year"),
    grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
        )
    )
</div>
<p><a href="~/AddMovie">Add a movie</a></p>

Lista completa de la página para agregar página de películas (actualizada para el diseño)

@{
    Layout = "~/_Layout.cshtml";
    Page.Title = "Add a Movie";

    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");

    var title = "";
    var genre = "";
    var year = "";

    if(IsPost){
        if(Validation.IsValid()){
            title = Request.Form["title"];
            genre = Request.Form["genre"];
            year = Request.Form["year"];

            var db = Database.Open("WebPagesMovies");
            var insertCommand = "INSERT INTO Movies (Title, Genre, Year) VALUES(@0, @1, @2)";
            db.Execute(insertCommand, title, genre, year);

            Response.Redirect("~/Movies");
        }
    }
}

<h2>Add a Movie</h2>
@Html.ValidationSummary()
<form method="post">
<fieldset>
    <legend>Movie Information</legend>
    <p><label for="title">Title:</label>
        <input type="text" name="title" value="@Request.Form["title"]" />
        @Html.ValidationMessage("title")

    <p><label for="genre">Genre:</label>
        <input type="text" name="genre" value="@Request.Form["genre"]" />
        @Html.ValidationMessage("genre")

    <p><label for="year">Year:</label>
        <input type="text" name="year" value="@Request.Form["year"]" />
        @Html.ValidationMessage("year")

    <p><input type="submit" name="buttonSubmit" value="Add Movie" /></p>
</fieldset>
</form>

Lista completa de la página para eliminar página de películas (actualizada para el diseño)

@{
    Layout = "~/_Layout.cshtml";
    Page.Title = "Delete a Movie";

    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].AsInt() > 0){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was found for that ID.");
                // If you are using a version of ASP.NET Web Pages 2 that's
                // earlier than the RC release, comment out the preceding
                // statement and uncomment the following one.
                //ModelState.AddFormError("No movie was found for that ID.");
            }
        }
        else{
            Validation.AddFormError("No movie was found for that ID.");
            // If you are using a version of ASP.NET Web Pages 2 that's
            // earlier than the RC release, comment out the preceding
            // statement and uncomment the following one.
            //ModelState.AddFormError("No movie was found for that ID.");
        }
    }

    if(IsPost && !Request["buttonDelete"].IsEmpty()){
        movieId = Request.Form["movieId"];
        var db = Database.Open("WebPagesMovies");
        var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
        db.Execute(deleteCommand, movieId);
        Response.Redirect("~/Movies");
    }

}

<h2>Delete a Movie</h2>
@Html.ValidationSummary()
<p><a href="~/Movies">Return to movie listing</a></p>

<form method="post">
<fieldset>
<legend>Movie Information</legend>

<p><span>Title:</span>
    <span>@title</span></p>

<p><span>Genre:</span>
    <span>@genre</span></p>

<p><span>Year:</span>
    <span>@year</span></p>

<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
</fieldset>
</form>

Lista completa de la página para editar página de películas (actualizada para diseño)

@{
    Layout = "~/_Layout.cshtml";
    Page.Title = "Edit a Movie";

    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);

            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was selected.");
                // If you are using a version of ASP.NET Web Pages 2 that's
                // earlier than the RC release, comment out the preceding
                // statement and uncomment the following one.
                //ModelState.AddFormError("No movie was selected.");
            }
        }
        else{
            Validation.AddFormError("No movie was selected.");
            // If you are using a version of ASP.NET Web Pages 2 that's
            // earlier than the RC release, comment out the preceding
            // statement and uncomment the following one.
            //ModelState.AddFormError("No movie was selected.");
        }
    }

    if(IsPost){
        Validation.RequireField("title", "You must enter a title");
        Validation.RequireField("genre", "Genre is required");
        Validation.RequireField("year", "You haven't entered a year");
        Validation.RequireField("movieid", "No movie ID was submitted!");

        title = Request.Form["title"];
        genre = Request.Form["genre"];
        year = Request.Form["year"];
        movieId = Request.Form["movieId"];

        if(Validation.IsValid()){
            var db = Database.Open("WebPagesMovies");
            var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
            db.Execute(updateCommand, title, genre, year, movieId);
            Response.Redirect("~/Movies");
        }
    }
}

<h2>Edit a Movie</h2>
@Html.ValidationSummary()
<form method="post">
<fieldset>
    <legend>Movie Information</legend>

    <p><label for="title">Title:</label>
        <input type="text" name="title" value="@title" /></p>

    <p><label for="genre">Genre:</label>
        <input type="text" name="genre" value="@genre" /></p>

    <p><label for="year">Year:</label>
        <input type="text" name="year" value="@year" /></p>

    <input type="hidden" name="movieid" value="@movieId" />

    <p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
</fieldset>
</form>
<p><a href="~/Movies">Return to movie listing</a></p>

Próximamente

En el siguiente tutorial, aprenderá a publicar el sitio en Internet para que todos los usuarios puedan verlo.

Recursos adicionales

  • Creación de una apariencia coherente: un artículo que proporciona más detalles sobre cómo trabajar con diseños. También describe cómo pasar un valor a una página de diseño que muestra u oculta parte del contenido.
  • Páginas de diseño anidadas con Razor: Mike Brind publica en el blog un ejemplo de cómo anidar páginas de diseño. (Incluye una descarga de las páginas.)