Si tu solución de SharePoint posee varios webparts, quizá quieras considerar lo que os cuento en breve, de cara a tener una organización de los items del proyecto algo más limpia, y evitar entradas SafeControl innecesarias en el web.config.

Imaginemos que nuestra solución tiene 3 webparts visuales, añadidos a través de la plantilla de Visual Studio. Quedaría algo así:

image

Para empezar, fijaros en los NameSpaces que tenemos, para cada webpart:

   1: namespace Spartans.Sharepoint.OrganizedWebparts.VisualWebPart3

   2: //...

   3: namespace Spartans.Sharepoint.OrganizedWebparts.VisualWebPart2

   4: //...

   5: namespace Spartans.Sharepoint.OrganizedWebparts.VisualWebPart1

Un poco “feo” bajo mi punto de vista. Además, si nos vamos a las propiedades de cada webpart, y nos fijamos en la colección de Safe Control Entries:

image

image

Vemos que tenemos una entrada SafeControl, y lo mismo para el resto de webparts. Esto hará, que al desplegarlo, tengamos 3 entradas en nuestro Web.Config:

   1: <SafeControl Assembly="Spartans.Sharepoint.OrganizedWebparts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=76693daf4f35b7d3" Namespace="Spartans.Sharepoint.OrganizedWebparts.VisualWebPart1" TypeName="*" Safe="True" SafeAgainstScript="False" />

   2: <SafeControl Assembly="Spartans.Sharepoint.OrganizedWebparts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=76693daf4f35b7d3" Namespace="Spartans.Sharepoint.OrganizedWebparts.VisualWebPart2" TypeName="*" Safe="True" SafeAgainstScript="False" />

   3: <SafeControl Assembly="Spartans.Sharepoint.OrganizedWebparts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=76693daf4f35b7d3" Namespace="Spartans.Sharepoint.OrganizedWebparts.VisualWebPart3" TypeName="*" Safe="True" SafeAgainstScript="False" />

¿No sería más limpio organizar los Namespaces de forma algo más lógica, y sólo tener una entrada a nivel de web.config, que incluya todos los webparts de nuestra solución?

Vamos a ello !!

Primero de todo, ya que los webparts visuales se basan en controles de usuario, y es posible que nuestra solución tenga otros controles de usuario, vamos a añadir la carpeta mapeada de SharePoint “ControlTemplates”, y creamos una carpeta para todos nuestros controles:

image image

Ahora vamos a mover los controles de usuario que usan los webparts visuales, a esa carpeta. Y ya que estamos, vamos a cambiar el Namespace de los 3 controles, para que todos pertenezcan al mismo Namespace.

   1: namespace Spartans.Sharepoint.OrganizedWebparts.Web.UI

Recordar que al cambiar el Namespace, también lo tenemos que hacer en el fichero .ascx, en el atributo “Inherits” de la directiva “Control”:

   1: <%@ Control 

   2:     Language="C#" 

   3:     AutoEventWireup="true" 

   4:     CodeBehind="VisualWebPart3UserControl.ascx.cs" 

   5:     Inherits="Spartans.Sharepoint.OrganizedWebparts.Web.UI.VisualWebPart3UserControl" %>

Ahora tenemos que cambiar algunas cosas de los webparts.

Primero de todo, ya que no queremos varias entradas SafeControl en el web.config, las eliminamos de las propiedades.

image

Lo siguiente es re-apuntar a la nueva ubicación de los controles:

   1: [ToolboxItemAttribute(false)]

   2: public class VisualWebPart3 : WebPart

   3: {

   4:     // Visual Studio might automatically update this path when you change the Visual Web Part project item.

   5:     private const string _ascxPath = @"~/_CONTROLTEMPLATES/OrganizedControls/VisualWebPart3UserControl.ascx";

   6:  

   7:     protected override void CreateChildControls()

   8:     {

   9:         Control control = Page.LoadControl(_ascxPath);

  10:         Controls.Add(control);

  11:     }

  12: }

Y ya que nos ponemos, vamos a cambiar el Namespace de los webparts, y agruparlos en el mismo:

   1: namespace Spartans.Sharepoint.OrganizedWebparts.Web.UI.Webparts

Al cambiar el Namespace, tenemos que actualizar también el fichero .webpart

   1: <?xml version="1.0" encoding="utf-8"?>

   2: <webParts>

   3:   <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">

   4:     <metaData>

   5:       <type name="Spartans.Sharepoint.OrganizedWebparts.Web.UI.Webparts.VisualWebPart1, $SharePoint.Project.AssemblyFullName$" />

   6:       <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>

   7:     </metaData>

   8:     <data>

   9:       <properties>

  10:         <property name="Title" type="string">Oraganized webparts VisualWebPart1</property>

  11:         <property name="Description" type="string">This is webpart 1, from Organized webparts sample</property>

  12:       </properties>

  13:     </data>

  14:   </webPart>

  15: </webParts>

Para acabar, nos falta configurar la solución para que genere una única entrada de SafeControl en el web.config. Para ello, vamos a utilizar el editor del Manifest del paquete de nuestra solución. Este editor, permite combinar el XML que ha autogenerado Visual Studio, con nuestros propios valores insertados en el cuadro de texto.

image

Añadimos nuestra entrada de SafeControl:

   1: <?xml version="1.0" encoding="utf-8"?>

   2: <Solution xmlns="http://schemas.microsoft.com/sharepoint/">

   3:   <Assemblies>

   4:     <Assembly Location="Spartans.Sharepoint.OrganizedWebparts.dll" DeploymentTarget="GlobalAssemblyCache">

   5:       <SafeControls>

   6:         <SafeControl Assembly="Spartans.Sharepoint.OrganizedWebparts" Namespace="Spartans.Sharepoint.OrganizedWebparts.Web.UI.Webparts" TypeName="*" />

   7:       </SafeControls>

   8:     </Assembly>

   9:   </Assemblies>

  10: </Solution>

Si hacemos el Deploy de la solución, ya vemos que tenemos una única entrada SafeControl en el web.config:

   1: <SafeControl Assembly="Spartans.Sharepoint.OrganizedWebparts, Version=1.0.0.0, Culture=neutral,     PublicKeyToken=76693daf4f35b7d3" 

   2:     Namespace="Spartans.Sharepoint.OrganizedWebparts.Web.UI.Webparts" 

   3:     TypeName="*" 

   4:     Safe="True" 

   5:     SafeAgainstScript="False" />

Al indicar el TypeName como “*”, estamos incluyendo todos los controles de ese Namespace (todos nuestros webparts de la solución).

Si además, vemos nuestra DLL con algún “Decompiler” (Reflector, ILSpy, JustDecompile…), vamos que nuestro namespaces, webparts y controls, están ordenaditos:

image

Si tenemos una solución con mucho desarrollo personalizado, seguro que agradecemos este orden.

Espero que os sirva.

Saludos!!

30