Configurar “permiso” para recrear tablas en VS 2010

Trabajando en una aplicación web de gestión de productos me he encontrado con que, en una de las tablas de mi base de datos, olvidé definir uno de los campos necesarios . A posteriori he ido a añadirlo y  VS no me dejaba guardar las nuevas tablas con los cambios realizados…¡¡Ya no me acordaba de esto!!!.

Por temas de seguridad VS 2010 esta configurado, por defecto, de forma que no permite rehacer las tablas una vez creadas, algo lógico por una parte. Pero si trabajamos con nuestras propias bases de datos, nos damos cuenta que en un gran numero de casos es necesario realizar algún tipo de modificación. Para que esto sea posible es necesario modificar un parámetro de la configuración de VS 2010. Para ello accedemos a Tools ->Options

image

Y dentro de la pestaña DataBase Tools > Table and DataBase Designers tenemos que quitar la selección del checkbox que indica ”Prevent saving changes that require table re-creation” tal y como se observa en la imagen.

image

De esta forma ya podemos trabajar sobre nuestras tablas sin ningún tipo problema.

😉

Personalizar el enrutamiento de nuestra aplicación ASP.NET MVC

Por defecto cuando creamos una aplicación ASP.NET MVC se define una tabla de enrutamiento que se encarga de decidir que controlador gestiona cada petición Web basándose en la URL de dicha petición. Esta forma de enrutamiento presenta dos grandes ventajas con respecto a las aplicaciones tradicionales de ASP.NET:

1. En cada petición URL no se asigna un archivo físico del disco como una página .aspx, sino que se asigna una acción de un controlador (más un parámetro), que nos mostrará una vista específica.

2. Las rutas son lógicas, es decir, siguen la estructura definida en la tabla de enrutamiento, lo que favorece y facilita la gestión de la navegación en nuestro sitio.

A continuación, podemos ver la tabla de enrutamiento que se genera por defecto al crear una aplicación ASP.NET MVC. Esta tabla de enrutamiento se implementa en el archivo global.asax, y esta definida de la siguiente manera:

 

  1. routes.IgnoreRoute(«{resource}.axd/{*pathInfo}»);
  2.  
  3.             routes.MapRoute(
  4.                 «Default»,                                              // Route name
  5.                 «{controller}/{action}/{id}»,                           // URL with parameters
  6.                 new { controller = «Home», action = «Index», id = «»// Parameter defaults
  7.             );

Si implementamos nuestra aplicación, sin modificar este enrutado, podemos comprobar que, según los parámetros iniciales, se toma por defecto el controlador Home, y la acción Index (tenga o no identificador) como se puede observar en las siguientes imágenes:

image image

Esto funciona así ya que la cadena «Home» se convierte en el parámetro del controlador {controller}, y la cadena «Index» en el parámetro de la acción {action}

Si en nuestra aplicación vamos a utilizar varios controladores nos interesa definir sus rutas de forma individual. Para ello vamos a ver un pequeño ejemplo de como se podría personalizar nuestra tabla de enrutamiento. En nuestro caso, partimos de un proyecto ASP.NET MVC creado para la gestión de libros y al que queremos añadir la posibilidad de gestionar música. Para ello añadimos un nuevo controlador que se llamará Music, y que contará con una acción Category que simplemente nos tiene que mostrar un texto plano en el que ponga la categoría de la música que estamos indicando a través de la URL.

El código que utilizaremos para definir el enrutamiento de nuestra aplicación de música será el siguiente (siguiendo la estructura básica):

  1. routes.MapRoute(
  2.                 «Musica»,                                                         
  3.                 «{controller}/{action}/{categoria}»,                              
  4.                 new { controller = «Music», action = «Category», categoria = «»
  5.             );

Y dentro de nuestro controlador añadiremos el código:

 

  1. public string Category(string categoria)
  2.         {
  3.  
  4.             return «Categoría: « + «<b>»+ categoria + «</b>»;
  5.  
  6.         }

 

Al compilar nuestra aplicación podemos comprobar que si ejecutamos la ruta especificada para nuestro apartado de música, pasándole un parámetro de tipo categoría como puede ser Jazz, se nos muestra el resultado definido a través de la acción Category.

image

Este es un ejemplo muy simple, pero a la vez es extensible a cualquier tipo de aplicación más compleja. Para profundizar en el tema y ver más opciones referentes al mismo, aquí os dejo una página muy útil para introducirse en el mundo del enrutamiento con ASP.NET, en general, y también para MVC. Os recomiendo echarle un vistazo, ya que a mi me a servido muchísimo para ponerme al día con este tema…;)

Otras fuentes:

http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx (depuración de enrutamiento)

Automatizar documentos Office 2010 con datos de SharePoint 2010

Como Office 2010 y SharePoint 2010 ya están al caer, me apetecía crear una aplicación que nos permita trabajar con ambas plataformas, y que por supuesto tenga alguna utilidad interesante. En el artículo de hoy vamos a ver como podemos automatizar nuestros documentos de Word 2010 con los datos que obtenemos de una lista de contactos de SharePoint 2010. Esto es muy útil para informes que siguen una misma estructura como puede ser la invitación a un evento, que es el caso que vamos a ver a continuación.

Para ello, partiendo de un documento inteligente (Smart Document), vamos a utilizar la potencia que nos ofrecen las herramientas VSTO (Visual Studio Tools for Office) para la creación de aplicaciones de negocio para Office. Estas ya vienen integradas en VS 2010, y nos permiten crear aplicaciones tanto para la versión 2007 como para la versión 2010 de Office.

Abrimos VS 2010 y creamos un proyecto de tipo Word Document2010, que en nuestro caso llamaremos InvitacionCES.

image 

Una vez creado el documento sobre el que vamos a trabajar, lo primero que hacemos es añadir un elemento de tipo Action Pane Control, que utilizaremos como navegador de nuestros contactos. Para ello hacemos clic con el botón derecho sobre nuestro proyecto y seleccionamos Add > New Item> ActionsPaneControl que llamaremos NavegadorContactos.

image 

Dentro de nuestro panel de acciones, añadiremos los controles que vamos a utilizar para mostrar las propiedades de los elementos de la lista, teniendo en cuenta cuales son las propiedades que queremos mostrar. Viendo los elementos que debemos rellenar en nuestro documento, nuestro panel de acciones debe tener un aspecto similar a este:

image

Hasta este punto hemos diseñado nuestro panel de acciones, pero todavía nos falta añadirlo al documento Word para que este se visualice, y darle la funcionalidad deseada. Para lo primero, es necesario crear una instancia del control en el archivo ThisDocument.cs de nuestra aplicación:

  1. NavegadorContactos Contactos = new NavegadorContactos();

Y hacer que dicho control se añada a la aplicación cuando arrancamos Word. Esto último se hace a través del evento ThisDocument_Startup

  1. private void ThisDocument_Startup(object sender, System.EventArgs e)
  2.         {
  3.             this.ActionsPane.Controls.Add(Contactos);
  4.         }

A continuación vamos a darle funcionalidad al “navegador de contactos”. En nuestro caso, vamos a implementar un servicio web que nos permita conectar la aplicación cliente de Office con nuestro sitio SharePoint: http://sharepoint2010:200 y que rellene los controles de nuestro panel con los datos de la lista de contactos. Para añadir un servicio web a la misma, pinchamos con el botón derecho sobre Referencias > Agregar referencia de servicio en el explorador de soluciones. Dentro de todos los servicios disponibles en la máquina local, especificamos la URL del servicio al que nos queremos conectar, que en nuestro caso es http://localhost:200/_vti_bin/Lists.asmx (ya que Contactos es un tipo de Lista), y le damos el nombre de ContactosSP. De esta manera ya podemos usar este servicio Web en nuestro proyecto.

image 

Ahora que ya hemos creado nuestro servicio web para conectarnos a la aplicación SharePoint, vamos a implementar el código necesario para que los controles realicen su función correctamente.  Para ello vamos al archivo NavegadorContactos.cs, y añadimos dos clases más aparte de la existente (NavegadorContactos) una que se encargará de construir los Items que forman nuestro ComboBox:

Elementos del combobox
  1. public class Item
  2.     {
  3.         public string Name;
  4.  
  5.         public Item(string name)
  6.         {
  7.             Name = name;
  8.  
  9.         }
  10.         public override string ToString()
  11.         {
  12.             // Genera el texto mostrado en el ComboBox
  13.             return Name;
  14.         }
  15.     }

Y otra que se encargará de construir un objeto Contacto con los siguientes atributos:

 

 

Elemento Contacto
  1. public class Contacto
  2.     {
  3.         public string Name;
  4.         public string LastName;
  5.         public string City;
  6.         public string ZipCode;
  7.         public string Country;
  8.         public string Email;
  9.         public string Telephone;
  10.         public string Company;
  11.  
  12.         public Contacto(string name, string lastname, string city, string zipcode, string country, string email, string telephone, string company)
  13.         {
  14.             Name = name;
  15.             LastName = lastname;
  16.             City = city;
  17.             ZipCode = zipcode;
  18.             Country = country;
  19.             Email = email;
  20.             Telephone = telephone;
  21.             Company = company;
  22.         }
  23.  
  24.     }

 

A continuación dentro de la clase NavegadorContactos, inicializamos las variables que vamos a utilizar y que son necesarias para ir leyendo las propiedad de los elementos de la lista en SharePoint, ya que dicha información la obtenemos a partir de un documento XML

 

Inicializacion variables
  1. XmlNode listNode, contactFN, contactLN, contactEM, contactMP, contactWC, contactZC, contactCR, contactCN;
  2.         XmlAttributeCollection nodeAttribs;
  3.         XmlDocument xmlDoc;
  4.         XmlNode ndViewFields;
  5.         XmlNode ndListItems;
  6.         Contacto cont;
  7.         List<Contacto> mContact = new List<Contacto>();

Creamos un método llamado BuscarContactos que es el que se encargará de conectarse al servicio web creado y obtener los datos almacenados en nuestra lista de Contactos. Constará del siguiente código:

Buscar Contactos
  1. public void BuscarContactos()
  2.         {
  3.  
  4.             ContactosSP.Lists contactosService = new InvitacionCES.ContactosSP.Lists();
  5.  
  6.             // Creamos las credenciales que nos permiten conectarnos a
  7.             // SharePoint y las asignamos al servicio
  8.  
  9.             System.Net.NetworkCredential myCred = new System.Net.NetworkCredential(«Administrador», «AdmSP2010»);
  10.  
  11.             contactosService.Credentials = myCred;
  12.  
  13.             // Recuperamos
  14.  
  15.             listNode = contactosService.GetList(«Contactos»);
  16.  
  17.             // Creamos las estructuras XML necesarias para volcar nuestra información
  18.  
  19.             xmlDoc = new System.Xml.XmlDocument();
  20.  
  21.             ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, «ViewFields», «»);
  22.  
  23.  
  24.             // Indicamos los campos que queremos que nos muestre, es decir la vista
  25.  
  26.             ndViewFields.InnerXml = «<FieldRef Name=’LinkTitle’/><FieldRef Name=’FirstName’/><FieldRef Name=’Email’/><FieldRef Name=’CellPhone’/><FieldRef Name=’WorkCity’/><FieldRef Name=’WorkZip’/><FieldRef Name=’Company’/><FieldRef Name=’WorkCountry’/>»;
  27.  
  28.  
  29.             try
  30.             {
  31.                 // Indicamos que lista queremos que lea y la vista de la misma
  32.  
  33.                 ndListItems = contactosService.GetListItems(«Contactos», null, null, ndViewFields, null, null, null);
  34.  
  35.                 // Procesamos cada elemento recuperado buscando el título
  36.  
  37.                 foreach (XmlNode node in ndListItems.ChildNodes)
  38.                 {
  39.  
  40.                     // El contenido va en los subnodos que nos devuelve SharePoint
  41.  
  42.                     foreach (XmlNode subnode in node.ChildNodes)
  43.                     {
  44.  
  45.                         // Buscamos valores de los atributos del nodo
  46.  
  47.                         nodeAttribs = subnode.Attributes;
  48.  
  49.                         if (nodeAttribs != null)
  50.                         {
  51.                             // Obtenemos los valores de los atributos de los subnodos
  52.                             contactFN = nodeAttribs.GetNamedItem(«ows_FirstName»);
  53.                             contactLN = nodeAttribs.GetNamedItem(«ows_LinkTitle»);
  54.                             contactEM = nodeAttribs.GetNamedItem(«ows_Email»);
  55.                             contactMP = nodeAttribs.GetNamedItem(«ows_CellPhone»);
  56.                             contactWC = nodeAttribs.GetNamedItem(«ows_WorkCity»);
  57.                             contactZC = nodeAttribs.GetNamedItem(«ows_WorkZip»);
  58.                             contactCR = nodeAttribs.GetNamedItem(«ows_WorkCountry»);
  59.                             contactCN = nodeAttribs.GetNamedItem(«ows_Company»);
  60.                             //Creamos nuestros contactos y los añadimos a la lista de contactos
  61.                             cont = new Contacto(contactFN.Value, contactLN.Value, contactWC.Value, contactZC.Value, contactCR.Value, contactEM.Value, contactMP.Value, contactCN.Value);
  62.                             mContact.Add(cont);
  63.                             //Anadimos los apellidos de nuestros contactos al comboBox
  64.                             cb_Contactos.Items.Add(new Item(cont.LastName));
  65.  
  66.                         }
  67.  
  68.  
  69.                     };
  70.  
  71.                 };
  72.  
  73.             }
  74.             // Definimos una excepción de conexión al servicio web
  75.  
  76.             catch (System.Web.Services.Protocols.SoapException ex)
  77.             {
  78.  
  79.                 MessageBox.Show(«Message:n» + ex.Message + «nDetail:n» + ex.Detail.InnerText + «nStackTrace:n» + ex.StackTrace);
  80.  
  81.             }
  82.  
  83.         }

Llamaremos a dicho método cuando se haga clic sobre el botón Conectar. Mediante este método se van a cargar en nuestro ComboBox los apellidos de los distintos contactos que tengamos almacenados en nuestra lista de Contactos.

Conectar
  1. private void but_Conectar_Click(object sender, EventArgs e)
  2.         {
  3.             BuscarContactos();
  4.             //Deja no visible el control conectar
  5.             but_Conectar.Visible = false;
  6.         }

Y por último definimos el evento, que hará que al seleccionar en cada uno de elementos del combobox se nos carguen el resto de valores de nuestro contacto (nombre, email, teléfono…) tanto en los controles del navegador como en los controles del documento.

 

Carga de contactos
  1. private void cb_Contactos_SelectedIndexChanged(object sender, EventArgs e)
  2.         {
  3.             for (int i = 0; i <= cb_Contactos.SelectedIndex; i++)
  4.             {
  5.                 Globals.ThisDocument.richTextContentControl1.Text = mContact[i].LastName;
  6.  
  7.                 tb_Email.Text = mContact[i].Email;//Rellenamos el cuadro de texto Email del navegador
  8.                 Globals.ThisDocument.richTextContentControl2.Text = tb_Email.Text;//Rellenamos el campo Email del documento
  9.  
  10.                 tb_City.Text = mContact[i].City;//Rellenamos el cuadro de texto Ciudad del navegador
  11.                 Globals.ThisDocument.richTextContentControl3.Text = tb_City.Text;//Rellenamos el campo Ciudad del documento
  12.  
  13.                 tb_ZipCode.Text = mContact[i].ZipCode;//Rellenamos el cuadro de texto Codigo Postal del navegador
  14.                 Globals.ThisDocument.richTextContentControl4.Text = tb_ZipCode.Text;//Rellenamos el Codigo Postal del documento
  15.  
  16.                 tb_Country.Text = mContact[i].Country;//Rellenamos el cuadro de texto Pais del navegador
  17.                 Globals.ThisDocument.richTextContentControl6.Text = tb_Country.Text;//Rellenamos el campo Pais del documento
  18.  
  19.                 tb_Telephone.Text = mContact[i].Telephone;//Rellenamos el cuadro de texto Telefono del navegador
  20.                 Globals.ThisDocument.richTextContentControl5.Text = tb_Telephone.Text;//Rellenamos el campo Telefono del documento
  21.  
  22.                 tb_Company.Text = mContact[i].Company;
  23.                 Globals.ThisDocument.richTextContentControl7.Text = tb_Company.Text;
  24.  
  25.                 tb_Name.Text = mContact[i].Name; //Rellenamos el cuadro de texto Nombre del navegador
  26.                 Globals.ThisDocument.richTextContentControl8.Text = tb_Name.Text;//Rellenamos el campo Nombre del documento
  27.             }
  28.  
  29.  
  30.         }

Para ver que todo funciona correctamente, compilamos (F5) y observamos que el resultado es el siguiente:

image

Como se puede ver, es posible navegar por los distintos elementos mediante el combobox, de forma que podemos rellenar nuestros documentos de forma automática y sin el menor esfuerzo….para el usuario.

Además si probamos a añadir más contactos en nuestra lista de SharePoint veremos como estos se actualizan dinámicamente al conectarnos al servicio web desde nuestro navegador de contactos.

Espero que os resulte interesante.

Descargar el proyecto aquí

Diferencias en la programación de ASP.NET MVC con VS 2008 y VS 2010

Trabajando con las últimas versiones de Visual Studio, 2008 en casa y 2010 en el trabajo, me he encontrado con algunas diferencias entre ambas. En concreto he visto dos pequeñas “cositas” a tener en cuenta.

Por un lado, tanto si programamos con VS 2008 como 2010, al crear un nuevo controlador existe la opción de añadir una serie de métodos básicos (Create, Update, Details) que facilitan la interactuación con nuestro modelo de datos. Sin embargo, mientras que en la versión 2008 podemos implementar el método Delete de forma automática, en VS 2010 no tenemos esta opción, como se puede observar en las siguientes imágenes:

image

              VS 2008                                                VS 2010

De forma que cuando vamos a crear una vista en VS 2008, podemos aplicar un tipo de contenido de vista llamado Delete, que nos crea el  formulario básico para la eliminación de elementos. Mientras que en 2010 tendremos que crear esta vista a mano.

image

          VS 2008

Por otro lado si seguimos los tutoriales expuestos en la página http://www.asp.net/mvc/, donde encontramos numerosos recursos para el desarrollo de aplicaciones ASP.NET MVC, vemos que estos están preparados para trabajar con VS 2008. Por ejemplo, dentro del método Edit se utiliza la función ApplyPropertyChanges para aplicar las modificaciones sobre las propiedades de los elementos de nuestro modelo de datos:

  1. mbook.ApplyPropertyChanges(bookOriginal.EntityKey.EntitySetName,bookToEdit);

Mientras que en VS 2010 esta función está obsoleta y es necesario implementar la función ApplyCurrentValues quedando el código de la siguiente manera:

  1. mbook.ApplyCurrentValues(bookOriginal.EntityKey.EntitySetName, bookToEdit);

Según vaya encontrado más diferencias o aspectos a tener en cuenta os los iré contando.

Modificar elementos del modelo de datos en ASP.NET MVC

En mi post anterior vimos como se podía mostrar los elementos de una base de datos de manera sencilla, pero todavía no éramos capaces de interactuar con ella. Así que vamos a ir viendo como podemos conseguir trabajar con nuestro modelo de datos, implementando algunas acciones específicas mediante un controlador y una serie de vistas.

Para ello vamos a partir del proyecto MvcBookApp, que cree en el post anterior y vamos a ir dotándolo de las funcionalidades Crear, Editar y Mostrar detalles, que son las acciones que se nos añadieron al controlador HomeController al crearlo:

image

Inicialmente añadiremos la referencia a 

  1. using MvcBookApp.Models

de forma que podamos trabajar más cómodamente con los objetos definidos en nuestro modelo. A continuación comenzaremos por implementar la opción Crear, que nos permitirá crear nuevos elementos en nuestra base de datos. Para ello vamos al archivo HomeController.cs y dentro del método Create():

  1. Hacemos clic con el botón derecho y añadimos una vista
  2. Dejamos el nombre que toma por defecto (Create)
  3. Verificamos que está seleccionado el chekbox “Create a strongly-typed view”
  4. Seleccionamos el valor MvcBookApp.Models.Book dentro de la lista desplegable View data class
  5. Seleccionamos el valor Create dentro de la lista desplegable View content
  6. Hacemos clic en el botón Add para añadir la nueva vista.

image image

Como podemos observar el controlador contiene dos métodos denominados Create(). El primero se encarga de mostrar el formulario HTML para crear un nuevo registro. El segundo método se llama cuando se ejecuta el formulario HTML en el servidor, y este contiene la lógica para la inserción de un nuevo libro en la base de datos Book.

Como no nos interesa que el usuario cree el valor del bookID, sino que su actualización sea dinámica, vamos a quitarlo de la vista. Para ello eliminamos el siguiente código:

  1. <div class="editor-label">
  2.                 <%= Html.LabelFor(model => model.bookID) %>
  3.             </div>
  4.             <div class="editor-field">
  5.                 <%= Html.TextBoxFor(model => model.bookID) %>
  6.                 <%= Html.ValidationMessageFor(model => model.bookID) %>
  7.             </div>

Por último vamos a establecer el código que se ejecutará como resultado de la acción Create, dentro de las acciones del controlador:

  1. // POST: /Home/Create
  2.  
  3.         [HttpPost]
  4.         public ActionResult Create(Book bookC)
  5.         {
  6.             try
  7.             {
  8.                 // TODO: Add insert logic here
  9.                 if (!ModelState.IsValid)
  10.                 {
  11.                     return View();
  12.                 }
  13.                 mbook.AddToBooks(bookC);
  14.                 mbook.SaveChanges();
  15.                 return RedirectToAction("Index");
  16.             }
  17.             catch
  18.             {
  19.                 return View();
  20.             }
  21.         }

        

De esta forma si compilamos podemos ver como al seleccionar el vinculo Create new, nos aparece un formulario para introducir un nuevo elemento,permitiéndonos crear nuevos elementos:

image image

A continuación vamos a implementar la funcionalidad de Editar. Para ello vamos a seguir los mismos pasos que antes, y dentro del archivo HomeController.cs, en el método Edit:

  1. Hacemos clic con el botón derecho y añadimos una vista
  2. Dejamos el nombre que toma por defecto (Edit)
  3. Verificamos que está seleccionado el chekbox “Create a strongly-typed view”
  4. Seleccionamos el valor MvcBookApp.Models.Book dentro de la lista desplegable View data class
  5. Seleccionamos el valor Edit dentro de la lista desplegable View content
  6. Hacemos clic en el botón Add para añadir la nueva vista.

image image

Por último establecemos el código que se ejecutará como resultado de la acción Edit, y que será el siguiente:

  1. // GET: /Home/Edit/5
  2.         public ActionResult Edit(int id)
  3.         {
  4.             var bookE = (from m in mbook.Books
  5.  
  6.                                where m.bookID == id
  7.  
  8.                                select m).First();
  9.  
  10.             return View(bookE);
  11.         }
  12.  
  13.         //
  14.         // POST: /Home/Edit/5
  15.  
  16.         [HttpPost]
  17.         public ActionResult Edit(Book bookE)
  18.         {
  19.             try
  20.             {
  21.                 var bookO = (from m in mbook.Books
  22.  
  23.                                      where m.bookID == bookE.bookID
  24.  
  25.                                      select m).First();
  26.  
  27.                 if (!ModelState.IsValid)
  28.  
  29.                 return View(bookO);
  30.                 mbook.ApplyCurrentValues(bookO.EntityKey.EntitySetName, bookE);
  31.                 mbook.SaveChanges();
  32.  
  33.                 return RedirectToAction("Index");
  34.             }
  35.             catch
  36.             {
  37.                 return View();
  38.             }
  39.         }

Si compilamos podemos ver como al seleccionar el vinculo Edit, nos aparece un formulario que nos permite modificar el elemento seleccionado de nuestra lista.

image image

Para terminar vamos a implementar la funcionalidad que nos permita mostrar los detalles de un elemento. Para ello vamos a seguir los mismos pasos que antes, y dentro del archivo HomeController.cs, en el método Details:

  1. Hacemos clic con el botón derecho y añadimos una vista
  2. Dejamos el nombre que toma por defecto (Details)
  3. Verificamos que está seleccionado el chekbox “Create a strongly-typed view”
  4. Seleccionamos el valor MvcBookApp.Models.Book dentro de la lista desplegable View data class
  5. Seleccionamos el valor Details dentro de la lista desplegable View content
  6. Hacemos clic en el botón Add para añadir la nueva vista.

image image

Por último implementaremos la funcionalidad para mostrar, en formato de detalles, los elementos de nuestra base de datos mediante el siguiente código:

  1. public ActionResult Details(int id)
  2.         {
  3.             Book book = mbook.Books.FirstOrDefault(elemento => elemento.bookID == id);
  4.             return View(book);
  5.         }

Si compilamos podemos ver como al seleccionar el vinculo Details, obtenemos los detalles del elemento seleccionado.

image

Para personalizar un poco la aplicación, he modificado alguna de las vistas para que aparezcan los títulos en negrita, y también he eliminado el campo del ID porque no me interesa que se vea en algunas ocasiones. De esta forma ya tendríamos nuestra aplicación perfectamente funcionando, y le podríamos añadir nuevas funcionalidades como, por ejemplo, la opción Delete.

Mostrar datos de un Modelo en ASP.NET MVC

Para comenzar mi andadura aquí en Geeks, y también con esta plataforma, voy a escribir acerca de como crear un modelo de datos en nuestra aplicación ASP. NET MVC  y sobre como podemos mostrar los datos que extraemos del mismo de forma sencilla.

Lo primero que vamos a hacer es crear nuestra base de datos, donde almacenaremos la información que queremos mostrar en la página, que en nuestro caso serán un conjunto de libros. Hacemos clic con el botón derecho sobre App_Data, y seleccionamos Add > New Item, de tipo SQL Server DataBase, y le damos el nombre de BooksDB.mdf.

image image

*Por defecto todos los elementos de tipo de datos que vayamos a utilizar en nuestra aplicación web, se deben almacenar en la carpeta App_Data. Si no lo hacemos así, la propia aplicación se encargará de preguntárnoslo.

image 

Una vez creada nuestra base de datos (BookDB.mdf) , hacemos doble clic sobre la misma y se nos desplegará en el Explorador de Servidores. Dentro de Books.mdf, hacemos clic con el botón derecho sobre Tables , y seleccionamos Add > New Table.

image

Dentro de la tabla, vamos a añadir los campos específicos que queremos que tengan cada uno de los elementos de nuestra tabla, que en nuestro caso son: bookID (int), Titulo (nchar), Autor (nchar), y deseleccionamos la opción “Allow Nulls”, ya que nuestros elementos deben contener las tres propiedades definidas, y no se pueden quedar ninguno en blanco.

image  

A continuación, establecemos como Primary Key la columna bookID de nuestra tabla, y ponemos su propiedad IsIdentity a True .

image image 

Finalmente guardamos nuestra tabla dándole el nombre de Books.

image

Una vez creada la tabla, vamos a introducir algunos elementos a la misma. Para ello, hacemos clic con el botón derecho sobre Books, seleccionamos Show Table Data, y añadimos los libros que queremos mostrar inicialmente.

 imageimage

A continuación es necesario crea un modelo que nos permita conectar nuestra aplicación con la base de datos, para ello vamos a la carpeta Models > Add > New Item. Seleccionamos un elemento de tipo ADO.NET Entity Data Model que llamaremos BookModel, y vamos siguiendo el Wizard, tal y como se puede observar en las siguientes imágenes.

image image image image

De esta forma ya tenemos creado nuestro modelo, que tendrá el siguiente aspecto, y al que cambiaremos el nombre de Books por Book.

image 

Una vez creado el modelo, vamos a crear la vista y el controlador que nos permitan interactuar con él. Para ello, primero vamos a la carpeta Controllers, eliminamos el archivo HomeController que se nos ha creado por defecto y añadimos otro llamado igual, haciendo clic con el botón derecho mediante Add > Controller. Para este, seleccionaremos la opción de añadir los métodos Create, Update y Details, de forma que no sólo podamos ver los elementos de nuestro modelo, sino que también podamos editarlos o crear nuevos, como veremos en el próximo articulo.

image image

Si accedemos al código del controlador, podemos ver que hay varios métodos de tipo ActionResult. Estos son los que se encargan de lanzar las acciones especificas que se deben realizar en cada vista. En nuestro caso, queremos asociar la acción Index con una vista que nos permita mostrar en la página principal una lista con todos los elementos de nuestro modelo. Para ello eliminamos previamente, la vista Index, que se encuentra dentro de las carpetas Views > Home, y creamos una nueva vista haciendo clic con el botón derecho en Index() dentro del archivo HomeController.cs, tal y como se ve en la imagen.

image image

Al crear una nueva vista debemos definir una serie de parámetros, en función de lo que queremos mostrar y cómo. Dejamos el nombre que toma por defecto (Index), y seleccionamos la opción Create a strongly-typed view. Como View Data Class, escogemos MvcBookApp.Models.Book. *Si esta opción no nos aparece inicialmente, es necesario depurar la aplicación y volver a repetir este último paso.

Y como View content, debemos seleccionar List, ya que queremos que dicha vista nos muestre nuestro elementos en formato lista. El resto de parámetros los dejamos tal y como están, y pulsamos Add. Como vemos, la vista que se nos crea es una página .aspx, por lo que podemos modificar la interfaz de la misma a través de este archivo, bien en modo diseño o de código.

Por último volvemos a HomeController.cs, donde crearemos una instancia a nuestra entidad del modelo de datos:

  1. MvcBookApp.Models.BooksDBEntities mbook = new Models.BooksDBEntities();

Y modificaremos el resultado de la acción de Index, para que se muestre nuestra entidad de datos a través de una lista. El código de la misma será el siguiente:

  1. public ActionResult Index()
  2.         {
  3.             return View(mbook.Books.ToList());
  4.         }

Si compilamos nuestra aplicación (F5) veremos que nos aparece la lista con nuestro libros, pero no podemos interactuar con ella, ya que no hemos definido ni las vistas, ni las acciones del controlador que nos lo permitan. Esto lo veremos en el siguiente Post 😉

image

¡¡Así que seguid atentos!!

Microsoft Office Web Apps

Las Microsoft Office Web Apps son el recurso complementario para aplicaciones de Word, Excel, PowerPoint y OneNote que permiten que los usuarios tengan acceso a documentos desde cualquier lugar. De todas ellas, la funcionalidad que me parece más interesante es PowerPoint Web App. Ésta característica, nueva en Microsoft Office 2010, permite difundir una presentación de diapositivas de PowerPoint 2010 a espectadores remotos en un explorador web o en un servidor SharePoint. Pero la pregunta es ¿y como hacemos esto?

A continuación vamos a ver que es muy sencillo realizar una publicación de este tipo. Para ello abrimos Power Point 2010,  y dentro de la pestaña Presentación con diapositivas seleccionamos la opción Difundir presentación de diapositivas.

image

Si hacemos clic en este botón vemos que inicialmente esta definido el PowerPoint Broadcast Service como predeterminado, pero que existe la opción de cambiar el servicio de difusión.

image 

Los servicios de difusión entre los que podemos elegir son:

– Difusión en un explorador web (predefinido)

– Difusión en un sitio SharePoint

El primero de los casos es el más simple, ya que es similar al que se viene utilizando hasta ahora en los webcasts. Se genera una Url de difusión a través de la cual los asistentes pueden acceder a la presentación de manera remota. Este servicio no necesita ningún tipo de configuración específica, pero lo que si es necesario es tener una cuenta de Windows Live ID para poder emitir. Al conectarnos a este servicio, mediante la opción Iniciar difusión, se nos pedirá introducir el usuario y contraseña de nuestra cuenta.

image

Una vez conectados, vemos que se genera la Url correspondiente, que será la que enviaremos a los asistentes a nuestra presentación para que pueden acceder a ella. Por último, sólo nos falta pulsar en Iniciar presentación con diapositivas.

 image image

En el segundo de los casos, si que es necesario realizar una configuración previa para poder emitir nuestras presentaciones desde un entorno SharePoint. Para ello vamos a ver los pasos necesarios que hay que realizar.

  • Instalar Office Web Apps mediante la ejecución del programa de instalación (WCSetup.exe). 
  • Activar los servicios de Office Web Apps en la central de administración, en caso de que no estén activados:
    • Para ello abrimos la Central de Administración> Asistentes de configuración e iniciamos el asistente de configuración del conjunto de servidores. Vamos siguiéndolo hasta llegar a la última pantalla en la que están los servicios, y donde podemos ver su estado y activarlos.

 

image

  • image 

 

  • A continuación debemos crear una colección sitios de publicación de Power Point . Para ello vamos a Crear colección de sitios. Seleccionamos una aplicación web, que en nuestro caso es http://sharepoint2010:500/sitios/, y utilizamos una plantilla de sitio, que llamaremos Presentaciones, de tipo Enterprise > Sitio de difusión de PowerPoint

image 

Una vez que ya tenemos el sitio SharePoint listo para difundir presentaciones Power Point, lo que tenemos que hacer es iniciar la difusión desde la propia aplicación cliente, al igual que en el caso anterior,  pero esta vez seleccionamos la opción Cambiar servicio de difusión > Agregar nuevo servicio donde deberemos indicar la url de nuestro sitio de presentaciones, y el usuario con permisos para la difusión(en nuestro caso el administrador). De forma que obtendremos la url especifica de nuestro sitio donde se va a emitir la presentación.

image imageimage

Además de esta forma podremos definir los usuarios que van a tener acceso a estas presentaciones. Si entramos a la zona de personas y grupos vemos que por defecto ya hay definidos 4 grupos con distintos permisos:

– Administradores de difusión

– Moderadores de la difusión

– Asistentes a la difusión

– Usuarios con acceso al contenido de la difusión

Por último decir que las Office Web Apps se van a integrar en SkyDrive. Esto quiere decir que si tenemos un documento de Office en la nube, podremos abrir y editarlo online, sin necesidad de descargarlo.

En resumen, este tipo de aplicaciones, aportan gran potencia a nuestras organizaciones. ya que permiten compartir y acceder a recursos de manera remota eliminando de esta manera limites de comunicación y publicación, entre otros.

Personalizar entradas de blog en SharePoint 2007

A medida que vamos acumulando una gran cantidad de entradas en nuestro blog de SharePoint, vemos que la forma predeterminada en que estas se muestran no es muy práctica para navegar por ellas. Por que digo esto, porque nos aparecen todos los artículos enteros de forma que, tenemos que ir desplazándonos verticalmente por nuestra página para localizar uno en concreto.

Una forma de hacer que nuestro blog sea más “visual” e intuitivo es limitar el contenido de nuestras entradas para que se muestre sólo un determinado número de palabras. Esta técnica no sólo se puede utilizar en blogs, sino que también sirve para cualquier tipo de lista cuyo “Cuerpo” sean múltiples líneas de texto, como pueden ser listas de artículos, noticias, posts…

El primer paso a dar, consiste en convertir nuestro Web Part a vista de datos XLST, de esta forma podremos trabajar con el código de forma más sencilla. Para ello seleccionamos el elemento web al que queremos aplicar esta vista, y hacemos clic con el botón derecho donde nos aparecerá la opción “Convertir a vista de datos XSLT”

image 

Dentro de la etiqueta <DataSources> que se nos crea, modificamos la definición de nuestros parámetros, para que podamos identificarlos de manera más sencilla. Para ello sustituimos los valores iniciales de DefaultValue y Name

  1. DefaultValue="{FE289146-94E7-4004-814E-7EF446C52100}" Name="ListID

por:

  1. DefaultValue="Entradas de blog" Name="ListName

A continuación localizamos la definición de la plantilla <xsl:template name =”dvt_1”>, y justo encima de ella definimos una plantilla, mediante el código que vemos a continuación, que se encargará de eliminar las etiquetas HTML que se añaden, cada vez que creamos un elemento nuevo en nuestra lista.

  1. <xsl:template name="removeHtmlTags">
  2.     <xsl:param name="html"/>
  3.     <xsl:choose>
  4.         <xsl:when test="contains($html, ‘&lt;’)">
  5.             <xsl:value-of select="substring-before($html, ‘&lt;’)"/>
  6.             <!– Recurse through HTML –>
  7.             <xsl:call-template name="removeHtmlTags">
  8.                 <xsl:with-param name="html" select="substring-after($html, ‘&gt;’)"/>
  9.             </xsl:call-template>
  10.         </xsl:when>
  11.         <xsl:otherwise>
  12.             <xsl:value-of select="$html"/>
  13.         </xsl:otherwise>
  14.     </xsl:choose>
  15. </xsl:template>

Para usar esta plantilla, vamos al elemento <div> donde se muestra el “Cuerpo” (Body) de nuestras entradas, y que podremos identificar mediante la clase “ms-PostBody”, y  sustituimos el siguiente código:

  1. <div class="ms-PostBody">
  2.     <div dir="{ddwrt:GetVar(‘Direction’)}">
  3.         <xsl:value-of disable-output-escaping="yes" select="@Body" />
  4.     </div>
  5. </div>

por :

  1. <div class="ms-PostBody">
  2.     <div dir="{ddwrt:GetVar(‘Direction’)}">
  3.         <xsl:variable name="pureText">
  4.             <xsl:call-template name="removeHtmlTags">
  5.                 <xsl:with-param name="html" select="@Body" />
  6.             </xsl:call-template>
  7.         </xsl:variable>
  8.         <span><xsl:value-of select="substring($pureText, 0, 250)" /></span><br/>
  9.     </div>
  10. </div>

   

Como se puede ver, lo que hacemos es crear un variable pureText que se encargará de almacenar el texto limpio de etiquetas tras llamar a la plantilla removeHtmlTags, y a la que se le aplicará una consulta mediante el método substring que nos devolverá el “Body” de nuestras entradas, desde el carácter 0 al 250, en nuestro caso.

Y para terminar, decir, que he utilizado esta “técnica” porque me parece una de las formas más sencillas que se pueden encontrar para hacer este tipo de personalizaciones.

Tutoriales jQuery

No hace falta que diga que jQuery me tiene encantada. Cada vez que navego por Internet encuentro nuevas y más potentes aplicaciones. Como sería imposible ponerme a implementar todas ellas en mis sitios web, principalmente porque no tendría mucho sentido, me parece interesante dejaros aquí los links donde podéis encontrar varios tutoriales sobre aplicaciones jQuery que podéis utilizar en vuestros propios sitios. En estos tutoriales se puede encontrar tanto una demo en la que se ve el funcionamiento de la aplicación como el código de la misma. Así que disfrutad de ellos:

jQuery Tools Scrollable

Sliding Boxes and Captions with jQuery

10 Fresh jQuery Tutorials to Enhance Navigation Menus

14 Easy to Implement Drop Down Menu Solutions

14 jQuery Plugins for Enhanced Content Viewing

12 Excellent jQuery Plugins for Enhancing Forms

12 Useful jQuery Plugins for Working with Tables

Step By Step To Create Content Slider using jFlow

Create Beautiful jQuery slider tutorial

Using the Wonderful jFlow Plugin

jCarousel

ImageSwitch

Moving Boxes

Making a Content Slider with jQuery UI

Sliding Boxes and Captions with jQuery

AnythingSlider jQuery Plugin

Y para terminar 50 técnicas del uso de jQuery, todas juntas…Posiblemente se repitan alguna de las comentadas anteriormente, pero nunca esta de más:

http://www.smashingmagazine.com/2009/08/23/50-useful-new-jquery-techniques/

😉

Instalar Microsoft SharePoint Server 2010

Esta semana, me he visto enredada en la instalación de SharePoint Server 2010 Beta en nuestra organización con la finalidad de crear un entorno de prueba que nos permita trabajar con las nuevas funcionalidades de esta plataforma. A continuación voy a describir el escenario de trabajo que hemos creado, los pasos que hay que seguir para una correcta instalación de esta plataforma, y los problemas con los que me he encontrado durante la misma.

 

Primero: Nuestro escenario de trabajo.

Para la instalación de SharePoint 2010 hemos creado una máquina virtual en Hyper-V, con las siguientes características :

– Sistema operativo Windows Server 2008 SP2 x64

– 2Gb de RAM

– 40GB de disco duro

Aún teniendo en cuenta que los requisitos mínimos indicados por Microsoft son algo diferentes: http://technet.microsoft.com/es-es/library/cc262485(en-us,office.14).aspx#section3

 

Segundo: Pasos a seguir.

Una vez instalado el sistema operativo, bajamos todas las actualizaciones disponibles para el mismo mediante la aplicación Windows Update. Además debemos tener en cuenta que nuestro servidor debe tener la función de:

– Servidor Web

– Servidor de aplicaciones

Y que, en nuestro caso, debe tener activadas las siguientes características:

image 

Una vez configurado el servidor, arrancamos el ejecutable de Microsoft SharePoint Server 2010, de forma que se nos abrirá la siguiente pantalla.

image 

Inicialmente chequearemos que nuestro equipo presenta todos los requisitos requeridos para la instalación por lo que seleccionamos la opción Instalar requisitos previos de software. En caso de que nos falte alguna de las aplicaciones necesarias se descargaran automáticamente (“casi todas”), o sino lo podemos hacer manualmente desde los siguientes vínculos:

Microsoft SQL Server 2008 Native Client:

http://go.microsoft.com/fwlink/?LinkId=166505

Microsoft SQL Server 2008 Analysis Services ADOMD.NET :

http://www.microsoft.com/downloads/details.aspx?FamilyId=228DE03F-3B5A-428A-923F-58A033D316E1&displaylang=en

ADO.NET Data Services v1.5 CTP2:

http://www.microsoft.com/downloads/details.aspx?FamilyID=a71060eb-454e-4475-81a6-e9552b1034fc&displaylang=en

Microsoft Filter Pack 2.0:

http://www.microsoft.com/downloads/details.aspx?displaylang=es&FamilyID=60c92a37-719c-4077-b5c6-cac34f4227cc

Microsoft "Geneva" Framework Runtime

http://go.microsoft.com/fwlink/?LinkID=165752

Windows PowerShell 2.0 CTP3

http://blogs.msdn.com/powershell/pages/download-windows-powershell.aspx

Si no hemos obtenido ningún error, una vez que ya tengamos todos los requisitos necesarios, podemos continuar con la instalación. Para ello seleccionamos la opción Instalar SharePoint Server. Si todo funciona correctamente se arrancará el wizard de configuración propio de este tipo de aplicaciones. Nos preguntará que tipo de instalación queremos hacer stand alone (único servidor) o en granja de servidores  y continuaremos con el wizard  tal como lo hacíamos en versiones anteriores.

 

Tercero: Problemas

Uno de los problemas que me surgió durante la instalación, es que a la hora de instalar los pre-requisitos,  no podía instalar Windows PowerShell 2.0 CTP3 si ya tenía instalado Windows PowerShell 1.0 que viene con Windows Server 2008.

Solución: desinstalar la versión 1.0 previamente.

Una vez instalados todos los pre-requisitos, y ejecutándose el wizard de configuración de SharePoint…, ¡¡¡y cuando ya pensaba que todo iba bien!!! me apareció el siguiente mensaje:

“Failed to create sample data.
An exception of type Microsoft.Office.Server.UserProfiles.UserProfileException was thrown.  Additional exception information: Unrecognized attribute ‘allowInsecureTransport’. Note that attribute names are case-sensitive. (C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14WebClientsProfileclient.config line 56)”

Cuando aparece un error de este tipo es necesario parar el wizard, arreglarlo y volver a ejecutarlo una vez arreglado. Ante este contratiempo, mi primera reacción fue, voy a ver si a alguien le ha pasado lo mismo, y ¡¡efectivamente!!. Al buscar en Internet, me aparecieron múltiples fuentes en las que se comentaba el mismo problema, y vaya suerte la mía que hemos utilizado Windows Server 2008 y no la versión R2. Y os preguntareís ¿por qué? Pues la razón es que hay que instalar un hotfix para solucionar este problema, que SI esta disponible para Windows Server 2008 y todavía NO para la versión R2.

Solución: instalar el hotfix

Bueno y después de una larga jornada, peleándome para que la máquina funcionara correctamente….hoy ya puedo dormir tranquila.

 

dormir

 

Links de interés (Requerimientos de Hardware y software para la instalación de SharePoint 2010):

http://technet.microsoft.com/en-us/library/cc262485(office.14).aspx

http://code.msdn.microsoft.com/project/download/filedownload.aspx?projectname=kb971831&downloadid=7285