Obtener acceso a los datos del modelo desde un nuevo controlador

por Rick Anderson

Nota:

Existe una versión actualizada de este tutorial, disponible aquí, donde se usa la versión más reciente de Visual Studio. El nuevo tutorial usa ASP.NET Core MVC, que proporciona muchas mejoras en este tutorial.

En este tutorial se muestra ASP.NET Core MVC con controladores y vistas. Razor Pages es una nueva alternativa en ASP.NET Core 2.0, un modelo de programación basado en páginas que facilita la compilación de interfaces de usuario web y hace que sean más productivas. Se recomienda probar el tutorial de las páginas de Razor antes que la versión MVC. El tutorial de las páginas de Razor:

  • Es más fácil de seguir.
  • Abarca más características.
  • Es el método preferido para el desarrollo de nuevas aplicaciones.

En esta sección, creará una nueva clase llamada MoviesController y escribirá código que recupere los datos de películas y los muestre en el explorador mediante una plantilla de vista.

Cree la aplicación antes de continuar con el paso siguiente. Si no crea la aplicación, obtendrá un error al agregar un controlador.

En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Controladores, luego en Agregar y, por último, en Controlador.

Screenshot that shows the Solution Explorer window. The right click menu from the Controllers folder is open and Add is selected. Controller is selected in the sub menu.

En el cuadro de diálogo Agregar scaffolding, haga clic en Controlador de MVC 5 con vistas, usando Entity Framework y haga clic en Agregar.

Screenshot that shows the Add Scaffold dialog. M V C 5 Controller with views, using Entity Framework is selected.

  • Seleccione Movie (MvcMovie.Models) para la clase de modelo.

  • Seleccione MovieDBContext (MvcMovie.Models) para la clase de contexto de datos.

  • En Nombre del controlador, escriba MoviesController.

    En la imagen siguiente se muestra el cuadro de diálogo completo.

Screenshot that shows the Add Controller dialog with class and name data inputted.

Haga clic en Agregar. (Si recibe un error, probablemente no creó la aplicación antes de empezar a agregar el controlador). Visual Studio crea los siguientes archivos y carpetas:

  • Un archivo MoviesController.cs en la carpeta Controllers del proyecto.
  • Una carpeta Views\Movies.
  • Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml e Index.cshtml en la nueva carpeta Views\Movies.

Visual Studio creó automáticamente los métodos de acción CRUD (crear, leer, actualizar y eliminar) y las vistas (la creación automática de métodos de acción CRUD y vistas se conoce como scaffolding). Ahora tiene una aplicación web totalmente funcional que le permite crear, enumerar, editar y eliminar entradas de películas.

Ejecute la aplicación y haga clic en el vínculoMVC Movie (o vaya al controlador Movies anexando /Movies a la dirección URL en la barra de direcciones del explorador). Como la aplicación se basa en el enrutamiento predeterminado (definido en el archivo App_Start\RouteConfig.cs), la solicitud del explorador http://localhost:xxxxx/Movies se enruta al método de acción Index predeterminado del controlador Movies. Es decir, la solicitud del explorador http://localhost:xxxxx/Movies es efectivamente la misma que la solicitud del explorador http://localhost:xxxxx/Movies/Index. El resultado es una lista vacía de películas, ya que aún no agregó ninguna.

Screenshot that shows the M V C Movie Page with an empty Index list.

Creación de una película

Seleccione el vínculo Crear nuevo. Escriba algunos detalles sobre una película y, después, haga clic en el botón Crear.

Screenshot that shows the Create Movie page.

Nota:

Es posible que no pueda escribir comas ni puntos decimales en el campo Precio. Para admitir la validación de jQuery para configuraciones regionales diferentes del inglés que usan una coma (",") como separador decimal y formatos de fecha que no sean del inglés de Estados Unidos, debe incluir globalize.js y su archivo cultures/globalize.cultures.js específico (de https://github.com/jquery/globalize) y JavaScript para usar Globalize.parseFloat. Mostraré cómo hacerlo en el siguiente tutorial. Por ahora, escriba solamente números enteros como 10.

Al hacer clic en el botón Crear, el formulario se publica en el servidor, donde la información de la película se guarda en la base de datos. Después, se le redirige a la dirección URL /Movies, donde puede ver la película recién creada en la lista.

Screenshot that shows the Index page with a new movie added.

Cree un par de entradas más de película. Compruebe que todos los vínculos Editar, Detalles y Eliminar son funcionales.

Examen del código generado

Abra el archivo Controllers\MoviesController.cs y examine el método Index generado. A continuación se muestra una parte del controlador de películas con el método Index.

public class MoviesController : Controller
{
    private MovieDBContext db = new MovieDBContext();

    // GET: /Movies/
    public ActionResult Index()
    {
        return View(db.Movies.ToList());
    }

Una solicitud al controlador Movies devuelve todas las entradas de la tabla Movies y, después, pasa los resultados a la vista Index. La siguiente línea de la clase MoviesController crea una instancia de un contexto de base de datos de películas, como se describió antes. Puede usar el contexto de base de datos de películas para consultar, editar y eliminar películas.

private MovieDBContext db = new MovieDBContext();

Modelos fuertemente tipados y la palabra clave @model

Anteriormente en este tutorial, vimos cómo un controlador puede pasar datos u objetos a una plantilla de vista mediante el objeto ViewBag. El objeto ViewBag es un objeto dinámico que proporciona una cómoda manera enlazada en tiempo de ejecución de pasar información a una vista.

MVC también proporciona la capacidad de pasar objetos fuertemente tipados a una plantilla de vista. Este enfoque fuertemente tipado permite una mejor comprobación en tiempo de compilación del código e IntelliSense más enriquecido en el editor de Visual Studio. El mecanismo de scaffolding en Visual Studio usó este enfoque (que consiste en pasar un modelo fuertemente tipado) con la clase MoviesController y las plantillas de vista cuando creó los métodos y las vistas.

Examine el método generado en el archivo Controllers/MoviesController.csDetails. A continuación se muestra el método Details.

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

Por lo general, el parámetro id se pasa como datos de ruta. Por ejemplo, http://localhost:1234/movies/details/1 establecerá el controlador en el controlador de películas, la acción en details y id en 1. También puede pasar el id. con una cadena de consulta como se indica a continuación:

http://localhost:1234/movies/details?id=1

Si se encuentra un elemento Movie, se pasa una instancia del modelo Movie a la vista Details:

return View(movie);

Examine el contenido del archivo Views/Movies/Details.cshtml:

@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Movie</h4>
<hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
        </dt>
         @*Markup omitted for clarity.*@        
    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
    @Html.ActionLink("Back to List", "Index")
</p>

Mediante la inclusión de una instrucción @model en la parte superior del archivo de plantilla de vista, puede especificar el tipo de objeto que espera la vista. Cuando se creó el controlador de película, Visual Studio incluyó automáticamente la siguiente instrucción @model en la parte superior del archivo Details.cshtml:

@model MvcMovie.Models.Movie

Esta directiva @model permite acceder a la película que el controlador pasó a la vista usando un objeto Model fuertemente tipado. Por ejemplo, en la plantilla Details.cshtml, el código pasa cada campo de película a los asistentes de HTML DisplayNameFor y DisplayFor con el objeto Model fuertemente tipado. Los métodos Create y Edit y las plantillas de vista también pasan un objeto de modelo de películas.

Examine la plantilla de vista Index.cshtml y el método Index en el archivo MoviesController.cs. Observe cómo el código crea un objeto List cuando llama al método auxiliar View en el método de acción Index. El código pasa esta lista Movies desde el método de acción Index a la vista:

public ActionResult Index()
{
    return View(db.Movies.ToList());
}

Cuando se creó el controlador de películas, Visual Studio incluyó automáticamente la siguiente instrucción @model en la parte superior del archivo Index.cshtml:

@model IEnumerable<MvcMovie.Models.Movie>

Esta directiva @model permite acceder a la lista de películas que el controlador pasó a la vista usando un objeto Model fuertemente tipado. Por ejemplo, en la plantilla Index.cshtml, el código recorre en bucle las películas con una instrucción foreach sobre el objeto Model fuertemente tipado:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
         <th>
            @Html.DisplayFor(modelItem => item.Rating)
        </th>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID })  |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID }) 
        </td>
    </tr>
}

Como el objeto Model está fuertemente tipado (como un objeto IEnumerable<Movie>), cada objeto item del bucle está tipado como Movie. Entre otras ventajas, esto significa que obtiene la comprobación en tiempo de compilación del código y la compatibilidad completa de IntelliSense en el editor de código:

ModelIntelliSense

Trabajar con SQL Server LocalDB

Code First de Entity Framework detectó que la cadena de conexión de la base de datos proporcionada apuntaba a una base de datos Movies que aún no existía, por lo que Code First creó automáticamente la base de datos. Para comprobar que se creó, busque en la carpeta App_Data. Si no ve el archivo Movies.mdf, haga clic en el botón Mostrar todos los archivos de la barra de herramientas del Explorador de soluciones, haga clic en el botón Actualizar y, después, expanda la carpeta App_Data.

Screenshot that shows the Solution Explorer window. The App Data folder and the Movies dot m d f subfolder are circled in red.

Haga doble clic en Movies.mdf para abrir el EXPLORADOR DE SERVIDORES y expanda la carpeta Tables para ver la tabla Movies. Observe el icono de llave junto a ID. De forma predeterminada, EF convierte una propiedad denominada ID en la clave principal. Para obtener más información sobre EF y MVC, consulte el excelente tutorial de Tom Dykstra sobre MVC y EF.

DB_explorer

Haga clic con el botón derecho en la tabla Movies y seleccione Mostrar datos de tabla para ver los datos que creó.

Screenshot that shows the Server Explorer window. The Movies right click menu is open. Show Table Data is selected and circled in red.

Screenshot that shows the M V C Movie Microsoft Visual Studio window. The d b o dot Movies Data tab is selected.

Haga clic con el botón derecho en la tabla Movies y seleccione Abrir definición de tabla para ver la estructura de tabla que Code First de Entity Framework creó automáticamente.

Screenshot that shows the Server Explorer window. The Movies right click menu is open. Open Table Definition is selected and circled in red.

Screenshot that shows the M V C Movie Microsoft Visual Studio window. The d b o dot Movies Design tab is selected.

Observe cómo el esquema de la tabla Movies se asigna a la clase Movie que creó anteriormente. Code First de Entity Framework creó automáticamente este esquema en función de la clase Movie.

Cuando termine, para cerrar la conexión haga clic con el botón derecho en MovieDBContext y seleccione Cerrar conexión. (Si no cierra la conexión, es posible que reciba un error la próxima vez que ejecute el proyecto).

Screenshot that shows the Server Explorer window. The Movie D B Context right click menu is open. Close Connection is selected and circled in red.

Ahora dispone de una base de datos y de páginas para mostrar, editar, actualizar y eliminar datos. En el siguiente tutorial, se examinará el resto del código con scaffolding y se agregará un método SearchIndex y una vista SearchIndex que le permita buscar películas en esta base de datos. Para obtener más información sobre el uso de Entity Framework con MVC, consulte Creación de un modelo de datos de Entity Framework para una aplicación de ASP.NET MVC.