MOSS: Ejemplo funcional: tipo de datos personalizados

Escenario de negocio:

Implementación de toda la empresa de musgo para empresa industrial con 30+ sitios y unos docenas de departamentos.

Objetivo de negocio:

A pesar de una multitud de grupos empresariales (departamentos, ubicaciones, etc.), ciertos datos deben mantenerse a un nivel global. Por ejemplo, una lista autorizada de todas las ubicaciones físicas de la empresa (por ejemplo:. instalaciones de fabricación, ubicaciones de almacén, oficinas de ventas) debe mantenerse en una ubicación central.

Problema técnico:

La taxonomía de empresa se implementó utilizando múltiples colecciones de sitios. Nos hubiera gustado crear la lista autorizada de ubicaciones físicas en una lista personalizada de WSS. A continuación, cuando necesitamos tener una columna en un tipo de contenido (o agrega una columna a una biblioteca lista o doc) que contenía sedes corporativas, crearíamos una columna usando la "búsqueda" tipo de datos y punto a esta lista maestra.

Por desgracia, tipos de datos de búsqueda deben acceder a una lista de fuentes "localmente" lo que significa que la lista autorizada no puede abarcar colecciones de sitios.

Solución técnica:

Implementar un nuevo tipo de datos personalizado aplicado basado en SPField y representado como un DropDownList en la interfaz de usuario cuyas ListItems poblar de la lista principal de WSS.

Hemos creado una nueva colección de sitios llamada "http://localhost/EnterpriseData". Allí, Hemos creado una lista personalizada denominada "Sedes corporativas". Esta lista sólo utiliza el estándar "título" campo que contiene la lista de sedes corporativas reales.

Uno sigue varios pasos específicos para crear un tipo de datos personalizado en WSS. Son:

  1. Definir una clase que hereda de SPField (uno puede heredar de otros campos si es necesario).

Aquí está el código para que:

público clase XYZZYCorporateLocationField : SPFieldText
{
público XYZZYCorporateLocationField
(SPFieldCollection campos, cadena typeName, cadena displayName)
: base(campos, typeName, displayName) { }

público XYZZYCorporateLocationField
(SPFieldCollection campos, cadena displayName)
: base(campos, displayName) { }

público reemplazar BaseFieldControl FieldRenderingControl
{
Obtener
{
BaseFieldControl control = Nuevo XYZZYCorporateLocationFieldControl();
control. FieldName = Esto.InternalName;
retorno control;
} //Obtener
} // fieldrenderingcontrol

público reemplazar cadena GetValidatedString(objeto valor)
{
Si (Esto.Obligatorio || valor. ToString().Es igual a(Cadena.Vacío))
{
tiro Nuevo SPFieldValidationException ("El Departamento no está asignado.");
}
retorno base.GetValidatedString(valor);
} // getvalidatedstring

} // XYZZYCorporateLocation

  1. Definir otra clase que se hereda del control de campo base, como en:

público clase XYZZYCorporateLocationFieldControl : BaseFieldControl
{
protegido DropDownList XYZZYCorporateLocationSelector;

protegido reemplazar cadena DefaultTemplateName
{
Obtener
{
retorno "XYZZYCorporateLocationFieldControl";
}
} // DefaultTemplateName

público reemplazar objeto Valor
{
Obtener
{
EnsureChildControls();
retorno Esto.XYZZYCorporateLocationSelector. SelectedValue;
} // Obtener
conjunto
{
EnsureChildControls();
Esto.XYZZYCorporateLocationSelector.SelectedValue = (cadena)Esto.ItemFieldValue;
} // conjunto
} // redefinir objeto valor

protegido reemplazar void CreateChildControls()
{

Si (Esto.Campo == NULL || Esto.ControlMode == SPControlMode.Pantalla)
retorno;

base.CreateChildControls();

Esto.XYZZYCorporateLocationSelector =
(DropDownList)TemplateContainer. FindControl("XYZZYCorporateLocationSelector");

Si (Esto.XYZZYCorporateLocationSelector == NULL)
tiro Nuevo Excepción("ERROR: No se puede cargar. Archivo ASCX!");

Si (!Esto.IsPostBack página.)
{

utilizando (SPSite sitio = Nuevo SPSite("http://localhost/enterprisedata"))
{
utilizando (SPWeb Web = página. OpenWeb())
{

SPList currentList = web. Listas de[«Sedes corporativas"];

foreach (SPItem XYZZYCorporateLocation en currentList.Items)
{
Si (XYZZYCorporateLocation["El título"] == NULL) «««;

cadena Sr.;
theTitle = XYZZYCorporateLocation["El título"].ToString();

Esto.XYZZYCorporateLocationSelector.Items.Add
(Nuevo ListItem(Sr., Sr.));

} // foreach

} // uso de spweb web = site.openweb()
} // uso de spsite site = new spsite("http://localhost/enterprisedata")

} // Si no es una devolución de datos

} // CreateChildControls

} // XYZZYCorporateLocationFieldControl

El código anterior básicamente implementa la lógica para rellenar el DropDownList con los valores de la lista personalizada de WSS ubicado en http://localhost/enterprisedata y llamado "departamentos".

Definí ambas clases en un archivo .cs sola, lo compila y lo puso en la GAC (fuerte necesaria, Claro).

  1. Aplicar una plantilla de control (.ascx) como se muestra:

<%@ Control Idioma= "C#" Hereda="Microsoft.SharePoint.portal.ServerAdmin.CreateSiteCollectionPanel1,Microsoft.SharePoint.portal,Versión = 12.0.0.0, cultura = neutral,PublicKeyToken = 71e9bce111e9429c" compilationMode= "Always" %>
<%
@ Registro TagPrefix= wssawc"" Namespace="Microsoft.SharePoint.WebControls" Asamblea="Microsoft.SharePoint, Versión = 12.0.0.0, Cultura = neutral, PublicKeyToken = 71e9bce111e9429c" %> <%@ Registro TagPrefix= "SharePoint" Namespace="Microsoft.SharePoint.WebControls" Asamblea="Microsoft.SharePoint, Versión = 12.0.0.0, Cultura = neutral, PublicKeyToken = 71e9bce111e9429c" %>
<SharePoint:RenderingTemplate ID.= XYZZYCorporateLocationFieldControl"" runat= "server">
<Plantilla>
<ASP:DropDownList ID.= XYZZYCorporateLocationSelector"" runat= "server" />
</Plantilla>
</
SharePoint:RenderingTemplate>

Lo anterior se guarda en c:\programa archivos de programaArchivos comunesMicrosoft sharedweb server extensions12controltemplates.

  1. Finalmente, creamos un archivo XML para guardar en el... 12XML directorio. Se trata de CAML que define el tipo de datos personalizados y por mi ejemplo, Parece que esto:

<?XML Versión="1.0" codificación="UTF-8" ?>
<
FieldTypes>
<
FieldType>
<
Campo Nombre="TypeName">CorporateLocations</Campo>
<
Campo Nombre="ParentType">Texto</Campo>
<
Campo Nombre="TypeDisplayName">Sedes corporativas</Campo>
<
Campo Nombre="TypeShortDescription">Todas las ubicaciones XYZZY corporativo incluyendo instalaciones de fabricación o de otras.</Campo>
<
Campo Nombre="UserCreatable">VERDADERO</Campo>
<
Campo Nombre="ShowInListCreate">VERDADERO</Campo>
<
Campo Nombre="ShowInDocumentLibraryCreate">VERDADERO</Campo>
<
Campo Nombre="ShowInSurveyCreate">VERDADERO</Campo>
<
Campo Nombre="ShowInColumnTemplateCreate">VERDADERO</Campo>
<
Campo Nombre="FieldTypeClass">Conchango.XYZZYCorporateLocationField, XYZZYCorporateLocationField, Versión = 1.0.0.0, Cultura = neutral, PublicKeyToken = b0b19e85410990c4</Campo>
<
RenderPattern Nombre="DisplayPattern">
<
Interruptor>
<
Expr>
<
Columna />
</
Expr>

<Caso Valor=""/>

<Por defecto>
<
HTML>
<![CDATA[
<span estilo = "color:Rojo"><b>]]>
</
HTML>

<
Columna SubColumnNumber="0" HTMLEncode="VERDADERO"/>

<HTML><![CDATA[</b></abarcan>]]></HTML>

</
Por defecto>
</
Interruptor>

</
RenderPattern>
</
FieldType>
</
FieldTypes>
Este archivo XML agrega el tipo de datos personalizado a la "biblioteca WSS" y coincide con lo contra la GAC tenía Asamblea.

Después de todos estos bits en su lugar, iisreset en el servidor y debe empezar a trabajar muy bien.

3 pensamientos sobre "MOSS: Ejemplo funcional: tipo de datos personalizados

  1. Alejandro
    Hola Pablo,
    En primer lugar, Gracias por el artículo, Porque es muy interesante. Sólo una pregunta;
    ¿Sabes si es posible procesar correctamente un tipo de campo personalizado en la vista Hoja de datos de una lista?
    Porque cada tipo de campo personalizado lo creo se muestra como de sólo lectura en la vista Hoja de datos (y la MSDN, por ejemplo, No me ayuda mucho :-S).
    Gracias
    Respuesta
  2. Lindsay

    Estoy tratando de implementar la solución. Sin embargo yo en vez de DropDownList, Sólo tengo la opción de un DropDownChoiceList. Suceden saber cómo agregar elementos a un DropDownChoiceList? Estamos utilizando SharePoint 2007 SP1 y Visual Studio 2005 SP1.

    Respuesta

Contesta

su dirección de correo electrónico no será publicada. Los campos necesarios están marcados *