Wednesday, February 17, 2010

Getting Announcements with attachments from sharepoint site

Situation:

I want a web page for the users who does not have network access to be able to look into current announcements published in our sharepoint.


My solution:

1. Use sharepoint web services to get list of current (unexpired/non-expiring) announcements

2. use a console application for 1. so that it can be scheduled and the sarepoint server is not hit everytime a user tryies to see the announcement

3. All announcements are saved in database with a link to attachments (if any)

4. Download all attachments to a location

5. When the schedule runs it clears the database and attachment folder so that we always have current data


This is how I did:

using System;
using System.Text;
using System.Xml;
using System.Configuration;
using System.IO;


namespace SharepointInterface
{
class Program
{
static void Main(string[] args)
{
string webPath = "http://MySharePointSite";
try
{
ClearAllFiles();//delete all previously downloaded attachment
XmlNode xmlData = GetDataFromWebService(webPath);
TraverseXmlData(xmlData);
}
catch (Exception ex)
{
//take necessary action I sent notification email
}
}

///
/// this function will delete all previously downloaded
/// files in 'DownloadLocation'
///

static void ClearAllFiles()
{
try
{
string path = ConfigurationSettings.AppSettings["DownloadLocation"];
string[] files = Directory.GetFiles(path);
foreach (string file in files)
{
FileInfo fi = new FileInfo(file);
fi.Delete();
}
string sql = "DELETE FROM Announcements; DELETE FROM Attachments";
//remove all records from database
DataAccessor da = new DataAccessor();
da.WriteData(sql);
}
catch (Exception ex)
{
//take necessary action
}
}

///
/// Function to communicate with sharepoint web service to get
/// required list data
///

/// Web path

//ref:
//http://www.sharepoint-tips.com/2007/02/how-to-use-getlistitems-web-service.html
private static XmlNode GetDataFromWebService(string webPath)
{
ListWebRef2.Lists sharepointLists = new SharepointInterface.ListWebRef2.Lists();
sharepointLists.Url = webPath + "/_vti_bin/Lists.asmx";
sharepointLists.UseDefaultCredentials = true;

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<Document> <Query /> <ViewFields /> <QueryOptions /> </Document>");
XmlNode query = xmlDoc.SelectSingleNode("//Query");
XmlNode viewFields = xmlDoc.SelectSingleNode("//ViewFields");
XmlNode queryOptions = xmlDoc.SelectSingleNode("//QueryOptions");

//get announcements that has no expiration date or the expiration date is higher than NOW
query.InnerXml = "<Where>" +
"<Or>" +
"<Geq>" +
"<FieldRef Name='Expires' />" +
"<Value Type='DateTime'>" + DateTime.Now.ToString("s").Replace('T', ' ') + "
"<OrderBy> <FieldRef Name='Modified' Ascending='False' />
///
///

///
///
private static void TraverseXmlData(XmlNode xnod)
{
XmlNode xnodWorking;
try
{
if (xnod.NodeType == XmlNodeType.Element)
{//its element
CrackAnnouncementXmlNode(xnod);
}

//if not element; check for child node
if (xnod.HasChildNodes)
{//the node has child node; traverse them as well
xnodWorking = xnod.FirstChild;
while (xnodWorking != null)
{//using recursive technique
TraverseXmlData(xnodWorking);
xnodWorking = xnodWorking.NextSibling;
}
}
}
catch (Exception ex)
{
//take necessary action
}
}

///
/// This function will break announcement node
///

/// Announcement
private static void CrackAnnouncementXmlNode(XmlNode xnode)

{
string sql = string.Empty;
string title, body, modified, editor, uniqueId, attachments;
title = body = modified = editor = uniqueId = attachments = string.Empty;

try
{
/* uncomment this section to see all returned attributes and comment all following if’s
for (int i = 0; i < title =" xnode.Attributes.GetNamedItem(" title =" title.Replace(" body =" xnode.Attributes.GetNamedItem(" body =" body.Replace(" modified =" xnode.Attributes.GetNamedItem(" editor =" xnode.Attributes.GetNamedItem("> 0)
editor = editor.Substring(editor.IndexOf(";#") + 2);
editor = editor.Replace("'", "''");
}

//this is prefixed with ;#
if (xnode.Attributes.GetNamedItem("ows_UniqueId") != null)
{
uniqueId = xnode.Attributes.GetNamedItem("ows_UniqueId").Value;
if (uniqueId.IndexOf(";#") > 0)
uniqueId = uniqueId.Substring(uniqueId.IndexOf(";#") + 2);
}

if (xnode.Attributes.GetNamedItem("ows_Attachments") != null)
{
attachments = xnode.Attributes.GetNamedItem("ows_Attachments").Value;
}

if (attachments != "0" && attachments != string.Empty)
{
//announcement has attachment so download it
DownloadFile df;
df = new DownloadFile(uniqueId, attachments);
df.ParseAndDownload(); //download file(s)
}

if (uniqueId != string.Empty)
{
sql = "INSERT INTO Announcements VALUES ('" + uniqueId + "', '" + title + "', '" + modified + "', '" + editor + "', '" + body + "')";
DataAccessor da = new DataAccessor();
da.WriteData(sql);
}
}
catch (Exception ex)
{
//take necessary action
}
}
}
}

Tuesday, February 16, 2010

Programming with SharePoint

I am writing a small webapp to download "Announcements" from a sharepoint site and had to work with GUIDs. The following link helped me to get guid i needed
http://blogs.msdn.com/ronalus/archive/2007/09/08/a-little-guid-picker.aspx