Compartir a través de


Procedimiento para crear un adaptador móvil

Última modificación: jueves, 17 de marzo de 2011

Hace referencia a: SharePoint Foundation 2010

En este tema se explica cómo crear una clase de adaptador móvil que permita que los dispositivos móviles tengan acceso a un elemento web en una página de Microsoft SharePoint Foundation.

Para obtener un ejemplo concreto de adaptación de un elemento Web, vea Tutorial: Crear un adaptador móvil..

Configuración del entorno de desarrollo

Requisitos previos de tareas de desarrollo

  1. Si la página de elementos web a la que se va a poder obtener acceso desde dispositivos móviles no existe, debe crearla. Para obtener más información, vea Infraestructura de elementos web en SharePoint Foundation y WebPartPage.

    Nota

    No cree páginas de la clase WebPartMobilePage, ya que las crea el tiempo de ejecución cuando un dispositivo móvil solicita una página de elementos web (WebPartPage).

  2. Si la página de elementos web que desea adaptar para obtener acceso desde dispositivos móviles no existe, debe crearla. Para obtener más información, vea Infraestructura de elementos web en SharePoint Foundation y Introducción a los elementos web.

Creación e implementación de una clase de adaptador móvil

  1. En un proyecto de biblioteca de clases de Visual Studio, agregue una referencia a System.Web y Microsoft.SharePoint.dll y, a continuación, agregue una instrucción using (Imports en Visual Basic) para el espacio de nombres Microsoft.SharePoint.WebPartPages. Es posible que deba agregar instrucciones using para otros espacios de nombres, según los detalles de la implementación del adaptador. Comúnmente, los adaptadores móviles hacen llamadas a tipos en System.Web.UI.MobileControls, Microsoft.SharePoint y Microsoft.SharePoint.MobileControls.

  2. Agregue una clase llamada WebPartClassMobileAdapter, donde WebPartClass es el nombre del elemento web que va a adaptar. Por ejemplo, si el elemento web es StockListWebPart, nombre la clase de adaptador como StockListWebPartMobileAdapter. Establezca la clase para que herede de WebPartMobileAdapter.

  3. Defina el espacio de nombres para que cumpla las instrucciones de instrucciones de nomenclatura de espacios de nombres. Para un adaptador móvil use un nombre similar a MyCompany.SharePoint.WebPartPages.MobileAdapters.

  4. Aunque la propiedad WebPartMobileAdapter.Control no esté marcada como virtual o override (Overridable y Overrides en Visual Basic), es posible que necesite ocultarla y reemplazarla para invalidarla. Para ello, debe declarar una nueva propiedad Control en la clase derivada mediante la palabra clave new (Shadows en Visual Basic). Para obtener más información sobre por qué es útil realizar esta acción y sobre cómo realizarla, vea el tema de referencia para WebPartMobileAdapter.Control.

  5. Si la implementación predeterminada no es adecuada para obtener acceso al elemento web desde dispositivos móviles, invalide el método CreateControlsForSummaryView(). Básicamente, una invalidación debería crear todos los controles secundarios que se necesiten y agregarlos a la colección Controls en el orden que deberían aparecer en un dispositivo móvil. Normalmente, querrá que aparezcan al menos un icono pequeño y un título para el elemento web en la vista de resumen en un dispositivo móvil. (Si eso es todo lo que desea que aparezca en la vista de resumen, no es necesario que invalide CreateControlsForSummaryView().) Para que esto sea más fácil, se proporcionan dos métodos auxiliares: CreateWebPartIcon(WebPartMobileAdapter.WebPartIconLink) y CreateWebPartLabel().

    Pero a veces se necesita más información, incluso en la vista de resumen. Por ejemplo, imagine que el elemento web que se va a adaptar tiene varios elementos secundarios, todos del mismo tipo. Puede agregar el número total de elementos secundarios en la vista de resumen con un control Label que viene después del icono y el título. El siguiente código muestra cómo hacerlo.

    Nota importanteImportante

    En este ejemplo se suponen dos cosas. Primero, que el elemento web que se va a adaptar tiene una propiedad Count, del tipo String, que devuelve el número total de elementos secundarios; y segundo, que se tiene acceso a esta propiedad, porque la propiedad Control ha estado oculta y se la reemplazó como se explicó en el paso anterior.

    protected override void CreateControlsForSummaryView()
    {
        Image iconImage = this.CreateWebPartIcon(WebPartIconLink.LinkToDetailView);
        iconImage.BreakAfter = false;
        this.Controls.Add(iconImage);
    
        Label titleLabel = this.CreateWebPartLabel();
        titleLabel.BreakAfter = false;
        this.Controls.Add(titleLabel);
    
        Label count = new Label() { Text=this.Control.Count.ToString() }
        this.Controls.Add(count);
    }
    
    Protected Overrides Sub CreateControlsForSummaryView()
            Dim iconImage As Image = Me.CreateWebPartIcon(WebPartIconLink.LinkToDetailView)
            iconImage.BreakAfter = False
            Me.Controls.Add(iconImage)
    
            Dim titleLabel As Label = Me.CreateWebPartLabel()
            titleLabel.BreakAfter = False
            Me.Controls.Add(titleLabel)
    
            Dim count As New Label() With {.Text=Me.Control.Count.ToString()} 
            Me.Controls.Add(count)
    End Sub
    

    Tenga en cuenta que cuando el método CreateWebPartIcon(WebPartMobileAdapter.WebPartIconLink) se pasa a LinkToDetailView, como en este ejemplo, siempre que el explorador del dispositivo admita CSS y ECMAScript 1.0 o superiores, se presenta un icono de cabeza de flecha que actúa como un control sobre el que se puede hacer clic y que ejecuta el script de expansión del marco del adaptador móvil de SharePoint Foundation. Cuando un usuario hace clic en él, el elemento web se expande a la vista de detalles y el icono se convierte en una cabeza de flecha que apunta hacia abajo (que es, en sí misma, un control que ejecuta el script de contracción). Si el explorador no admite CSS y ECMAScript 1.0 o superiores, se presenta otro icono y, si se hace clic en él, el usuario navega hacia una página (mblwpdetail.aspx), que consiste en una vista de detalles del elemento web. Si no desea que el elemento web tenga una vista de detalles en las páginas móviles, pase NoLink a CreateWebPartIcon(WebPartMobileAdapter.WebPartIconLink) en su lugar.

    En una invalidación de CreateControlsForSummaryView() también podría realizar alguna de las siguientes acciones:

    • Si la lógica de presentación supone que ciertas entidades no tienen un valor null o que otras condiciones son verdaderas, considere diseñar la invalidación para probar la hipótesis y no hacer nada, o proporcionar una presentación alternativa cuando las condiciones no sean verdaderas. Por ejemplo, si el elemento web que va a adaptar presenta una vista de lista, puede comprobar si la vista está designada como vista móvil mediante la prueba de this.Control.View.MobileView. Para obtener más información, vea MobileView.

    • Si hay aspectos visibles del elemento web que va a adaptar, que no se muestran solo con un icono y un título, considere construir pequeñas versiones de ellos para la vista de resumen. Por ejemplo, si un gráfico circular es parte del elemento web, la invalidación de CreateControlsForSummaryView() podría incluir una pequeña imagen de un gráfico circular; o si el elemento web incluye una fotografía, la invalidación podría tener una versión a escala muy pequeña de la misma.

  6. Invalide el método CreateControlsForDetailView() si la implementación predeterminada no es adecuada para obtener acceso al elemento web desde dispositivos móviles. La implementación predeterminada presenta un icono y un título para el elemento web, seguidos de un mensaje que dice que no existe una vista de detalles para el elemento web. Si ha invalidado CreateControlsForSummaryView() y no desea proporcionar una vista de detalles, invalide CreateControlsForDetailView() para que no haga nada, como se muestra en el siguiente ejemplo.

    protected override void CreateControlsForDetailView(){}
    
    Protected Overrides Sub CreateControlsForDetailView()
    End Sub
    

    Si desea una vista de detalles, el proceso de invalidación de CreateControlsForDetailView() es el mismo que para invalidar CreateControlsForSummaryView(), excepto que se muestran más detalles del elemento web. Por ejemplo, si el elemento web tiene varios elementos secundarios del mismo tipo, considere mostrar solo algunos de los primeros en la vista de detalles. En el siguiente código de ejemplo, el método se invalida CreateControlsForDetailView() para mostrar hasta tres elementos de la lista actual como secundarios debajo del icono y el título. En Tutorial: Crear un adaptador móvil se brinda una descripción más detallada de este código.

    protected override void CreateControlsForDetailView()
    {
        Image iconImage = this.CreateWebPartIcon(WebPartIconLink.LinkToSummaryView);
        iconImage.BreakAfter = false;
        this.Controls.Add(iconImage);
    
        Label titleLabel = this.CreateWebPartLabel();
        this.Controls.Add(titleLabel);
    
        SPSite siteCollection = SPContext.Current.Site;
        SPUser currentUser = SPContext.Current.Web.CurrentUser;
        SPList taskList = siteCollection.AllWebs["MyGPSite"].Lists["Tasks"];
        SPListItemCollection allTasks = taskList.GetItems(taskList.DefaultView);
    
        // Use LINQ to filter out other users ... 
        var lightweightTasksOfUser = from SPListItem task in allTasks
                                     where task["AssignedTo"].ToString().EndsWith(currentUser.Name)
                                     select new {task.Title, Priority=task["Priority"]}; // ... and unneeded columns.
    
        Int16 itemCount = 1;
        foreach (var lightweightTask in lightweightTasksOfUser)
        {
            Image taskIcon = new Image() { ImageUrl = this.ItemBulletIconUrl,
                                           BreakAfter = false};
            this.Controls.Add(taskIcon);
    
            Label taskTitle = new Label { Text = lightweightTask.Title,
                                          BreakAfter = false};
            taskTitle.Font.Bold = BooleanOption.True;
            this.Controls.Add(taskTitle);
    
            Label priority = new Label() { Text = " " + lightweightTask.Priority };
            priority.Font.Size = FontSize.Small; 
            this.Controls.Add(priority);
    
            this.Controls.Add(new LiteralText());
    
            // Render no more than 3 tasks, but provide link to others.
            if (itemCount++ >= 3)
            {
                Link moreItemLink = new Link
                {
                    Text = "All my tasks",
                    href = SPMobileUtility.GetViewUrl(taskList, taskList.Views["My Tasks"])
                };
                this.Controls.Add(moreItemLink);
                break;
            } // end "if limit has been reached"
    
        } // end "for each lightweight task of the current user"
    } // end CreateControlsForDetailView
    
    Protected Overrides Sub CreateControlsForDetailView()
        Dim iconImage As Image = Me.CreateWebPartIcon(WebPartIconLink.LinkToSummaryView)
        iconImage.BreakAfter = False
        Me.Controls.Add(iconImage)
    
        Dim titleLabel As Label = Me.CreateWebPartLabel()
        Me.Controls.Add(titleLabel)
    
        Dim siteCollection As SPSite = SPContext.Current.Site
        Dim currentUser As SPUser = SPContext.Current.Web.CurrentUser
        Dim taskList As SPList = siteCollection.AllWebs("MyGPSite").Lists("Tasks")
        Dim allTasks As SPListItemCollection = taskList.GetItems(taskList.DefaultView)
    
        ' Use LINQ to filter out other users ... 
        Dim lightweightTasksOfUser = From task As SPListItem In allTasks
                                     Where task("AssignedTo").ToString().EndsWith(currentUser.Name)
                                     Select New With {Key task.Title, Key .Priority = task("Priority")} '... and unneeded columns.
    
        Dim itemCount As Int16 = 1
        For Each lightweightTask In lightweightTasksOfUser
            Dim taskIcon As New Image() With {.ImageUrl = Me.ItemBulletIconUrl, .BreakAfter = False}
            Me.Controls.Add(taskIcon)
    
            Dim taskTitle As Label = New Label With {.Text = lightweightTask.Title, .BreakAfter = False}
            taskTitle.Font.Bold = BooleanOption.True
            Me.Controls.Add(taskTitle)
    
            Dim priority As New Label() With {.Text = " " & lightweightTask.Priority}
            priority.Font.Size = FontSize.Small
            Me.Controls.Add(priority)
    
            Me.Controls.Add(New LiteralText())
    
            ' Render no more than 3 tasks, but provide link to others.
    
            If itemCount >= 3 Then
                itemCount += 1
                Dim moreItemLink As Link = New Link With {.Text = "All my tasks", .href = SPMobileUtility.GetViewUrl(taskList, taskList.Views("My Tasks"))}
                Me.Controls.Add(moreItemLink)
                Exit For
            End If ' end "if limit has been reached"
            itemCount += 1
        Next  ' end "for each lightweight task of the current user"
    End Sub ' end CreateControlsForDetailView
    
  7. Si necesita usar lógica de presentación durante los eventos Init, Load, PreRender o Unload, invalide el método OnLoadForMobile(EventArgs), OnInitForMobile(EventArgs), OnPreRenderForMobile(EventArgs) o OnUnloadForMobile(EventArgs), respectivamente.

  8. Si desea que se redirija a los usuarios móviles directamente a una página de vista de resumen personalizada o a una página de vista de detalles, en lugar de las páginas que se proporcionan en las páginas predeterminadas integradas, invalide la propiedad SummaryViewPageUrl o DetailViewPageUrl.

  9. Para cambiar el icono que aparece al lado del título del elemento web, invalide una o más de las siguientes propiedades:

    • SummaryViewTitleIconUrl – El icono que aparece al lado del título cuando el elemento web está colapsado.

    • DetailViewTitleIconUrl – El icono que aparece al lado del título cuando el elemento web está expandido.

    • TitleIconUrl – El icono que aparece al lado del título cuando un dispositivo móvil no admite scripting de expansión o colapso.

    El siguiente código muestra un ejemplo de cómo invalidar una de estas propiedades. En esta invalidación de TitleIconUrl, si el elemento web muestra una lista que tiene un icono propio en la propiedad ImageUrl, el icono se mostrará.

    protected override string TitleIconUrl
    {
        get
        { 
            SPContext context = SPContext.GetContext(HttpContext.Current);
    
            if (String.IsNullOrEmpty(context.List.ImageUrl))
            {
                return base.TitleIconUrl;
            }
            return context.List.ImageUrl;
        }
    }
    
    Protected Overrides ReadOnly Property TitleIconUrl() As String
        Get
            Dim context As SPContext = SPContext.GetContext(HttpContext.Current)
    
            If String.IsNullOrEmpty(context.List.ImageUrl) Then
                Return MyBase.TitleIconUrl
            End If
            Return context.List.ImageUrl
        End Get
    End Property
    
  10. Compile el ensamblado, asígnele un nombre seguro e impleméntelo en la memoria caché global de ensamblados (GAC) o en la carpeta \BIN de la aplicación web, en todos los servidores front-end web del conjunto o granja de servidores. Se recomienda realizar esta tarea mediante la implementación del adaptador con una solución de SharePoint Foundation. Para simplificar, en este tema se supone que se implementa en la GAC. Para obtener más información sobre la elección, vea el tema sobre cómo colocar el ensamblado en la bandeja o en la memoria caché de ensamblados global. Para copiar el ensamblado solo en la GAC del equipo de desarrollo, use la utilidad gacutil.exe. La manera más fácil de garantizar que cada nueva versión del adaptador se instale en la GAC consiste en ejecutar la utilidad desde un archivo por lotes que se inicie con un evento posterior a la compilación en Visual Studio. El archivo por lotes debe tener la siguiente línea, donde AssemblyName se reemplaza por el nombre del ensamblado.

    Nota

    En este código se supone que ha seguido las recomendaciones de Procedimiento para agregar ubicaciones de herramienta a la variable de entorno PATH.

    gacutil –if bin\debug\AssemblyName.dll
    

Edición del archivo compat.browser

  1. Abra el archivo \\Inetpub\wwwroot\wss\VirtualDirectories\port_number\App_Browsers\compat.browser, donde port_number es el puerto de la aplicación web, en un editor de texto y desplácese hasta el elemento <browser> cuyo valor de atributo refID es "default". Tendrá un elemento secundario <controlAdapters> que tiene una apariencia similar a la del siguiente ejemplo:

    <controlAdapters>
      <adapter controlType="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.XsltListViewWebPartMobileAdapter, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <adapter controlType="Microsoft.SharePoint.WebPartPages.ListViewWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.ListViewWebPartMobileAdapter, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <adapter controlType="Microsoft.SharePoint.Applications.GroupBoard.WebPartPages.WhereaboutsWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.WhereaboutsWebPartMobileAdapter, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <adapter controlType="Microsoft.SharePoint.WebPartPages.ImageWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.ImageWebPartMobileAdapter, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    </controlAdapters>
    
  2. Agregue un elemento <adapter> como elemento secundario del elemento <controlAdapters> para asignar la clase de adaptador al elemento web que adapta, de acuerdo con el modelo del ejemplo anterior. Tenga en cuenta que los atributos controlType y adapterType son obligatorios. Ambos conforman el nombre completo de la clase y el nombre de cuatro partes del ensamblado. Para obtener el token de clave pública del ensamblado de adaptador, use el elemento Get Assembly Public Key en el menú Herramientas de Visual Studio. (Si el elemento no se encuentra allí, vea Procedimiento para crear una herramienta para obtener la clave pública de un ensamblado). Para obtener más información sobre este marcado XML, vea el tema sobre el esquema de archivos de definición de explorador (elemento browsers).

    Los siguientes son ejemplos de los nuevos elementos <adapter>. El primero es para un control Contoso que adapta el UserTasksWebPart que se suministra con SharePoint Foundation. El segundo es para un control Northwinds que adapta un elemento web de Northwinds en la misma solución de Northwinds.

      <adapter controlType="Microsoft.SharePoint.WebPartPages.UserTasksWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c "
        adapterType="Contoso.SharePoint.WebPartPages.UserTasksWebPartMobileAdapter, Contoso, Version=1.0.0.0, Culture=neutral, PublicKeyToken=eedb3d3ba3b4c675" />
    
      <adapter controlType="NorthWinds.SharePoint.WebPartPages.VotingWebPart, Northwinds, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ffec2e2af2b4c675"
        adapterType="NorthWinds.SharePoint.WebPartPages.VotingWebPartMobileAdapter, NorthWinds, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ffec2e2af2b4c675" />
    

    Nota

    Para implementar la clase de adaptador en una granja de servidores, debe cambiar el archivo compat.browser, como se describió anteriormente, en todos los servidores front-end web. No debe sobrescribir el archivo compat.browser existente con un archivo compat.browser propio, ya que esto podría cancelar las asignaciones del adaptador que realizan otros proveedores de soluciones de SharePoint Foundation. Considere implementar el adaptador como parte de una característica de SharePoint Foundation. En el controlador de eventos FeatureActivated(SPFeatureReceiverProperties), agregue código para crear un trabajo del temporizador (SPJobDefinition) que agregue el elemento <adapter> necesario al archivo compat.browser en todos los servidores front-end web. Para obtener información detallada acerca de cómo editar mediante programación el archivo compat.brower en todos los servidores mediante un trabajo del temporizador, vea Procedimiento para ejecutar código en todos los servidores web.

Registro del adaptador como control seguro

  1. Debe registrar la clase de adaptador como control seguro.

    SugerenciaSugerencia

    Se recomienda hacerlo mediante la implementación del adaptador con una solución de SharePoint Foundation. Solo debe realizar los pasos de esta sección si el equipo de desarrollo es un único servidor front-end web. El uso de una solución de SharePoint Foundation permite registrar controles como seguros en todos los servidores front-end web, de manera automática, cuando se implementa la solución. Para obtener más información sobre la implementación de una solución para registrar controles como seguros, vea Introducción a las soluciones, Creación manual de una solución y Esquema de solución.

  2. En el proyecto de Visual Studio, agregue un archivo XML con un nombre en formato webconfig.*.xml, en el cual reemplazará el * con el nombre de su compañía u otro nombre que no vayan a usar otros proveedores de soluciones de SharePoint Foundation.

  3. Agregue un elemento <action> al archivo como el que se muestra en el siguiente marcado. El atributo TypeName del elemento <SafeControl> puede ser el nombre de la clase de adaptador, como UserTasksWebPartMobileAdapter. Si tiene varias clases de adaptador en el mismo espacio de nombres, puede usar "*" como el valor de TypeName. A continuación se muestra un ejemplo.

    <action>
      <remove path="configuration/SharePoint/SafeControls/SafeControl[@Assembly=MyCompany.SharePoint.WebPartPages.MobileAdapters3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=yourAssemblyPublicKeyToken']" />
    
      <add path="configuration/SharePoint/SafeControls">
        <SafeControl
          Assembly="MyCompany.SharePoint.WebPartPages.MobileAdapters3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=yourAssemblyPublicKeyToken"
          Namespace="MyCompany.SharePoint.WebPartPages.MobileAdapters3"
          TypeName="*"
          Safe="True"
          AllowRemoteDesigner="True"
        />
      </add>
    </action>
    
    Nota de precauciónPrecaución

    El uso de "*" como el valor de TypeName hace que todas las clases del espacio de nombres sean controles seguros. Si algunas de las clases del ensamblado no se deberían designar como seguras, muévalas a un ensamblado distinto o evite usar "*".

    Para obtener más información sobre el elemento <SafeControl> y los archivos webconfig.*.xml, vea Procedimiento para crear un archivo adicional .config y Trabajo con archivos Web.config.

  4. Guarde el archivo. Debe copiarlo en la carpeta %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\CONFIG en el equipo de desarrollo. La manera más fácil de hacerlo es agregar las siguientes líneas a una línea de comandos de un evento posterior a la compilación o a un archivo por lotes que se ejecute en una línea de comandos de un evento posterior a la compilación.

    Nota

    En este código se supone que ha seguido las recomendaciones de Procedimiento para agregar ubicaciones de herramienta a la variable de entorno PATH.

    xcopy /y webconfig.MyCompany.xml "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG"
    stsadm –o copyappbincontent
    
  5. El comando stsadmn.execopyappbincontent realiza la "<action>" definida en webconfig.*.xml. En este caso, inserta el nuevo elemento <SafeControl> para el adaptador en el archivo web.config en la raíz de la aplicación web. (Primero quita los elementos <SafeControl> existentes para el adaptador. Esto permite volver a ejecutar la operación stsadm con cada compilación sin duplicar el elemento <SafeControl>). Para obtener más información acerca de copyappbincontent y stsadm.exe, vea el tema sobre la herramienta de línea de comandos Stsadm y sobre Copyappbincontent: operación de Stsadm