Archive

Archive for 30 junio 2011

Algunos recursos sobre FAST Search Server


Si usas SharePoint sabes que 2010 viene con FAST Search Server for SharePoint. Ésta es una herramienta poderosísima de búsqueda, tanto para sitios internos como externos y bases de datos.

Para programar contra FAST, haré una serie de artículos. Pero por el momento, revisa estos recursos.

1.- Consulta FAST Search Server desde aplicación cliente. Me sirvió mucho este tutorial, y en esencia lo que dice es que uses el servicio web Search.asmx provisto por SharePoint.

2.- FAST Query Language. FAST usa un lenguaje llamado FQL para realizar consultas personalizadas. Explora su contenido.

3.- Ejemplo Sencillo sobre FQL. Pues eso, un ejemplo sencillo.

Espero sirvan de introducción. Kudos al equipo de MSDN por esta documentación. También, si saben de más ejemplos, no duden en dejar el comentario, ya que es información difícil de localizar.

Tschüss!

Obtener la dirección del perfil de un usuario en SharePoint 2010


Un pequeño tip / código para obtener el perfil de un usuario en SharePoint 2010. Tienes que referenciar la librería Microsoft.Office.Server.UserProfiles para que funcione.

SPServiceContext context = SPServiceContext.GetContext(Web.Site);
UserProfileManager manager = new UserProfileManager(context);

string userLogin = "dominio\\usuario";
UserProfile profile;
if (!manager.UserExists(userLogin))
    profile = manager.CreateUserProfile(userLogin);
else
    profile = manager.GetUserProfile(userLogin);
url = profile.PersonalUrl.ToString();

En la línea 1 obtenemos un contexto de servicio, mientras que en la 2 obtenemos el administrador del perfil. En la sexta línea revisamos si existe el perfil del usuario, y si no existe la creamos. Si sí existe, obtenemos el perfil.

Por último, la propiedad PersonalUrl de UserProfile contiene un Uri hacia el perfil del usuario. Schön gut!

Cómo utilizar los servicios de .NET Framework para leer canales RSS y ATOM


He añadido un código de ejemplo a la Galería de Código de MSDN, a continuación transcribo lo que publiqué. Pueden descargar el código desde aquí.

 

Introducción

 

Los canales RSS y ATOM proveen un mecanismo estándar para publicar contenido sobre sitios web, como texto, imágenes, vídeos, etc. Dichos formatos son documentos XML con una estructura predefinida. Durante cierto tiempo la solución para crear un lector para dichos formatos ha sido, en el mundo de .NET, crear el documento y analizarlo a mano. Las últimas versiones de .NET vienen con servicios para poder analizar ese contenido de forma automática. El código aquí presentado muestra cómo hacerlo.

Construcción del ejemplo

El ejemplo está construido sobre .NET Framework 4, para Visual Studio 2010. Sin embargo debe poder portarse a .NET Framework 3.5 sin mucho problema. En particular, se utiliza la biblioteca System.ServiceModel.dll, la cual contiene las clases necesarias para leer los canales RSS y ATOM.

La compilación de este ejemplo es sencilla y no necesita consideraciones especiales.

Descripción

Básicamente el proceso de lectura de un canal RSS o ATOM se da siguiendo estos pasos.

  1. Descargar el contenido XML del canal, usando un XmlReader por ejemplo.
  2. Crear un formateador. Estos pueden ser, por ejemplo, las clases Rss20FeedFormatter, o bien Atom10FeedFormatter (del espacio de nombres System.ServiceModel.Syndication), para canales RSS y ATOM, respectivamente.
  3. Pasar el objeto XmlReader al método ReadFrom del Rss20FeedFormatter o del Atom10FeedFormatter.

Una vez hecho esto, el objeto formateador habrá analizado el XML y ¡bazzinga! estamos listos. Mediante la propiedad Feed se accede al contenido del canal, la cual a su vez cuenta con la propiedad Items, que es una colección para cada uno de los elementos encontrados.

El siguiente trozo de código es un extracto, el cual muestra cómo leemos el canal y cargamos el contenido en un control TreeView.

// Creamos el formateador, el cual será RSS o ATOM, dependiendo de la opción
// seleccionada por el usuario. 
SyndicationFeedFormatter formatter = CreateFormatter();

// Leemos el XML de la URL seleccionada...
using (XmlReader reader = XmlReader.Create(_urlText.Text))
{
    // ...y le decimos al formateador que analice el XML del feed. 
    formatter.ReadFrom(reader);
}
// Si la URL es inválida, recibiremos un UriFormatException. Si el XML 
// descargado tiene algún contenido inválido, que no se ciña a la especificación
// de RSS o de ATOM, entonces recibiremos un XmlException. 

// Vaciamos el árbol y añadimos un nodo raíz. 
_feedTree.Nodes.Clear();
TreeNode rootNode = _feedTree.Nodes.Add(formatter.Feed.Title.Text);

// Para cada elemento encontrado en el feed añadimos un nodo. Adjuntamos 
// el objeto de dicho elemento a la propiedad Tag del nodo, para poder
// referirnos a éste posteriormente (i.e. cuando se dispare el evento
// NodeMouseClick). 
foreach (SyndicationItem item in formatter.Feed.Items)
{
    TreeNode feedNode = rootNode.Nodes.Add(item.Title.Text);
    feedNode.Tag = item;
}

El siguiente trozo muestra cómo cargar el contenido de un elemento del canal en una caja de texto. También es un extracto del código fuente.

SyndicationItem item = args.Node.Tag as SyndicationItem; 
if (item != null) 
{ 
    StringBuilder text = new StringBuilder() 
        .AppendFormat("Título: {0}\r\n", item.Title.Text) 
        .AppendFormat("Publicado: {0}\r\n", item.PublishDate.DateTime) 
        .AppendFormat("Actualizado: {0}\r\n", item.LastUpdatedTime.DateTime) 
        .AppendLine() 
        .AppendFormat(item.Summary.Text) 
        .AppendLine() 
        .AppendLine(); 
    if (item.Content != null) 
    { 
        text.AppendLine(item.Content.Type); 
    } 
                 
    _contentText.Text = text.ToString(); 
 
    _linkLabel.Text = item.Title.Text; 
    _linkLabel.Tag = item; 
}

A continuación, una imagen de cómo luce el programa.

Lector sencillo de rss

Código fuente

 

La solución presenta estos proyectos:

1.- SimpleRssFeed. Muestra una aplicación en Windows Forms sobre cómo utilizar los canales de comunicación RSS y ATOM. Muestra cómo emplear las clases System.ServiceModel.Syndication.Rss20FeedFormatter.

  • RssFeed.cs – el formulario principal de la aplicación.

Más información

Para más información, revisa estos enlaces en la documentación de MSDN:

Atom10FeedFormatter

Rss20FeedFormatter

SyndicationFeed

SyndicationItem

Problemas al mostrar ventana emergente


Hace unos días escribí sobre cómo mostrar una ventana emergente en SharePoint. Pues bien, todo se reducía a un simple código con JavaScript, el cual reproduzco:

<script type="text/javascript" language="javascript">
    function openAsgardDialog()
    {
        var options = {
            url: "/Pages/AsgardPantheon.aspx",
            width: 800,
            height: 650,
            title: "Hola mundo",
	    };
	    SP.UI.ModalDialog.showModalDialog(options);
    }
</script>";

Ahora bien, ese código funciona bien… o eso pensé. Resulta que correr eso en el Internet Explorer 7 nos piña y nos manda un error, diciendo que no se pudieron cargar los controles Ajax. El hecho, sin embargo, es que esta sintaxis no le funciona, al parecer. Estuve investigando y aquí hay una sintaxis alternativa para iniciar el objeto. Por lo demás, queda igual…

<script type="text/javascript" language="javascript">
    function openAsgardDialog() 
    {
        var options = SP.UI.$create_DialogOptions();
        options.url = "/Pages/AsgardPantheon.aspx";
        options.height = 800;
        options.width = 650;
        options.title = "Hola mundo";

	    SP.UI.ModalDialog.showModalDialog(options);
    }
</script>

Una sintaxis un poquito más tradicional, pero funciona con IE 7.

Mostrar una ventana emergente desde un WebPart


En SharePoint 2010 introdujeron para muchas cosas ventanas emergentes, aprovechando que todo el sitio ahora cuenta con soporte para Ajax a través del UpdatePanel. Para que podamos hacer algo similar, basta usar un sencillo código en JavaScript.

<script type="text/javascript" language="javascript">
    function openAsgardDialog() 
    {
        var options = {
            url: "/Pages/AsgardPantheon.aspx",
            width: 800,
            height: 650,
            title: "Hola mundo",
	    };
	    SP.UI.ModalDialog.showModalDialog(options);
    }
</script>";

Al ser invocada dicha función, aparecerá una ventana emergente con el título y dimensiones especificadas, y cargará la página /Pages/AsgardPantheon.aspx, o cualquier otra que especifiquemos.

Ahora bien, para hacer esto desde un WebPart, tres cosas deben ocurrir.

1.- Asegurarnos que el master page cuenta con un UpdatePanel. Esto es esencial, puesto que si no Ajax no funciona. Es el comportamiento por default en SharePoint, sólo una precaución por si alguien lo quitó.

2.- El WebPart deberá registrar el script que permitirá mostrar la ventana emergente.

private void RegisterOpenHelloWorldDialogScript()
{
    string script =
        @"<script type=""text/javascript"" language=""javascript"">
            function openAsgardDialog() 
            {{
                var options = {{
                    url: ""{0}/Pages/AsgardPantheon.aspx"",
                    width: 800,
                    height: 650,
                    title: ""ASGARD"",
	            }};
	            SP.UI.ModalDialog.showModalDialog(options);
            }}
            </script>";
    script = string.Format(script, SPContext.Current.Web.Url);

    Page.ClientScript.RegisterClientScriptBlock(GetType(),
            "OpenAsgardDialogScript", script);
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    RegisterOpenHelloWorldDialogScript();
}

3.- Llamamos a nuestro JavaScript desde algún control. En este caso, creamos una etiqueta <a> que haga lo propio.

protected override void CreateChildControls()
{
    Literal literal = new Literal();
    literal.Text = "<h3>Ejemplo Ventana Emergente</h3>" +
                           "Haga <a href="\&quot;#\&quot;" onclick="\"javascript:openAsgardDialog();\"">" +
                           "click aqu&iacute;</a> para abrir. ";
    Controls.Add(literal);
}

Y eso es todo. Una imagen de cómo luciría el WebPart…

image

…y la ventana emergente.

image