[ASP.NET MVC] Mostrar datos paginados en un Datagrid I

Siguiendo la línea de Scott Mitchell en sus últimos artículos, a lo largo de una serie de posts vamos a ir viendo como podemos mostrar nuestros datos en formato datagrid, y como podemos aplicar las funcionalidades de paginado, filtrado y orden sobre los mismos, dentro de una aplicación ASP.NET MVC. En el artículo de hoy vamos a ver el primero de los casos, para ello creamos un proyecto de tipo ASP.NET MVC 2 Web Application que llamaremos DataGridApp. En el, añadimos la base de datos AdventureWorks, ya que tiene un gran número de tablas y registros con los que poder trabajar, y aplicarles la funcionalidad específica.

A continuación creamos un modelo de tipo LINQ to SQL Classes llamado StoreModel, que contendrá las tablas Customer y Store, de forma que nuestro modelo quede de la siguiente forma:

image

 

A continuación creamos un controlador especifico para trabajar con el modelo creado, y al que llamaremos StoreController.

image

En dicho controlador

1.Añadimos la referencia a nuestro modelo, y la referencia a Linq para poder trabajar con ellos:

  1. using DataGridApp.Models;
  2. using System.Data.Linq;

2.Inicializamos el contexto de nuestro modelo:

  1. StoreModelDataContext context = new StoreModelDataContext();

 

3.Creamos la acción Index, cuyo código será el siguiente:

  1. public ActionResult Index()
  2. {
  3.     return View(context.Stores);
  4. }

Y su vista correspondiente, de forma que podamos mostrar todos los elementos definidos en nuestro contexto de datos. Para ello hacemos clic con él botón derecho sobre Index y añadimos una vista con las siguientes propiedades:

image

En dicha vista, cambiamos la propiedad Inherits a:

System.Web.Mvc.ViewPage<IEnumerable<DataGridApp.Models.Store>>

Y dentro del contenedor principal añadimos el siguiente código:

  1. <table>
  2.         <tr>
  3.             <th>Store Name</th>
  4.             <th>Cust. Acc. Number</th>
  5.             <th>Sales Person ID</th>
  6.         </tr>
  7.  
  8.     <% foreach (var item in Model) { %>
  9.     
  10.         <tr>
  11.             <td><%: item.Name %></td>
  12.             <td><%: item.Customer.AccountNumber %></td>
  13.             <td><%: item.SalesPersonID %></td>
  14.         </tr>
  15.     
  16.     <% } %>
  17.  
  18.     </table>

A continuación creamos una clase para definir el modelo específico que queremos mostrar mediante la acción Paged. Para ello hacemos clic con el botón derecho sobre la carpeta Models y añadimos una clase llamada StoreGridModel que contendrá el siguiente código:

  1. public class StoreGridModel
  2.     {
  3.  
  4.         // Definimos las propiedades
  5.         public IEnumerable<Store> Stores { get; set; }
  6.         public int CurrentPageIndex { get; set; }
  7.         public int PageSize { get; set; }
  8.         public int TotalRecordCount { get; set; }
  9.         public int NumericPageCount { get; set; }
  10.         public int PageCount
  11.         {
  12.             get
  13.             {
  14.                 return this.TotalRecordCount / this.PageSize;
  15.             }
  16.         }
  17.         public StoreGridModel()
  18.         {
  19.  
  20.             // Establecemos los valores por defecto
  21.             this.PageSize = 10;
  22.             this.NumericPageCount = 10;
  23.         }
  24.  
  25.     }

Por último pasamos a definir la acción Paged, a través de la cual mostraremos nuestros elementos paginados en grupos de 10 en 10, y por los que podremos navegar mediante el uso de vistas parciales. El código que utilizamos para implementar dicha acción es el siguiente:

  1. public ActionResult Paged(int page = 1, int pageSize = 10)
  2.         {
  3.             var model = new  StoreGridModel
  4.             {
  5.                 CurrentPageIndex = page,
  6.                 PageSize = pageSize
  7.             };
  8.  
  9.             // Se determina el numero total de «stores» que se muestran en cada página
  10.             model.TotalRecordCount = context.Stores.Count();
  11.             // Se obtiene la página actual de «stores»
  12.  
  13.             model.Stores = context.Stores
  14.                            .Skip((model.CurrentPageIndex – 1) * model.PageSize)
  15.                            .Take(model.PageSize);
  16.  
  17.             return View(model);
  18.         }

 

Definimos su vista correspondiente, que tendrá las siguientes propiedades:

image

Y cuyo código será el siguiente:

  1. <p>
  2.         <i>Estas viendo la página <%: Model.CurrentPageIndex %> de <%: Model.PageCount %></i>
  3.     </p>
  4.     <table>
  5.         <tr>
  6.             <th>Store Name</th>
  7.             <th>Cust. Acc. Number</th>
  8.             <th>Sales Person ID</th>
  9.         </tr>
  10.  
  11.     <% foreach (var item in Model.Stores) { %>
  12.     
  13.         <tr>
  14.             <td><%: item.Name %></td>
  15.             <td><%: item.Customer.AccountNumber %></td>
  16.             <td><%: item.SalesPersonID %></td>
  17.         </tr>
  18.     
  19.     <% } %>
  20.  
  21.         <tr>
  22.             <td colspan=»5″>
  23.                 <% Html.RenderPartial(«Pager», Model); %>
  24.             </td>
  25.         </tr>
  26.  
  27.     </table>

Para que dicha vista funcione correctamente es necesario implementar previamente dos vistas parciales que guardaremos en la carpeta Views/Shared.

La primera de ellas, Pager.ascx nos permitirá realizar el renderizado parcial de los elementos de nuestro modelo, y en ella definiremos los distintos elementos de navegación. Esta vista se crea con las siguientes propiedades:

image

Y cuyo código es el siguiente:

  1. <div class=»pager»>
  2. <%
  3.     // Creamos el Link «Anterior»
  4.     Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «<< Anterior» }, { «PageIndex», Model.CurrentPageIndex – 1 }, { «Selected», false }, { «Inactive», Model.CurrentPageIndex == 1 } });
  5.  
  6.     
  7.     // Creamos los links númericos    
  8.     var startPageIndex = Math.Max(1, Model.CurrentPageIndex – Model.NumericPageCount / 2);
  9.     var endPageIndex = Math.Min(Model.PageCount, Model.CurrentPageIndex + Model.NumericPageCount / 2);
  10.  
  11.     // Mostramos los valores iniciales
  12.     if (Model.PageCount > Model.NumericPageCount / 2)
  13.     {
  14.         if (startPageIndex > 1)
  15.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «1» }, { «PageIndex», 1 }, { «Selected», false }, { «Inactive», false } });
  16.         if (startPageIndex > 2)
  17.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «2» }, { «PageIndex», 2 }, { «Selected», false }, { «Inactive», false } });
  18.         if (startPageIndex > 3)
  19.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «…» }, { «PageIndex», 1 }, { «Selected», false }, { «Inactive», true } });
  20.     }
  21.  
  22.     // Añadimos el resto de páginas numericas
  23.     for (var i = startPageIndex; i <= endPageIndex; i++)
  24.         Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», i }, { «PageIndex», i }, { «Selected», i == Model.CurrentPageIndex }, { «Inactive», false } });
  25.  
  26.     
  27.     // Mostramos los valores finales
  28.     if (Model.PageCount > Model.NumericPageCount / 2)
  29.     {
  30.         if (endPageIndex < Model.PageCount – 2)
  31.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «…» }, { «PageIndex», 1 }, { «Selected», false }, { «Inactive», true } });
  32.         if (endPageIndex < Model.PageCount – 1)
  33.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», Model.PageCount – 1 }, { «PageIndex», Model.PageCount – 1 }, { «Selected», false }, { «Inactive», false } });
  34.         if (endPageIndex < Model.PageCount)
  35.             Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», Model.PageCount }, { «PageIndex», Model.PageCount }, { «Selected», false }, { «Inactive», false } });
  36.     }
  37.  
  38.     // Creamos el link «Siguiente»
  39.     Html.RenderPartial(«PagerLink», Model, new ViewDataDictionary { { «Text», «Siguiente >>» }, { «PageIndex», Model.CurrentPageIndex + 1 }, { «Selected», false }, { «Inactive», Model.CurrentPageIndex == Model.PageCount } });
  40. %>
  41. </div>

Y la segunda PagerLink.ascx que nos permitirá navegar por las distintas vistas, y aplicarles los estilos específicos. Esta contará con las siguientes propiedades:

image

Y su código es el siguiente:

  1. <%
  2.     if ((bool)ViewData[«Inactive»])
  3.     {
  4.         Response.Write(string.Format(«<span class=»{0}»>{1}</span>», «pagerButtonDisabled», ViewData[«Text»]));
  5.     }
  6.     else
  7.     {
  8.         var routeData = new RouteValueDictionary { { «page», ViewData[«PageIndex»].ToString() }, { «pageSize», Model.PageSize } };
  9.         var htmlAttributes = new Dictionary<string, object>();
  10.         if ((bool)ViewData[«Selected»])
  11.             htmlAttributes.Add(«class», «pagerButtonCurrentPage»);
  12.         else
  13.             htmlAttributes.Add(«class», «pagerButton»);
  14.  
  15.         Response.Write(
  16.             Html.ActionLink(
  17.                     ViewData[«Text»].ToString(),                                    // Link Text
  18.                     Html.ViewContext.RouteData.Values[«action»].ToString(),         // Acción
  19.                     Html.ViewContext.RouteData.Values[«controller»].ToString(),     // Controlador
  20.                     routeData,                                                      // Ruta
  21.                     htmlAttributes                                                  // Atributos HTML para aplicar a los hipervinculos
  22.                 ).ToHtmlString()
  23.         );
  24.     }
  25. %>

Creamos las clases que vamos a aplicar para personalizar el formato del paginado dentro de la hoja de estilos Site.css:

  1. /*Customizations*/
  2.  
  3. td.pager {
  4.     background-color: #eee;
  5. }
  6.  
  7. td.pager div {
  8.     font-size: smaller;
  9.     font-weight: bold;
  10.     padding: 5px;
  11. }
  12.  
  13. a.pagerButton, a.pagerButton:visited
  14. {
  15.     border: solid 1px #eee;
  16.     padding: 4px;
  17.     text-decoration: none;
  18.     color: #006;
  19.     margin: 0px 2px 0px 2px;
  20. }
  21.  
  22. a.pagerButton:hover
  23. {
  24.     border: solid 1px black;
  25.     color: Black;
  26. }
  27.  
  28. a.pagerButtonCurrentPage
  29. {
  30.     border: solid 1px #00a;
  31.     padding: 4px;
  32.     text-decoration: none;
  33.     color: White;
  34.     background-color: #006;
  35.     margin: 0px 2px 0px 2px;
  36. }
  37.  
  38. .pagerButtonDisabled
  39. {
  40.     border: none;
  41.     color: #999;
  42.     padding: 4px;
  43. }

Finalmente, compilamos la aplicación y navegamos a la ruta /Store/Paged donde podemos ver como se obtienen todos los elementos de nuestro modelo estructurados tal y como lo hemos definido en su configuración y como podemos navegar por ellos de forma sencilla.

image

[ASP.NET MVC] Validación modelo Entity Framework

En este artículo vamos a ver como validar los elementos de nuestro modelo de datos cuando implementamos las acciones Create y Edit. Existen dos tipos de validación que se pueden aplicar; validaciones en el lado servidor, y en el lado cliente. Para el primero de los casos vamos a usar Data Annotations. Las Data Annotations son atributos que nos permiten describir reglas que deben cumplir las propiedades de nuestro modelo:

  • Required – Indica que la propiedad es un campo requerido
  • DisplayName – Define el texto que queremos mostrar al validar los campos
  • StringLength – Define la longitud máxima para un campo de tipo string
  • Range – Da un rango de valores(máximo y mínimo) para un campo numérico
  • Bind – Permite excluir o incluir campos cuando enlazamos parámetros o valores con las propiedades del modelo
  • ScaffoldColumn – Permite ocultar campos del formulario de edición

 

En este caso partimos de una aplicación de tipo ASP.NET MVC 2 Web Application llamada ValidationApp, que tiene una base de datos que consta de una tabla llamada Team cuyos campos son los siguientes:

image

Creamos el modelo que nos permita interactuar con dicha base de datos que será de tipo ADO.NET Entity  Data Model, y que llamaremos TeamModel. Cuando trabajamos con modelos de tipo Entity Framework, las clases de dichos modelos se autogeneran, por lo que si añadimos las validaciones directamente sobre ellas, estas se sobrescribirían al actualizar el modelo desde la base de datos. En este caso lo que hacemos es definir clases parciales de nuestros modelos, en los que configuraremos las validaciones mediante el uso del atributo [MetadataType].

Creamos una clase llamada Team.cs que nos permitirá validar los valores de nuestro modelo Team. Para ello hacemos clic con el botón derecho sobre la carpeta Models y seleccionamos Add > class. Dentro de dicha clase:

1. Añadimos las siguientes referencias:

  1. using System.ComponentModel;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Web.Mvc;

3. Creamos la clase de validación de los metadatos con los requisitos de validación para cada uno de los campos

  1. [Bind(Exclude=«TeamID»)]
  2.         public class TeamMetaData
  3.         {
  4.             [Required(ErrorMessage=«Introduce el nombre del equipo»)]
  5.             public object TeamName { get; set; }
  6.  
  7.             [DisplayName(«Nombre del pabellón de juego»)]
  8.             [Required(ErrorMessage = «Introduce el nombre del pabellón»)]
  9.             public object TeamPlace { get; set; }
  10.  
  11.             [DisplayName(«Nombre del equipo»)]
  12.             [Required(ErrorMessage = «Introduce el nombre de la ciudad»)]
  13.             [StringLength(50,ErrorMessage=«El número de carácteres es demasiado largo»)]
  14.             public object TeamCity { get; set; }
  15.  
  16.         }

3. Indicamos que tipo de metadatos vamos a utilizar:

  1. [MetadataType(typeof(TeamMetaData))]

De forma que el código completo de la clase queda de la siguiente forma:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.ComponentModel;
  6. using System.ComponentModel.DataAnnotations;
  7. using System.Web.Mvc;
  8.  
  9.  
  10. namespace ValidationApp.Models
  11. {
  12.     [MetadataType(typeof(TeamMetaData))]
  13.     public partial class Team
  14.     {
  15.         [Bind(Exclude=«TeamID»)]
  16.         public class TeamMetaData
  17.         {
  18.             [Required(ErrorMessage=«Introduce el nombre del equipo»)]
  19.             public object TeamName { get; set; }
  20.  
  21.             [DisplayName(«Nombre del pabellón de juego»)]
  22.             [Required(ErrorMessage = «Introduce el nombre del pabellón»)]
  23.             public object TeamPlace { get; set; }
  24.  
  25.             [DisplayName(«Nombre del equipo»)]
  26.             [Required(ErrorMessage = «Introduce el nombre de la ciudad»)]
  27.             [StringLength(50,ErrorMessage=«El número de carácteres es demasiado largo»)]
  28.             public object TeamCity { get; set; }
  29.  
  30.         }
  31.     }
  32. }

A continuación creamos las distintas acciones de nuestro controlador y sus vistas correspondientes, como ya hemos visto en otras ocasiones, de forma que podamos implementar operaciones de tipo CRUD con nuestra base de datos.

Finalmente compilamos nuestra aplicación y navegamos hasta /Team/Create. Si intentamos crear un elemento, y este no cumple con los criterios establecidos vemos como se aplican las reglas de validación correspondientes.

image image image

Aunque la el tipo de validación que hemos visto funciona correctamente, existen tres problemas con él:

1. El usuario tiene que esperar a que se envíe el formulario, se valide en el servidor, y se reciba la respuesta en el navegador.

2. El usuario no obtiene inmediatamente feedback cuando se corrige un campo

3. Se gastan recursos de servidor para representar la validación lógica

A continuación vamos a ver como se realizaría la validación en el lado cliente, y las ventajas que esta presenta. Como nuestra clase Team, ya tiene los atributos de validación establecidos, sólo necesitamos añadir algo de javascript a nuestra página Create.aspx para activar la validación en el lado cliente. Para ello abrimos la vista Team/Create.aspx.

Arrastramos a dicha vista los archivos: MicrosoftAjax.js, MicrosoftMvcAjax.js, MicrosoftMvcValidation.js

De forma que se genera el siguiente código:

  1. <script src=»../../Scripts/MicrosoftAjax.js» type=»text/javascript»></script>
  2. <script src=»../../Scripts/MicrosoftMvcAjax.js» type=»text/javascript»></script>
  3. <script src=»../../Scripts/MicrosoftMvcValidation.js» type=»text/javascript»></script>

A continuación añadimos la siguiente línea de código sobre Html.BeginForm:

  1. <%Html.EnableClientValidation();%>

Así quedaría el código de nuestra vista:

  1. <asp:Content ID=»Content2″ ContentPlaceHolderID=»MainContent» runat=»server»>
  2.  
  3.     <h2>Create</h2>
  4.     <script src=»../../Scripts/MicrosoftAjax.js» type=»text/javascript»></script>
  5.     <script src=»../../Scripts/MicrosoftMvcAjax.js» type=»text/javascript»></script>
  6.     <script src=»../../Scripts/MicrosoftMvcValidation.js» type=»text/javascript»></script>
  7.     
  8.     <%Html.EnableClientValidation();%>
  9.     <% using (Html.BeginForm()) {%>
  10.         <%: Html.ValidationSummary(true) %>
  11.  
  12.         <fieldset>
  13.             <legend>Fields</legend>
  14.             
  15.             <div class=»editor-label»>
  16.                 <%: Html.LabelFor(model => model.TeamID) %>
  17.             </div>
  18.             <div class=»editor-field»>
  19.                 <%: Html.TextBoxFor(model => model.TeamID) %>
  20.                 <%: Html.ValidationMessageFor(model => model.TeamID) %>
  21.             </div>
  22.             
  23.             <div class=»editor-label»>
  24.                 <%: Html.LabelFor(model => model.TeamName) %>
  25.             </div>
  26.             <div class=»editor-field»>
  27.                 <%: Html.TextBoxFor(model => model.TeamName) %>
  28.                 <%: Html.ValidationMessageFor(model => model.TeamName) %>
  29.             </div>
  30.             
  31.             <div class=»editor-label»>
  32.                 <%: Html.LabelFor(model => model.TeamPlace) %>
  33.             </div>
  34.             <div class=»editor-field»>
  35.                 <%: Html.TextBoxFor(model => model.TeamPlace) %>
  36.                 <%: Html.ValidationMessageFor(model => model.TeamPlace) %>
  37.             </div>
  38.             
  39.             <div class=»editor-label»>
  40.                 <%: Html.LabelFor(model => model.TeamCity) %>
  41.             </div>
  42.             <div class=»editor-field»>
  43.                 <%: Html.TextBoxFor(model => model.TeamCity) %>
  44.                 <%: Html.ValidationMessageFor(model => model.TeamCity) %>
  45.             </div>
  46.             
  47.             <p>
  48.                 <input type=»submit» value=»Create» />
  49.             </p>
  50.         </fieldset>
  51.  
  52.     <% } %>
  53.  
  54.     <div>
  55.         <%: Html.ActionLink(«Back to List», «Index») %>
  56.     </div>
  57.  
  58. </asp:Content>

Si ejecutamos la aplicación y accedemos a la página /Team/Create, vemos que los mensajes de error aparecen inmediatamente sin tener que esperar a los postbacks. Esto se debe a que ahora la validación se realiza inicialmente en el cliente (mediante el uso de javascript).

Esto es todo lo que necesitamos aplicar para establecer una validación en el lado cliente. En este caso todos los campos son chequeados en el navegador antes de enviar la información a las acciones del controlador, y la respuesta de validación es inmediata.

 

Uso de RIA Services desde ASP.NET MVC

En las aplicaciones web tradicionales las diferentes capas lógicas (lógica de presentación, lógica de negocio, acceso a datos..) se distribuyen generalmente en dos capas físicas que se encuentran en el servidor. La lógica de presentación y de negocio suelen estar dentro de la misma capa, por lo que la comunicación entre ambas no supone ninguna complejidad.

web traditional 

El hecho de implementar una aplicación RIA supone desplazar una de dichas capas lógicas, en concreto, la capa de presentación a la parte cliente. Esto, además de convertirlo en un “cliente pesado”, complica las comunicaciones entre la lógica de presentación y la lógica de negocio.

ria app 

Para solucionar este problema aparecen los RIA Services. El objetivo de los RIA Services es simplificar el desarrollo de aplicaciones RIA, para que podamos desarrollar aplicaciones de este tipo como si fuesen aplicaciones web tradicionales. Estos servicios  trabajan en las capas intermedias ofreciendo control de acceso, cambios y operaciones definidas por el usuario, así como funciones de de validaciones, autentificación de usuarios y roles en las capas superiores.

ria services 

Con estos servicios aparece un nuevo DataSource llamado  DomainDataSource que nos va a permitir trabajar de una manera bastante cómoda y sencilla contra servicios de dominio que se exponen con RIA Services.

ria 

Después de esta pequeña explicación teórica (ver más) vamos a ver dichos servicios en acción 😉

En un artículo anterior vimos como utilizar los RIA Services para implementar una aplicación ASP.NET MVC cuyo cliente estaba basado en tecnología Silverlight. En este caso vamos a ver como podemos utilizar este tipo de servicios desde una aplicación basada completamente en ASP.NET MVC.

Para ello creamos una aplicación de tipo ASP.NET MVC 2 Web Application llamada RiaServices. A continuación, creamos la base de datos que se llamará UserDB.mdf, y en la que añadimos una tabla llamada Users que tendrá los siguientes campos:

image 

A continuación creamos el modelo de datos con el que vamos a trabajar, y a través del cual interactuaremos mediante el uso de RIA Services. Para ello dentro de la carpeta Models, hacemos clic con el botón derecho y añadimos un elemento de tipo ADO.NET Entity Model Data que llamaremos UserModel.edmx, y que estará basado en la base de datos creada inicialmente.

image 

Por último añadimos un servicio de dominio a nuestra aplicación, que es el que nos va a permitir comunicar de manera sencilla la lógica de presentación y la lógica de negocio. Para ello utilizaremos un elemento de tipo DomainService al que llamaremos UserService

image image

Una vez definido el servicio, vamos a pasar a implementarlo dentro de la aplicación para extraer información de nuestro modelo de datos. Para ello:

Dentro del controlador HomeController:

· Añadimos la referencia a nuestro modelo

  1. using RiaServices.Models;

· Inicializamos el servicio creado, y añadimos una lista de usuarios que más adelante rellenaremos con los valores extraídos mediante el servicio:

  1. UserService service = new UserService();
  2.         IQueryable<Users> usuarios;

· Añadimos un resultado de acción llamado List(), que se encargará de lanzar el servicio y obtener los datos de los usuarios a partir del mismo:

  1. public ActionResult List()
  2.         {
  3.             usuarios = service.GetUsers();
  4.             return View(usuarios);
  5.         }

Implementamos su correspondiente vista:

image 

Cuyo código será el siguiente:

  1. <h2>List</h2>
  2.     <% foreach (var item in Model)
  3.        { %>
  4.            <%=Html.ActionLink(item.UserName,"Details", new {id = item.UserID} )%>
  5.            Phone: <%=Html.Encode(item.UserPhone) %><br />
  6.     <% } %>

*Es necesario modificar el atributo Inherits, y poner:

  1. System.Web.Mvc.ViewPage<IQueryable<RiaServices.Models.Users>>

A continuación configuramos el resultado de acción Details, que nos mostrará los detalles del elemento seleccionado. Para ello implementamos uno de los métodos que se encuentra definido dentro del servicio Usersservice, y que  nos permite obtener todos los usuarios definidos en nuestro modelo de datos.

  1. public ActionResult Details(int id)
  2.         {
  3.             usuarios= service.GetUsers();
  4.             var usuario = (from t in usuarios
  5.                            where id == t.UserID
  6.                            select t).FirstOrDefault();
  7.             return View (usuario);
  8.  
  9.         }

Implementamos su correspondiente vista:

image 

Cuyo código será el siguiente:

  1. <h2>Details</h2>
  2.  
  3.     <fieldset>
  4.         <legend>Fields</legend>
  5.         
  6.         <div class="display-label"><b>UserID</b></div>
  7.         <div class="display-field"><%: Model.UserID %></div>
  8.         
  9.         <div class="display-label"><b>UserName</b></div>
  10.         <div class="display-field"><%: Model.UserName %></div>
  11.         
  12.         <div class="display-label"><b>UserAge</b></div>
  13.         <div class="display-field"><%: Model.UserAge %></div>
  14.         
  15.         <div class="display-label"><b>UserPhone</b></div>
  16.         <div class="display-field"><%: Model.UserPhone %></div>
  17.         
  18.     </fieldset>
  19.     <p>
  20.  
  21.         <%: Html.ActionLink("Edit", "Edit", new { id=Model.UserID }) %> |
  22.         <%: Html.ActionLink("Back to List", "Index") %>
  23.     </p>

Si ejecutamos nuestra aplicación y navegamos hasta la dirección http://[localhost]/Home/List accedemos a una vista en la que se muestra nuestra lista de usuarios. Y si pinchamos en cualquiera de ellos podemos acceder a sus detalles.

image image

Además podemos implementar el resto de acciones (CRUD) sobre nuestro DomainDataSource, implementando los distintos métodos con los que contamos dentro de nuestro servicio UserService como: InsertUser, UpdateUser, DeleteUser…¡¡¡Que intentaremos ver más adelante!!!

[Evento] WP7 Se presenta en Pamplona

Recordaros que el próximo martes, 14 de Diciembre, se presenta en Pamplona Windows Phone 7, en un evento en el que se verán, de forma práctica, las principales novedades y características que presenta este dispositivo tanto para su uso en el entorno empresarial como para el personal. Para ello contamos con 3 grandes profesionales:

En dicho evento veremos cuales son las nuevas “experiencias” que ofrece WP7 como: Xbox Live, redes sociales, entornos dinámicos…y que nos permiten entrar en una nueva dimensión de movilidad.

También veremos como se puede desarrollar entornos productivos, dinámicos y de alto rendimiento, de forma sencilla, para conseguir interfaces de usuario enriquecidas mediante el uso de aplicaciones Silverlight.

Por último, podremos ver como desarrollar e implementar aplicaciones 3D en XNA para WP7, desde donde podemos disfrutar de ellas con el mayor rendimiento y calidad posible. 

Si aún no os habéis apuntado… ¡¡a que estáis esperando!! Guiño 

Inscribirse aquí