viernes, 18 de noviembre de 2011

Error Soap al Editar Paginas con Sharepoint Designer 2010

Escenario del Error:
Abrimos Sharepoint designer 2010, y al intentar Editar una pagina nos aparece el error

En Español : "soap:Server El servidor no puede procesar la solicitud. ---> El valor no está dentro del intervalo esperado."
En Inglés: "soap:Server Server was unable to process request. ---> Value does not fall within the expected range."

Causa:
Nos estamos conectando usando la IP de la maquina, la palabra Localhost y cualquier DNS no registrado como ruta de acceso alternativa dentro de sharepoint.

Solución:
Conectarse usando el nombre de la maquina.




viernes, 11 de noviembre de 2011

Modificar el limite de registros (Throttle) en BCS

Problema:
Un BCS recupera demasiados datos y nos arroja un error de correlación, tras rastrearlo, vemos que hay problemas de timeout y nos recomienda el uso de Get-SPBusinessDataCatalogThrottleConfig

Hay que modificar el parametro Scope según donde se conecte el BCS, pueden ser Wcf, WebService, Database,Global o Custom.

Solución para WCF, los ponemos al maximo:

#Define el Proxy BCS
$bdcAppProxy = Get-SPServiceApplicationProxy | where {$_ -match "Business Data *"}

#Modifica el numero maximo de bytes
$throttleWCF = Get-SPBusinessDataCatalogThrottleConfig -Scope WCF -ThrottleType Size -ServiceApplicationProxy $bdcAppProxy
Set-SPBusinessDataCatalogThrottleConfig -Identity $throttleWCF -maximum 2147483647 -default 2147483647
$throttleWCF

#Modifica el tiempo maximo de la petición
$throttleWCF = Get-SPBusinessDataCatalogThrottleConfig -Scope WCF -ThrottleType Timeout -ServiceApplicationProxy $bdcAppProxy
Set-SPBusinessDataCatalogThrottleConfig -Identity $throttleWCF -maximum 2147483647 -default 2147483647
$throttleWCF

Encontrar el Error mensaje de error con el Correlation Id sin meterse en el barro de los logs de Sharepoint 2010

Cuando Sharepoint 2010 nos da un mensaje error y nos proporciona un Correlation ID para localizar el mensaje podemos sacarlo de forma sencilla con powershell.

image

Este es el comando que hay que lanzar en el Shell de Administracion de sharepoint.
get-splogevent | ?{$_.Correlation -eq "<GUID>"} | select Area, Category, Level, EventID, Message | Format-List

image

jueves, 9 de junio de 2011

El webpart ListingSummary no migra correctamente a Sharepoint 2010 (SOLUCION)

Problema:
Al realizar una migración a sharepoint 2010, si en algun sitio se ha usado el webpart de ListingSummary, este aparece como ErrorWebPart.

Causas:
Parece que a los chicos de microsoft se les ha pasado efectuar una operacion de transformación
para migrar correctamente este webpart


WorkAround:
Podemos ver la documentación de microsoft acerca del ListingSummary en esta página
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.portal.webcontrols.listingsummary_members(v=office.12).aspx

Este webpart nos permite usar ficheros externos XSLT para mostrar los datos con formato. Es posible que haya que reconfigurarlo pero es muy sencillo.


Si investigamos un poco, nos damos cuenta que no es posible que hayan BORRADO sin más este webpart, ya que en 2010 no aparece.... al menos donde estaba.
Lo que ha ocurrido es que lo han movido de namespace , le han cambiado el nombre y le han hecho unas mejoras (tiene mas parametros)
Podemos ver la documentación del ContentByQueryWebPart en esta página
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.webcontrols.contentbyquerywebpart_members.aspx



Solucion 1:
-Elimiar el ErrorWebpart

- Añadir el ContentByQueryWebPart y configurarlo a mano (hay que copiar la configuración antes de migrar)

Nota: Al configurarlo algunas propiedades nuevas son obligatorias.


Solucion2:

-Exportar el webpart como fichero ".webpart" (se hace desde la edicion de la pagina)

-Migrar a 2010

-Modificar a mano el fichero ".webpart"

Sustituir:

type name="Microsoft.SharePoint.Portal.WebControls.ListingSummary, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

Por esto:

type name="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

-Verificar que las nuevas propiedades obligatorias tienen valor.

-Importar a 2010 el fichero ".Webpart"

Cuidado:
Al realizar una migración InPlace, aparece el ErrorWebpart y pierdes la configuración que tenia, apuntadla para tenerla a mano.


Saludos Espero que os sirva de ayuda.

Roberto Marcos.

Eliminar Features Corruptas A LA FUERZA en Sharepoint 2007 con PowerShell

Escenario:

Uno de los pasos recomendados en las migraciones de Sharepoint 2007 a 2010, es limpiar el entorno de origen.

 

Problema:

Por desgracia muchas features que fueron usadas, activadas, retraídas, borradas, etc... al final se quedan como activas o de alguna manera hay referencias en la base de datos de contenidos, estas referencias nos salen como errores al realizar el "preupgradecheck".

 

Solución MicroSoft:

Utilizar estos programas para limpiar http://archive.msdn.microsoft.com/WssAnalyzeFeatures y http://archive.msdn.microsoft.com/WssRemoveFeatureFrom

Os anticipo que hay muchos casos en los que no es capaz de borrarlas


Solución Infalible:

Trasteando con la documentación vemos que accediendo mediante object modal se pueden borrar, pero tenemos adicionalmente la opción de FORCE, la cual solo es accesible por código, curiosamente es la única forma limpia de quitar todas estas features corruptas (sin tocar la base de datos de contenidos).

 

Con este PowerShell que he preparado, dejaremos nuestro entorno limpio de features mal instaladas o con problemas.

Le he puesto una salida a gridView para ver que va borrando.


Tras lanzar este script, desaparecerán los errores relacionados con features corruptas al realizar el preupgradecheck.


Nota: Si hay muchos sitios y muchas webs, el servidor a veces "SE ESTRESA" y da timeouts, yo recomiendo lanzarlo un par de veces.



=====================================

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal")

#Author : Roberto Marcos Asensio (info@robertomarcos.com)


function remove-spmissingfeatures([Boolean]$force) 


    $farm = [Microsoft.SharePoint.Administration.SPFarm]::Local

    foreach ($spService in $farm.Services) {

        if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {

            continue;

        }


        foreach ($webApp in $spService.WebApplications) {

        

            if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue }


                   #foreach ($site in $webApp.Sites  |Where-Object {$_.Url -match "intranet.miempresa.com"} ) {

                    foreach ($site in $webApp.Sites) {


                      foreach ($feature in $site.features) { 

                        if ($feature.definition -eq $null) { 

                         $data = @{

                        "MissingFeature" =  $feature.DefinitionId

                        "Parent"=$feature.parent 

                        "Web" = $site.Url;

                         }

                         New-Object PSObject -Property $data

                       

                          $site.features.remove($feature.DefinitionId,$force

                       

                        } 

                      }

                      

                      

                       foreach ($web in $site.AllWebs ){

                          

                          foreach ($feature in $web.features) { 

                            if ($feature.definition -eq $null) { 

                          

                                 $data = @{

                                "MissingFeature" =  $feature.DefinitionId

                                "Parent"=$feature.parent 

                                "Web" = $web.Url;

                                 }

                                 New-Object PSObject -Property $data

                                  $web.features.remove($feature.DefinitionId,$force) 

                            } 

                          }


                        }

                    }

            }

        }

        

 }    

remove-spmissingfeatures($true) | Out-GridView


=====================================
Saludos, espero que os sea de utilidad.
Roberto Marcos

martes, 31 de mayo de 2011

Migraciones SiteBySite a Sharepoint 2010

stsadm -o mergecontentdbs

Es un comando clásico de stsadm que típicamente se usa para juntar bases de datos,
pero..... tiene una opción extra con una funcionalidad muy útil en la "-operation 3" !!!


Podemos especificarle un fichero XML de sitios a mover y moverlos a una base de datos de contenidos VACIA por lo que podríamos hacer migraciones a Sharepoint 2010 SITE BY SITE o por Bloques.


Adjuntando esta nueva base de datos actualizamos únicamente lo que deseemos a sharepoint 2010 y así podemos migrar gradualmente los sitios poco a poco o lanzarlos en paralelo en nodos diferentes para acelerar y acortar la ventana de tiempo de parada de servicio.


Es una manera muy interesante de no arrastrar basura a sharepoint 2010.

http://technet.microsoft.com/en-us/library/cc262923(v=Office.12).aspx

Syntax

stsadm -o mergecontentdbs

-url <URL name>

-sourcedatabasename <source database name>

-destinationdatabasename <destination database name>

[-operation] {1-3}

1 - Analyze (default)

2 - Full database merge

3 - Read from file

[-filename] <file generated from stsadm -o enumsites>

Parameters

Parameter name

Value

Required?

Description

url

A valid URL, such as "http://server_name"

Yes

URL of the Web application whose databases that you want to merge.

sourcedatabasename

A valid database name, such as "WSS_Content_1

Yes

The database name from which site collections will be moved.

destinationdatabasename

A valid database name, such as "WSS_Content_2"

Yes

The name of the database to which the site collections will be moved.

operation

Any one of the following values:

  • 1 - Analyze

  • 2 - Full database merge

  • 3 - Read from file

No

1 - Analyze: Indicates that the command window displays the current number of site collections, the database size, the maximum number of site collections, and the number of site collections that can be added before reaching the maximum number of site collections for each content database.

Also, a recommendation regarding which content database should be used for the source and which content database should be used for the destination—assuming that all site collections in the database will be moved—is displayed in the command window. This recommendation is based on which content database contains less data and therefore would be faster to move.

This is the default.

2 - Full database merge: Merges the entire content database from one database to another. Once the operation is complete, the source content database still exists in Microsoft SQL Server and is still attached to the Web application. It simply has no site collections in it.

3 - Read from file: Moves only a subset of site collections from the source database to the destination database. The site collections that are to be moved should be listed in a file that is specified with the filename parameter.

filename

A valid file name, such as "sites.xml"

No

Specifies a specific site collection in the source content database you want moved to the destination database

This information is obtained using the databasename parameter of the Enumsites operation.

Note Note:

The databasename parameter was first introduced in Office SharePoint Server 2007 with Service Pack 1..

Note Note:

You can use the redirection operator ">" to capture the XML output of the enumsites operation into a text file.




martes, 29 de marzo de 2011

Load Testing Kit (LTK) – Kit para realizar Test de Stress en Sharepoint

Load Testing Kit (LTK) – Kit para realizar Test de Stress en Sharepoint

http://technet.microsoft.com/en-us/library/ff823736.aspx

Este kit contiene una colección de websites prefabricados para realizar  web test para la mayoría de los escenarios de sharepoint 2010, como Team Collaboration, Web content Management y Redes Sociales.

Podemos adaptarlo a nuestras propias necesidades, y nos permite la creación de test mucho mas rápido y fácilmente.

 

Contiene un componente para generación de grandes cantidades de datos (Data Generation Utility), en la sección de buenas practicas se recomienda su uso para hacer una simulación de un entorno real permitiéndonos saber como se va a comportar nuestro código en un entorno de producción bajo la carga de muchos usuarios generando cantidades ingentes de datos.

¿Quién se atreve a generar 100.000 documentos de forma manual?

 

La recomendación es tener el entorno conectado al Active Directory así podemos crear pequeños paquetes de datos en la granja con un perfil particular de carga, crear usuarios y crear tablas de ejecución para usarlas en visual Studio.

 

Es excelente para realizar un test de estrés exhaustivo para nuevas configuraciones de hardware.

 

Como guinda final tenemos una utilidad de Análisis de Logs para analizar el uso según  comportamiento real del IIS para identificar la utilización habitual que le dan los usuarios, para realizar una simulación que imite el entorno real de producción.

 

Es una parte del SharePoint 2010 Administration Toolkit (SharePoint Server 2010) http://technet.microsoft.com/en-us/library/cc508851.aspx

 

En la que podemos encontrar una parte bastante interesante de User Profile Replication Engine (SharePoint Server 2010) que a muchos nos esta dando algún que otro dolor de cabeza.

http://technet.microsoft.com/en-us/library/cc663011.aspx

 

 
Espero que os sea de utilidad
Roberto Marcos.

viernes, 25 de febrero de 2011

Script PowerShell de Inventario de Granja, Pre-Migración Sharepoint 2010

Actualmente me encuentro realizando una migración de sharepoint 2007 a sharepoint 2010.
Los whitepapers y la documentación de Microsoft y terceros resultan muy utiles e ilustrativos, pero como siempre se queda un poco cortos cuando se trata de migrar contenido muy customizado con soluciones de terceros y un sin fin de cosas que siempre se quedan en el tintero o son difíciles de localizar.

En uno de los puntos del proceso oficial se hace alusión a Inventariar sitios y soluciones custom como si fuese un punto de nada.... en fin.
He preparado un script de powershell que nos resultara de utilidad para poder obtener una radiografía completa de la granja que nos facilite localizar los desarrollos customizados y en general todo lo que esta en uso o instalado

El script obtiene los datos por object model, y no usa los comandos modernos de Sharepoint2010 ya que en 2007 no están disponibles, por lo que funciona en todos los escenarios. :)

Lo que obtenemos es :
  • Granja
  • Sitios
  • Webs
  • Eventos de Web
  • Listas y Campos
  • Eventos de Lista
  • ContentTypes
  • Eventos de ContentType
  • CustomFields
  • Features
  • Modules
  • Soluciones WSP
  • Paginas por sitio con sus webparts y las AUDIENCIAS de cada uno de ellos.
  • Bases de datos de contenido
El resultado es un XML , suele ser bastante grande. Unos 50-70Mb pero depende de vuestra granja.
Para usarlo, hay que guardarlo como InventarioSP2007.PS1 e ir a un nodo del frontal y lanzarlo.
Aquí lo dejo :

===================================================================
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#ROBERTO MARCOS 25-feb-2011 V1.1 sharepointworks.blogspot.com

$xmlFilePath = "C:\Inventario.xml"

$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$cul = New-Object System.Globalization.CultureInfo("ES-es")
$pscope= [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared

New-item $xmlFilePath -type file -force -value "<?xml version='1.0' encoding='utf-8'?>"

Add-Content $xmlFilePath "<MIGRACION>"
Add-Content $xmlFilePath ("<FARM name='{0}' ID='{1}' >" -f $farm.Name,$farm.ID);
foreach ($spService in $farm.Services) {
if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {
continue;
}
Add-Content $xmlFilePath ("<Solutions>")
foreach ($sol in $farm.Solutions)
{
Add-Content $xmlFilePath ("<Solution ID='{0}' Name='{1}' Parent='{2}'/>" -f $sol.solutionid ,$sol.displayname,$sol.Parent.Name )
}
Add-Content $xmlFilePath ("</Solutions>")
foreach ($webApp in $spService.WebApplications) {
#if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue }
Add-Content $xmlFilePath ("<WebApplication name='{0}' CurrentSiteCount='{1}' >" -f $webApp.Name,$webApp.ID);#webApplication.CurrentSiteCount
Add-Content $xmlFilePath ("<ContentDatabases>")
foreach ($contentDB in $webApp.ContentDatabases)
{

$DBName = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("Name")
$DBID = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("ID")
$CurrentDBName = $DBName.GetValue($ContentDB, $null)
$CurrentDBID = $DBID.GetValue($ContentDB, $null)
Add-Content $xmlFilePath ("<ContentDatabase Name='{0}' ID='{1}'/>" -f $CurrentDBName,$CurrentDBID )
}
Add-Content $xmlFilePath ("</ContentDatabases>")
Add-Content $xmlFilePath ("<Sites>")
foreach ($site in $webApp.Sites)
{
Add-Content $xmlFilePath ("<Site PortalName='{0}' Url='{1}'>" -f $site.PortalName ,$site.Url )
##FEATURES SITE
Add-Content $xmlFilePath ("<Features>")
foreach ($feature in $site.Features)
{
if($feature.Definition -eq $null){
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f "MISSING",$feature.DefinitionId )
}
else
{
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f $feature.Definition.GetTitle($cul) ,$feature.DefinitionId )

}
}
Add-Content $xmlFilePath ("</Features>")
Add-Content $xmlFilePath ("<Webs>")
foreach ($web in $site.AllWebs)
{
Add-Content $xmlFilePath ("<Web Name='{0}' URL='{1}'>" -f $web.Name ,$web.Url )
Add-Content $xmlFilePath ("<FeaturesWeb>")
foreach ($featurew in $web.Features)
{
Add-Content $xmlFilePath ("<Feature Title='{0}' DefinitionId='{1}'/>" -f $featurew.Definition.GetTitle($cul) ,$featurew.DefinitionId )
}
Add-Content $xmlFilePath ("</FeaturesWeb>")
Add-Content $xmlFilePath ("<ContentTypes>")
foreach ($ct in $web.ContentTypes)
{
Add-Content $xmlFilePath ("<ContentType Name='{0}' ID='{1}'/>" -f $ct.Name ,$ct.ID )
}
Add-Content $xmlFilePath ("</ContentTypes>")
Add-Content $xmlFilePath ("<WebEventReceivers>")
foreach ($evt in $web.EventReceivers)
{
Add-Content $xmlFilePath ("<WebEventReceiver Name='{0}' Type='{1}' Assembly='{2}' Class='{3}' />" -f $evt.Name ,$evt.Type,$evt.Assembly, $evt.Class )
}
Add-Content $xmlFilePath ("</WebEventReceivers>")
Add-Content $xmlFilePath ("<Modules>")
foreach ($md in $web.Modules)
{
Add-Content $xmlFilePath ("<Module Name='{0}' Enabled='{1}' Url='{2}' />" -f $md.Name ,$md.Enabled,$md.Url)
}
Add-Content $xmlFilePath ("</Modules>")
Add-Content $xmlFilePath ("<Lists>")
foreach ($lst in $web.Lists)
{
Add-Content $xmlFilePath ("<List Title='{0}' Description='{1}' ItemCount='{2}' >" -f $lst.Title ,$lst.Description,$lst.ItemCount)
Add-Content $xmlFilePath ("<ContentTypes>")
foreach ($ctt in $lst.ContentTypes)
{
Add-Content $xmlFilePath ("<ContentType Name='{0}' ID='{1}'/>" -f $ctt.Name ,$ctt.ID )
}
Add-Content $xmlFilePath ("</ContentTypes>")
Add-Content $xmlFilePath ("<ListEventReceivers>")
foreach ($evtl in $lst.EventReceivers)
{
Add-Content $xmlFilePath ("<ListEventReceiver Name='{0}' Type='{1}' Assembly='{2}' Class='{3}' />" -f $evtl.Name ,$evtl.Type,$evtl.Assembly, $evtl.Class )
}
Add-Content $xmlFilePath ("</ListEventReceivers>")
Add-Content $xmlFilePath ("<Fields>")
$campos=$lst.Fields Where-Object{$_.Hidden -eq 0 }
foreach ($campo in $campos)
{
Add-Content $xmlFilePath ("<Field InternalName='{0}' Title='{1}' Description='{2}' FieldTypeDefinitionName='{3}' FieldTypeDefinitionDisplayName='{4}' FieldTypeDescription='{5}' FieldEditorUserControl='{6}' BaseRenderingTypeName='{7}' FieldTypeClass='{8}'/>" -f $campo.InternalName , $campo.Title ,$campo.Description , $campo.FieldTypeDefinition.TypeName,$campo.FieldTypeDefinition.TypeDisplayName ,$campo.FieldTypeDefinition.TypeShortDescription,$campo.FieldTypeDefinition.FieldEditorUserControl,$campo.FieldTypeDefinition.BaseRenderingTypeName,$campo.FieldTypeDefinition.FieldTypeClass )
}
Add-Content $xmlFilePath ("</Fields>")
# Views
# WorkflowAssociations
Add-Content $xmlFilePath ("<WorkflowAssociations>")
foreach ($wf in $lst.WorkflowAssociations)
{
Add-Content $xmlFilePath ("<WorkflowAssociation Name='{0}' ID='{1}' Description='{2}' />" -f $wf.Name ,$wf.ID,$wf.Description )
}
Add-Content $xmlFilePath ("</WorkflowAssociations>")
Add-Content $xmlFilePath ("</List>")
}
Add-Content $xmlFilePath ("</Lists>")
Add-Content $xmlFilePath ("<Paginas>")
$pages = $web.Files Where-Object {$_.Name -match ".aspx"}
foreach ($pag in $pages)
{
Add-Content $xmlFilePath ("<PaginaASPX Name='{0}' URL='{1}' Length='{2}' Title='{3}'>" -f $pag.Name ,$pag.ServerRelativeUrl,$pag.Length , $pag.Title )
if($pag -ne $null){
$webPartManager = $pag.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
if ($webPartManager.WebParts.Count -gt 0){
Add-Content $xmlFilePath ("<WebParts>")
foreach ($wp in $webPartManager.WebParts)
{
Add-Content $xmlFilePath ("<WebPart Title='{0}' Hidden='{1}' IsClosed='{2}' AuthorizationFilter='{3}' ID='{4}' UniqueID='{5}' Description='{6}'/>" -f $wp.DisplayTitle ,$wp.Hidden,$wp.IsClosed, $wp.AuthorizationFilter,$wp.ID,$wp.UniqueID,$wp.Description )
}
Add-Content $xmlFilePath ("</WebParts>")
}
Add-Content $xmlFilePath ("</PaginaASPX>")
}
}
Add-Content $xmlFilePath ("</Paginas>")
Add-Content $xmlFilePath ("</Web>")
}
Add-Content $xmlFilePath ("</Webs>")
Add-Content $xmlFilePath ("</Site>")
}
Add-Content $xmlFilePath ("</Sites>")
#Add-Content $xmlFilePath($webApp.ContentDatabases New-XML -RootTag CONTENTDATABASES -ItemTag DATABASE -Attribute=Id,Name -ChildItems Server )
Add-Content $xmlFilePath "</WebApplication>"
}
}
Add-Content $xmlFilePath "</FARM>"
Add-Content $xmlFilePath "</MIGRACION>"


========================================

viernes, 28 de enero de 2011

Mostar Listado de adjuntos en dataview webpart y en dataform webpart

Con este snipet podemos mostrar el listado de adjuntos en un data view webpart :
 
         <xsl:element name="SharePoint:AttachmentsField">
          <xsl:attribute name="runat">server</xsl:attribute>
          <xsl:attribute name="FieldName">Attachments</xsl:attribute>
          <xsl:attribute name="ControlMode">Display</xsl:attribute>
          <xsl:attribute name="Visible">true</xsl:attribute>
          <xsl:attribute name="ItemId"><xsl:value-of select="@ID"/></xsl:attribute>
 
En un data form webpart se pueden mostrar así:
 
<SharePoint:AttachmentsField ControlMode="Display" FieldName="Attachments" runat="server" Visible="true"/>
 
Es lo mismo pero  con el truco de los atributos podemos meter condiciones y hacer filtrado por parámetros en el data view web part.
 
El problema real donde se puede aplicar esto aparece cuando se estan almacenando las paginas customizadas en una biblioteca de documentos... ya que si usamos el parámetro ID se producen errores porque sharepoint lo interpreta como que intentamos localizar la pagina (almacenada como item) usando el ID que le pasamos como parámetro, cuando realmente lo que queremos es filtrar usando el parámetro y no que localice una pagina customizada almacenada el la biblioteca.