Tag Archive | sharepoint

SharePoint 2010 – Using Document Id to Link to a Specific Version

SharePoint 2010 introduces Document Id, which is an easy way to create document permalinks across a SharePoint Site (SPSite), without worrying about changing names and folders.
This is all nice and well, but what if you’ve enabled versioning, and want to link to a specific version?
It is a shame DocIdRedir.aspx does not accept a version as an optional parameter, but a small shame, as it is easy enough to implement your own handler, using the API method DocumentId.FindUrlById. Alternately, you could have done that yourself and used DocumentId.FindUrlsById, find the appropriate SPListItem and find the version url, if you don’t approve of the way FindUrlById does that for you.
My solution is to create another page, much like DocIdRedir.aspx, and have it accept a version and act accordingly (in this case I’ve created an ASHX handler, but it should be just the same):

public void ProcessRequest(HttpContext context)
{
	string docId = context.Request.QueryString["id"];
	string versionLabel = context.Request.QueryString["v"];
	SPSite currentSite = SPContext.Current.Site;
	string url = null;
	try
	{
		url = GetUrlFromID(currentSite, docId, versionLabel);
	}
	catch (Exception ex)
	{
		string message = String.Format("Error finding document by id {0} and version [{1}], {2}"
			, docId, versionLabel, ex.Message);
		SPUtility.TransferToErrorPage(message);
	}

	if (url == null)
	{
		string message = String.Format("Could not find document with id {0} and version [{1}]"
			, docId, versionLabel);
		SPUtility.TransferToErrorPage(message);
	}
	else
	{
		context.Response.Write(url);
	}
}

private string GetUrlFromID(SPSite site, string docId, string version)
{
	//FindUrlById throws an exception if version is empty or null,
	// so I check it here to make sure it works.
	if (String.IsNullOrEmpty(version))
	{
		string[] urls = DocumentId.FindUrlsById(site, docId);
		return urls.Single(); // think about what you do here
	}
	else
	{
		return DocumentId.FindUrlById(site, docId, version);
	}
}

After creating and deploying your package, which is effortless in Visual Studio 2010, instead of using the default permalinks:

/_layouts/DocIdRedir.aspx?ID=GROOVY-10-2

you can use your own handler (you may want a shorter solution name and handler):

/_layouts/mySolution/VersionedDocumentId.ashx?id=GROOVY-10-2&v=2.5

See also:

Adding Items to a SharePoint List

Ok, a low-tech post this time. I’ve wasted the better part of my last few days battling Share Point permissions. My goal was to write a web part that lets users add an entry to a Share Point list. So, in case you (or me) need users to add items to a list, this could save us a lot of time…
Read More…

Using Sharepoint’s File Type Icons

We have an old web part that displays documents from a list, and shows an icon next to file. After reading the list, the web part has a long “if-else” block that checks the files extension and displays the proper image. The images come from sharepoint template directory. I need to update this web part to display more file types icons. At first we though to create a list that maps images to extensions, but after little research I’ve decided to read sharepoint’s docicon.xml file.
First, we need to find the file docicon.xml. The file usually sits under

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\template\xml\docicon.xml

The xml directory is not mapped on the IIS, but we can still find it using this little trick:

string path = MapPathSecure("~/_layouts/");
path = Path.Combine(path, @"..\xml\docicon.xml");

Now all that’s left is to read the xml and add the data to a collection:
(This is actually the first time using XmlDataReader, but how wrong can I be?)
First, we define two members, for all files and the default icon, and then go through the XML nodes:
protected NameValueCollection fileTypeIcons;
protected string defaultIcon;

protected void readIconsXml()
{
    XmlReader reader = XmlReader.Create(path);
    reader.ReadToFollowing("ByExtension");
    //find the first child. This doesn't skip the first node.
    reader.ReadToFollowing("Mapping");
    while (reader.ReadToNextSibling("Mapping"))
    {
        readOneNodeMapping(reader);
    }
    //find the default icon
    reader.ReadToFollowing("Default");
    reader.ReadToFollowing("Mapping");
    defaultIcon = reader.GetAttribute("Value");
}

protected void readOneNodeMapping(XmlReader reader)
{
    string tempKey = null;
    string tempValue = null;
    tempValue = reader.GetAttribute("Value");
    tempKey = reader.GetAttribute("Key");
    if ((tempKey != null) && (tempValue != null))
        fileTypeIcons.Add(tempKey, tempValue);
}

And that’s it. We have all icons defined in the site ready in our project.

Follow

Get every new post delivered to your Inbox.