Ejemplo sobre el uso de metadatos de SharePoint


Ayer puse un pequeño tip sobre cómo utilizar SPListItem.Properties y SPWeb.AllProperties para guardar información y que ésta no se muestre al usuario, de forma accesible. Pues bien, quisiera mostrarles esto que he hecho a fecha reciente para que vean cómo puede usarse.

Primero, les comento el requerimiento. Tengo una lista que contiene información sobre productos: código del material, nombre, descripción y una columna que indica los usuarios asignados a dicho producto. Posteriormente, es responsabilidad de cada usuario asignado a dicho producto, capturar diario un valor que refleje la cantidad de producto habido en el almacén.

Entonces, primero tengo mi lista. Ésta luce así.

image

Como pueden ver, es una lista normal y de hecho el sitio no tiene ninguna otra lista. Hasta aquí easy peasy. Ahora, necesitamos crear un Application Page que muestre los productos por fecha y permita capturar una cantidad. Para ello, tomamos un control calendario y un SPGridView, al cual le creamos la columna “Cantidad”. El código ASP del grid luce algo así:

<SharePoint:SPGridView ID="_grid" runat="server" 
    AutoGenerateColumns="false" DataSourceID="_mainSource">
    <Columns>
        <asp:CommandField ButtonType="Image" ShowEditButton="true" 
            EditImageUrl="/_layouts/images/edit.gif" 
            UpdateImageUrl="/_layouts/images/save.gif" 
            CancelImageUrl="/_layouts/images/delete.gif" />
        <SharePoint:SPBoundField HeaderText="Código de material" DataField="Code" />
        <SharePoint:SPBoundField HeaderText="Nombre del producto" DataField="Name" />
        <SharePoint:SPBoundField HeaderText="Descripción" DataField="Description" />
        <asp:TemplateField HeaderText="Cantidad">
            <ItemTemplate>
                <asp:Label runat="server" 
                    Text='<%# ((double)Eval("Quantity")).ToString("0.00") %>' />
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="_quantityText" runat="server" Width="100px" 
                    Text='<%# Bind("Quantity") %>' />
                <br />
                <asp:RangeValidator runat="server" EnableClientScript="true" Type="Double"
                    MinimumValue="0" MaximumValue="9999999999" 
                    ControlToValidate="_quantityText" 
                    Text="Sólo se admiten números positivos" />
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Fecha">
            <ItemTemplate>
                <asp:Label runat="server" 
                    Text='<%# ((DateTime)Eval("Date")).ToShortDateString() %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="">
            <ItemTemplate>
                <asp:HiddenField ID="_idHiddenField" runat="server" 
                    Value='<%# Bind("ID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <EmptyDataTemplate>
        <h3>No hay información a mostrar.</h3>
    </EmptyDataTemplate>    
</SharePoint:SPGridView>

Utilizo un ObjectDataSource como proveedor de datos, el cual manda llamar un método que retorna un DataTable, filtrado por la fecha seleccionada en el calendario. Éste método realiza lo siguiente:

1.- Obtiene una referencia a la lista (SPList) de los productos e itera sobre cada uno de ellos.

2.- Para cada producto (SPListItem) verifica que el usuario actualmente autenticado (SPContext.Web.CurrentUser) esté dentro de los elementos de la columna “Usuarios”.

3.- Crea una llave de texto con base en los siguientes datos: cuenta del usuario, guión bajo, la fecha del día seleccionado en el calendario.

private string GetDatedProductKey(string user, DateTime date)
{
    if (user == null)
        throw new ArgumentNullException("user");

    return string.Format("{0}_{1}{2}{3}", user, date.Year, date.Month, date.Day);
}

4.- Revisamos en el Hashtable “Properties” del producto (SPListItem) para ver si la clave existe. Si sí, obtenemos el valor y hacemos la conversión a un double. Si no, simplemente dejamos un 0.0.

string key = GetDatedProductKey(user, date);
if (product.Properties.Contains(key))
{
    string value = product.Properties[key] as string;
    double quantity;
    double.TryParse(value, out quantity);
    row["Quantity"] = quantity;
}
else
{
    bool allowUpdates = Web.AllowUnsafeUpdates;
    Web.AllowUnsafeUpdates = true;
    product.Properties.Add(key, "0.0");
    product.Update();
    Web.AllowUnsafeUpdates = allowUpdates;

    row["Quantity"] = 0.0;
}

5.- Añadimos una fila al DataTable, llenamos los datos y al final, retornamos la tabla. El SPGridView enlazará sin problemas.

Hacer lo anterior nos garantiza que la cantidad se guarde por fecha y usuarios diferentes. Es decir, para el 9 de mayo de 2011, asgard\loki muestra una cantidad de 10 unidades mientras que asgard\heimdall muestra 20. De esta manera almacenamos la información en el mismo elemento SPListItem, pero sin comprometer la información.

image

El proceso de hacer la actualización de la información en el SPGridView es muy similar a cualquier otro GridView. Baste decir que dicho control está enlazado con un método Update en el ObjectDataSource. Este método termina por modificar el valor de forma relatívamente fácil, usando la misma llave generada por la fecha y la cuenta del usuario.

public void UpdateDatedProducts(string user, DateTime date, int id, double quantity)
{
    SPListItem product = List.Items.GetItemById(id);
    string key = GetDatedProductKey(user, date);

    bool allowUpdates = Web.AllowUnsafeUpdates;
    Web.AllowUnsafeUpdates = true;
            
    if (!product.Properties.ContainsKey(key))
        product.Properties.Add(key, quantity.ToString("0.00"));
    else
        product.Properties[key] = quantity.ToString("0.00");
    product.Update();

    Web.AllowUnsafeUpdates = allowUpdates;
}

Y listo, easy peasy.

  1. Lisandro
    noviembre 23, 2011 a las 2:05 pm

    Tengo un problema que me urge resolver.

    He creado una biblioteca sharepoint donde subo documentos mediante un .net o manualmente, mucha veces el usuario deja la metadata en blanco cuando lo sube manualmente, necesito hacer un programa .net que haga esto.

    1. Busque los documentos que en una metadata “codigo”, “nombre”,”fecha” tenga valores en blanco o que en la metadata “cerrado” sea “SI”.

    2. A esos documento actualizarles la metadata masivamente con valores que el usuario escribira en la pantalla.

    como lo puedo hacer? tienen algun ejemplo

  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s