Cliff Green's Blog

Creating a 'Link to a Document' Item in a SharePoint Document Library programmatically

One of the new features available in SharePoint 2007 are content types.  Content types allow you to classify content to be a particular type.  By marking content as a particular content type the metadata, workflow and policies associated with that content type are leveraged instead of default policies that may apply to a standard document.  One of the content types available is called 'Link to a Document'.  This content type allows you to store a link to a document in a document library instead of the document itself.  This comes in handy for documents that are stored in an http(s) referenceable location.  When an item is added to a document library and it is classified as a 'Link to a Document' content type an .aspx page is created and stored in the document library as a file.  This page is used to redirect the opening of the file to the location where the document link actually resides.  The content of the .aspx file is shown below.

<%@ Assembly Name='Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' %>
<%@ Register TagPrefix='SharePoint' Namespace='Microsoft.SharePoint.WebControls' Assembly='Microsoft.SharePoint' %>
<%@ Import Namespace='System.IO' %>
<%@ Import Namespace='Microsoft.SharePoint' %>
<%@ Import Namespace='Microsoft.SharePoint.Utilities' %>
<%@ Import Namespace='Microsoft.SharePoint.WebControls' %>

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<Head> <META Name='progid' Content='SharePoint.Link'>
<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:URL msdt:dt="string">http://moss.litwareinc.com/docs/my.xls, http://moss.litwareinc.com/docs/my.xls</mso:URL>
<mso:ContentType msdt:dt="string">Link to a Document</mso:ContentType>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>
    <body>
        <form id='Form1' runat='server'>
            <SharePoint:UrlRedirector id='Redirector1' runat='server' />
        </form>
    </body>
</html>

If you want to create a 'Link to a Document' item programmatically, you can duplicate this file and replace the following string with the Url that matches the document where you want the item linked.

<mso:URL msdt:dt="string">http://moss.litwareinc.com/docs/my.xls, http://moss.litwareinc.com/docs/my.xls</mso:URL>

Create a template .txt file for this with the code below so that you can easily replace the url with your content link.  Notice the reference to {0}, {0}.  This will be used as a string replacement placeholder in the code snippet that will create the item in the document library.  In this example I have saved the file locally to the c: drive as linktodocumenttemplate.txt.

<%@ Assembly Name='Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' %>
<%@ Register TagPrefix='SharePoint' Namespace='Microsoft.SharePoint.WebControls' Assembly='Microsoft.SharePoint' %>
<%@ Import Namespace='System.IO' %>
<%@ Import Namespace='Microsoft.SharePoint' %>
<%@ Import Namespace='Microsoft.SharePoint.Utilities' %>
<%@ Import Namespace='Microsoft.SharePoint.WebControls' %>

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<Head> <META Name='progid' Content='SharePoint.Link'>
<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:URL msdt:dt="string">{0}, {0}</mso:URL>
<mso:ContentType msdt:dt="string">Link to a Document</mso:ContentType>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>
    <body>
        <form id='Form1' runat='server'>
            <SharePoint:UrlRedirector id='Redirector1' runat='server' />
        </form>
    </body>
</html>

Once you have that file in place the following code snippet can be used to create the item in the document library.

using ( SPSite siteCollection = new SPSite( "http://moss.litwareinc.com" ) ) {
    using ( SPWeb web = siteCollection.OpenWeb( "docs" ) ) {
        SPList list = web.Lists["Sample"];

        //link to the file
        string fileLinkUrl = "http://moss.litwareinc.com/docs/Shared%20Documents/ConfigureIRMinWSS30.doc";

        StringBuilder builder = new StringBuilder();

        using ( TextReader reader = new StreamReader( @"C:\linktodocumenttemplate.txt" ) ) {
            builder.Append( reader.ReadToEnd() );
        }

        //replace string template with values
        builder.Replace( "{0}", fileLinkUrl );
        
        //should change the name of the .aspx file per item
        SPFile file = list.RootFolder.Files.Add( "link_title.aspx", UTF8Encoding.UTF8.GetBytes(builder.ToString()));

        //set list item properties
        SPListItem item = file.Item;
        item["Content Type"] = "Link to a Document";
        SPFieldUrlValue itemUrl = new SPFieldUrlValue();
        itemUrl.Description = "From sample code";
        itemUrl.Url = fileLinkUrl;
        item["URL"] = itemUrl;
        //persist changes
        item.Update();
    }
}
Published Monday, June 23, 2008 4:06 PM by green.cliff

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

&raquo; Creating a &#8216;Link to a Document&#8217; Item in a SharePoint Document&#8230; A C One: What The World Is Saying About A C One said:

June 23, 2008 9:44 PM
 

James Shaw's Blog said:

Customizing Sharepoint 2007: Quick Post

July 17, 2008 9:55 PM
 

jim hudson said:

you sir, are a Q@#$%# genius. thanks so much.

July 25, 2008 1:05 PM
 

Nilesh said:

Hi,

following is giving me System.ArgumentException : "Value does not fall within the expected range"

item["URL"] = itemUrl;

can anybody help please?

Following is the stack trace :

  at Microsoft.SharePoint.SPFieldCollection.GetField(String strName, Boolean bThrowException)

  at Microsoft.SharePoint.SPFieldCollection.GetField(String strName)

  at Microsoft.SharePoint.SPListItem.SetValue(String strName, Object value, SPField field, Boolean protectFields)

  at Microsoft.SharePoint.SPListItem.SetValue(String strName, Object value, Boolean protectFields)

  at Microsoft.SharePoint.SPListItem.set_Item(String fieldName, Object value)

  at Landam.Residential.Vortal.Web.UserEventListsItemReceiver.<>c__DisplayClass2.<ItemAdded>b__0()

  at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)

  at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()

  at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)

Regards,

Nilesh Thakkar

October 13, 2008 10:01 AM
 

Bhanu said:

You are excellent! Thank you so much for posting this.

October 27, 2008 3:26 PM
 

kagoodm said:

Is there a way to create a link to a file or a link to a fileshare within a document library WITHOUT having to do programming code?  We haven't been able to figure it out.  Any help would be great.

November 14, 2008 9:59 AM
 

Ashish said:

Thanks

it is really easiest way to create link to a document using code.

for new bee in SharePoint I will recommend to go thru:

http://www.d2design.be/sharepoint/link-to-a-document-in-another-document-library/#comment-209

hope it helps in understanding it better.

December 3, 2008 9:08 AM
 

James Shaw's Blog said:

Customizing Sharepoint 2007: Quick Post

January 18, 2009 4:23 AM
 

David Tweito said:

For Nilesh:

If you're getting "Value does not fall within expected range" for this line:

item["URL"] = itemUrl;

it's most likely because your document library does not have the "Link to a Document" content type assigned.  

In your library, go to settings//document library settings/advanced settings and make sure that "manage content types" is set to yes.  

Next, return to the settings page, locate the "content types" seciton, and add from existing content types.   Make sure you add "Link to a Document"

March 17, 2009 9:18 PM
 

binbui said:

How if i want to run in Japanese lacation ?

March 19, 2009 4:09 AM
 

binbui said:

When running on another location, ex Japanese or French, then the statement:

item["Content Type"] = "Link to a Document";

not correct.

Is there any solution to solve this?

March 19, 2009 4:13 AM
 

binbui said:

When running on another location, ex Japanese or French, then the statement:

item["Content Type"] = "Link to a Document";

not correct.

Is there any solution to solve this?

March 19, 2009 4:13 AM
 

green.cliff said:

I  don't have another language pack installed to test this, but I imagine that the content type field will be called something else in the other language.  Link to Document will probably be called something else also.  I would use the object model to inspect a "Link to Document" item in the document library and output the Xml property so that you can see the internal field names for the item shown by the attributes on the SPListItem.  This should provide you with the correct property name and value that you will need to use in that language.  You can perhaps leverage the resource files to make your code dynamic so that it can change the field name based on the language being used.

March 19, 2009 8:48 AM
 

Veera said:

If I send the link of a LINK content type in an email message, the user cannot open the file by clicking on the link in the message.  Copying and pasting this link in the browser works fine.  Do you see a way around this?

March 27, 2009 1:39 PM
 

est said:

is there a way to make it link to the file in doc lib dynamically. such that it will always display the latest dated file in the folder or doc lib? instead of having to type the url manually

April 17, 2009 2:01 AM
 

green.cliff said:

veera,

sounds like something potentially wrong with the e-mail client.

est,

you would have to use a timer job or event receiver in order to montior the folder or doc lib and then update the content type directly.  it will always link to the latest version of a file because the urls in sharepoint are static as long as the document doesn't move.

April 17, 2009 9:38 PM
 

est said:

Hi,

   yep great. Is it okay if you provide more info on that? thanks alot

April 20, 2009 1:31 AM
 

green.cliff said:

est,

a search of the internet will provide tons of information related to timer jobs and event receivers.  they are well documented, so you sholdn't have trouble finding a solution that fits your needs.

if you just want to display the latest file that was added to a folder in a document library you can create a view and sort by last created date or modified date and limit the results to 1 or you can use the spquery class to query the list like you would a database and display that information.  in those cases you wouldn't need the link to document content type, just a way to show the latest file.

April 20, 2009 7:34 AM
 

est said:

wish it was so straightforward too. However, if i sort it based on the modified datetime. it will not get the most updated file by clicking the link.

for eg. today's date 20090420, so user upload the file.

however user realised theres changes made to 20090412's file. so in that case, 20090412 would be retrieve instead of 20090420's.

yep aware that there are alot info out there, however i dont rly understand why i need to make use of timer job and event receievers. do u think theres a need to?

thanks anyway

April 20, 2009 10:35 AM
 

green.cliff said:

It is not clear to me exactly what you are trying to do.  I offered pointers based on some best guesses, but your description is difficult to understand the use case you are attempting to support.

April 20, 2009 10:46 AM
 

est said:

I apologise for that. However, can I post my question here (with details) but that would be long. Is there alternative I can post it instead? Hope to hear from you soon. thanks

April 21, 2009 6:00 AM
 

est said:

Hi, I've tried out the view mthod you mentioned earlier. Indeed it will always display the latest file uploaded.

For eg. I wanna to display the latest file uploaded in folder A, but lets say I upload file in folder B at a later time than folder A. It will display folder B's file even though the URL path to view the document was folderA's path. I guess this method doesnt work for different subfolder. isnt it?

April 26, 2009 9:10 PM
 

green.cliff said:

it sounds like you need to create a web part that queries the list for this information.  YOu can use the SPQuery class or SPSiteDataQuery class to query the list and return the latest file to display to the user.

April 27, 2009 7:50 AM
 

piece of sharepoint said:

the api is huge and disgusting. there's no  .createlinktoadocument method, or some variation that's much harder to figure out and only works sometimes?

May 28, 2009 4:36 PM
 

Bhaskar said:

You are one of the best programmer.  Fantastic work and this is the only article on INTERNET which i could find.

although I wish there should have been something like

SPFile spFile  = spFolder.File.Add(nameof the file, link to the document);

this would have been much easier.

Best,

Bhaskar

July 1, 2009 11:22 PM
 

Savin said:

Has anyone come up with a way to add a button to an item display screen to link to another list using information on the current item as a filter?

For instance, lets say I have a list of project codes and I also have a list of tasks.  Could I create a link on the Display Project Info p[age to link to the Task List using the "project code" as a filter?

Or, lets say I have lots of documents in a folder and one of the columns is "project code" could I link to the list of documents using the current project code as a filter?

August 17, 2009 5:10 PM
 

Cliff said:

@savin,

I think you could use a QueryString Filter web part to link to the lists and filter that list based on the query string filter which would come from link you pass to the page.  You would probably need a custom action or formula in order to build the query string appropriately to link to the other page.  SPD could also be used to do this.

August 17, 2009 8:28 PM
 

Dheepa said:

This is very useful. Thanks. One suggestion is to check in the item after updating it.

August 21, 2009 10:09 AM
 

Seamus said:

Many thanks - really helped me out. Just one question re. the newly created aspx files - do they actually exist? I am probably missing the whole point, but when I hover over my newly created link it points to what appears to be a tangible aspx file which does not actually exist on the server - is this because the C:\linktodocumenttemplate.txt is just handling the redirect?

Great post, thanks again.

September 2, 2009 10:26 AM
 

green.cliff said:

The aspx files you have created are stored in the document library.  When you click the link it opens this file which casues the redirect to occur.

September 3, 2009 4:41 PM
 

benjamin.beck said:

thnx man. great post.

was lookin for a solution for nearly a week now.

thank u very much

October 6, 2009 1:02 PM

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker