martes, 13 de octubre de 2015

Dando formato a una carta en un elemento Web de SharePoint

Hay veces que necesitamos construir el formato de una carta para ser desplegada en un elemento Web.  Para darle formato necesitamos escribir código HTML de forma dinámica y luego desplegarla al momento que elemento Web es cargado en la página de SharePoint.

image

Lo primero es definir un control asp.net Literal ya que este escribe exactamente lo que le enviemos sin realizar ninguna conversión, esto nos permitirá enviar código HTML dentro del texto.  Asi como se demuestra a continuación:

   <asp:Literal runat="server" ID="uiCarta"></asp:Literal>

En el código adyacente o Code Behind podemos encontrar la siguiente declaración.

public string Carta
       {
           set
           {
               uiCarta.Text = value;
           }
       }

Definimos una propiedad tipo String y definimos el valor a ingresar es para la propiedad Text del control Literal.

Para facilitar su comprensión asumiremos de la definición al obtendremos de codigo definido a continuacion.

var carta = @”

Señores

<b>[NombreUsuario]</b>

<br>

[Departamento]

<br><div style=”text-align:justify”>

Por este medio deseo indicarle…. blalablalallal

</div><br>

<table style=”width=100%;”>

<tr>

<td style=”width=50%;”>

Vo.Bo.

</td>

<td style=”width=50%;”>

Revisado

</td>

</tr>

</table>

”;

carta= carta.replace(“[Usuairo]”,SPContext.Current.Web.CurrentUser.Name).Replace(“[Departamento]”,userDepartmentVariable);

_vista.Carta = carta;

El Resultado es el siguiente:

image

Eso es todo.   Una solución sencilla para un requerimiento común.

Code4Fun!,

Juan Manuel Herrera Ocheita

jueves, 8 de octubre de 2015

Ojo con las dependencias al desinstalar una solución de granja en SharePoint

Las soluciones de granja de SharePoint siguen siendo requeridas por los clientes con instalaciones On Premises.  Como es una solución de granja afecta a toda la granja de SharePoint y esto incluye las Aplicaciones Web configuradas en la granja a pesar que cuando lo instalé indique que era sobre una aplicación Web en especifico.

El Escenario

AjaxControlToolKit.dll es una libreria que nos ayudará a mejorar los controles disponibles en asp.net y como empresa nosotros la utilizamos en las aplicaciones que entregamos a nuestros clientes sobre SharePoint Server.  Esta libreria no le va bien instalada en el Global Assembly Cache, es mejor instalarla en el directorio bin de la aplicación Web elegida.

Esto lo hacemos especificando en el Package del Proyecto de SharePoint Visual Web Part que incluya el ensamblado a nivel de la WebApplication, como se muestra en la imagen de abajo.

image

El Problema

En esta granja de SharePoint habian otras aplicaciones Web donde habiamos instalado otras soluciones utilizando la libreria AjaxControlToolKit.dll.   Lo que sucedio fue que al actualizar la solución en la granja la desinstalamos y la volvimos a instalar, a través de los comandos uninstall-SPSolution y Remove-SPSolution, eliminó de las otras aplicaciones Web la libreria AjaxControlToolKit.dll.  Y aunque volvimos a instalar la solución que estabamos probando con add-SPSolution y install-SPSolution, no volvio a instalar la libreria en las demás aplicaciones Web.

Los comandos ejecutados para re-instalar fueron los siguientes:

PS C:\> Uninstall-SPSolution –Identity infoware.doc.publicadosui.wsp 

PS C:\> Remove-SPSolution -Identity infoware.doc.publicadosui.wsp

PS C:\> Add-SPSolution –LiteralPath c:\instaladores\infoware.doc.publicadosui.wsp

PS C:\> Install-SPSolution -Identity infoware.doc.publicadosui.wsp -WebApplicat
on http://sitioprueba -GACDeployment

La Solución

Al repotarnos el error el usuario final, lo que hicimos fue copiar la libreria AjaxControlToolKit.dll en las aplicaciones Web que nos reportaron el error.  La solución fue sencilla, pero nos sorprendió la forma de comportarse al desintalar la solución de granja sobre el resto de aplicaciones Web.

Lexión Aprendida

A pesar que dirigimos la instalación a una aplicación Web por cuanto es una solución de Granja necesitamos realizar un respaldo del directorio bin y validar las librerias dependientes que coicidan con la solución que estamos instalando nosotros, y validar que continuen funcionando como lo solian hacer.

Code4Fun & Share2KeepBusy,  Smile

Juan Manuel Herrera Ocheita

viernes, 2 de octubre de 2015

Cannot unregister UpdatePanel since it was not registered with ScriptManager en un elemento Web de SharePoint

 

El error es el siguiente:

clip_image002

El error es algo confuso, ya que posiblemente ya hayamos definido el update panel en otro elemento web y no nos da el error.

El problema es en la definición declarativa de los elementos en SharePoint.   En mi particular caso el elemento Web estaba siendo implementado dentro de la solución WSP adicionandolo a una pagina que despliega el elemento web, como se muestra a continuación el código de la página.

clip_image002[5]

Si puedes observar el WebPartZone se llama wpSeguros2 pero en la definición de Elements.xml del Modulo que se utiliza para crear una pagina que incluya el elemento web cuando se instala la solución.  (Si quieres saber mas de como agregar una pagina de elementos web que se incluya dentro de tu solución pueder ver el siguiente enlace https://amalhashim.wordpress.com/2013/02/14/sharepoint-deploy-webpart-page-using-module/)

image

El problema se debio a que no coincide el WebPartZone ya que se llama wpSeguros y allí esta todo el problema, ya que SharePoitn si incluye el elemento Web a la página pero en una nueva zona que no esta definida en la plantilla y esto le afecto el updatepanel.

 

clip_image002[7]

Esto es todo espero a verles ayudado.

SharePoint4Fun!,

Juan Manuel Herrera Ocheita

miércoles, 30 de septiembre de 2015

Desarrollando soluciones WSP separando las responsabilidades en SharePoint

Separar las responsabilidades implica escribir el código de tal forma que el código solo tenga una responsabilidad y delege a otro segmento de codigo la responsabilidad que no le compete al codigo escrito.  Este principio en el desarrollo de software se aplicado a Desarrollo en N-Capas, Diseño basado en Dominio.  Pero en SharePoint es un reto desarrollar de esta forma ya que deforma predeterminada todo se instala en el GAC y los cambios del codigo se ven reflajados hasta que el GAC se actualice.  Y en ambientes de producción en la implementación es un stress inecesario y riesgo.

Que podemos hacer?  Podemos definir a nivel quel Paquete de SharePoint que los ensamblados se instalen en la Web Application en vez del Global Assembly Cache.  Para ello también es necesario firmar cada ensambaldo.

Primero separamos en Proyectos de librerias de clases exceptuando el Project de Visual WebPart de SharePoint.

image

En el proyecto común tenemos la definición de las entidades de negocio y las interfases de los repositorios y servicios.

image

El proyecto de Repositorio tenemos las implementaciones de el código de acceso a base de datos de las operaciones básicas hacia la base de datos o CRUD (Create Read Update & Delete).  Ninguna lógica de negocio, como validaciones u operaciones entre diferentes Repositorios.

image

El proyecto de Servicios es donde se encuentra la lógica del negocio e invoca a los repositorios necesarios para cumplir con la regla de negocio.

image

Este proyecto es otro Repositorio Especializado para invocar las librerias de SharePoint y acceder los objetos de SharePoint, separado de la base de datos ya que no comparten las mismas librerias.

image

Para finalizar el proyecto de SharePoint que representa la Capa de Presentación o Visualización.  Aquí podemos aplicar el patrón MVP o Model View Presenter.

image

Detalles a Conocer.

1) Para cada Ensamblado firmamos el emsamblado esto lo relizamos en las propiedades del proyecto en la opción Signing.

image

2) Referenciar los proyectos según su dependencia que debe de ser jerarquica y no cruzada, evitar la referencia ciclica.

image

En el paquete agregamos los ensamblados que deben de incluirse en la solución WSP.

image

Y debemos indicar que es a nivel de Web Application y no a nivel de GAC.

image

Y eso es todo.  Una ultima nota si en caso le reporta que no encuentra algunas referencias solo seleccione la opción Clean Solution en Build. 

SharePoint4Fun!,

Juan Manuel Herrera Ocheita

martes, 29 de septiembre de 2015

Cinta o ribbon se oculta al adicionar elemento Web personalizado en SharePoint

A veces se desea integrar personalizaciones con funcionalidades de SharePoint.  Este es el caso de adicionar en la página de una biblioteca en SharePoint un elemento Web Personalizado.

El problema radica que cuando adicionamos este elemento Web Personalizado la barra superior o Ribbon de administración de la biblioteca desaparece.

 

Para hacerla aparecer es necesario agregar el siguiente código JavaScript dentro de la declaración html del elemento Web Visual:

<script type=”text/javascript”>

setTimeout(function() { var elem = document.getElementById("MSOZoneCell_WebPartWPQ2"); if(elem != null) { var dummyevent = new Array(); dummyevent["target"] = elem; dummyevent["srcElement"] = elem; WpClick(dummyevent); _ribbonStartInit("Ribbon.Browse", true) } }, 2000);

</script>

image

El resultado será ver la barra de configuración esperada.

image

 

Referencia de la solución aplicada:

http://stackoverflow.com/questions/4848892/list-tools-tab-is-no-longer-available-after-adding-webpart-to-the-page

SharePoint4Fun!,

Juan Manuel Herrera Ocheita

miércoles, 16 de septiembre de 2015

Clases Fuertemente Tipados en una ListView para un WebPart en SharePoint

El control ListView nos permite desplegar colecciones de Clases definidas en codigo (Ej.:List<MiEntidad> ).  

Normalmente utlizamos el metodo Eval(“Atributo de la Clase”) para desplegar la información que enlazamos en el control con el evento miListView.DataBind().

Una mejor forma es utilizando el Atributo ItemType del control ListView.  De la siguiente forma:

<asp:ListView ID="uiListado" runat="server" ItemPlaceholderID="DetalleListado"
          OnPagePropertiesChanged="uiListado_PagePropertiesChanged"
          ItemType="Infoware.Comun.Dominio.Entidad.MiClase">

En el detalle lo definimos de la siguiente forma:

<ItemTemplate>
      <tr class="">
          <td id="Td2" runat="server"><%#: Item.Perfil %></td>
          <td id="Td3" runat="server"><%#: Item.Plazas %></td>
          <td id="Td4" runat="server"><%#: Item.Seccion %></td>
          <td id="Td10" runat="server"><%#: Item.Departamento %></td>
          <td id="Td7" runat="server"><%#: Item.PlazasTotal %></td>
          <td id="Td9" runat="server"> Del: <%#: Item.InscripcionesFechaInicial.HasValue? Item.InscripcionesFechaInicial.Value.ToString("dd/MM/yyyy"):"" %> 
              Al: <%#: Item.InscripscionesFechaFin.HasValue?Item.InscripscionesFechaFin.Value.ToString("dd/MM/yyyy"):"" %></td>
          <td id="Td8" runat="server"><%#: Item.InscripscionesFechaFin.HasValue? Item.InscripscionesFechaFin.Value.ToString("dd/MM/yyyy"):"" %></td>
           <td id="Td1" runat="server"><%#: Item.ExamenLugar %></td>
          <td id="Td5" runat="server"><%#: Item.TipoConvocatoria %></td>
        
          <td class="clasebotones">
              <asp:LinkButton ID="uiVer" runat="server"  ToolTip="Ver"
                  OnClick="evento_ver" CommandArgument='<%#: Item.Id %>' ValidationGroup='<%#: Item.CircularNo %>'
                  OnClientClick="javascript:setFormSubmitToFalse()">Circular PDF</asp:LinkButton>
           
              <asp:LinkButton ID="LinkButton3" runat="server"  ToolTip="Ver"
                  OnClick="evento_Recrear" CommandArgument='<%#: Item.Id %>' ValidationGroup='<%#: Item.CircularNo %>'
                  OnClientClick="javascript:setFormSubmitToFalse()">Recrear Circular PDF</asp:LinkButton>
          </td>
      </tr>
  </ItemTemplate>

Como podemos observar utilizamos la clase Item.NombreAtributoClaseDefiniaEnItemType.

image

Uselo es práctico y evita errores de escritura.

SharePoint4Fun!,

Juan Manuel Herrera Ocheita

lunes, 27 de julio de 2015

Interminable error Could not load file or assembly en una solución de granja de SharePoint 2013

Este error nunca terminaba y se alternaba de dlls referenciados indicando diferentes versiones que no eran las referenciadas, por más que lo reinstale, borre el cache de asp.net, reinicie el IIS no terminaba, hasta que encontré el único consejo que en mi caso si me sirvió, el cual es el siguiente:

Copia el DLL del problema o bien todos los que hace referencia tu solución, en mi caso eran dos al directorio bin de la carpeta debug del proyecto de SharePoint y con ello el problema si desaparece.

En mi caso los DLL´s que tenia referenciados eran:

Aspose.words.dll y AjaxControlToolKit.dll.

Y esto es porque el directorio bin tiene precedencia del GAC en la aplicación Web siempre y cuando no se especifique la versión. 

Una de las ventajas de copiar el DLL en el directorio bin de la aplicación Web que se va utilizar es que no tiene que reiniciar el servidor y el riesgo se reduce porque solo afecta la aplicación Web que le interesa.  Esto también puede ser una desventaja si existen varias Aplicaciones Web que utilizan el mismo DLL.

Más información en: http://www.hanselman.com/blog/BINDeployingASPNETMVC3WithRazorToAWindowsServerWithoutMVCInstalled.aspx

Así que amigos mi recomendación es copien los DLL en el directorio Bin de la Aplicación Web que necesitan y afecten el servidor lo menos posible, tomen en cuenta que si el dll es utilizado en otras aplicaciones Web deberán actualizarlas también allí, pero esto es mejor a mi parecer que utilizar el GAC ya que este debe de actualizarse el cache reiniciando el IIS y algunas veces hasta el servidor mismo.

Code4Fun!,

Juan Manuel Herrera Ocheita