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();
    }
}

Comments (45)

  1. Anonymous says:

    Customizing Sharepoint 2007: Quick Post

  2. Anonymous says:

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

  3. Anonymous says:

    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

  4. Anonymous says:

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

  5. kagoodm says:

    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.

  6. Anonymous says:

    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.

  7. Anonymous says:

    Customizing Sharepoint 2007: Quick Post

  8. Anonymous says:

    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"

  9. Anonymous says:

    How if i want to run in Japanese lacation ?

  10. Anonymous says:

    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?

  11. Anonymous says:

    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?

  12. 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.

  13. Anonymous says:

    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?

  14. Anonymous says:

    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

  15. 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.

  16. Anonymous says:

    Hi,

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

  17. 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.

  18. Anonymous says:

    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

  19. 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.

  20. Anonymous says:

    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

  21. Anonymous says:

    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?

  22. 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.

  23. Anonymous says:

    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?

  24. Anonymous says:

    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

  25. Anonymous says:

    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?

  26. Anonymous says:

    @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.

  27. Anonymous says:

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

  28. Anonymous says:

    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.

  29. 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.

  30. Anonymous says:

    thnx man. great post.

    was lookin for a solution for nearly a week now.

    thank u very much

  31. Anonymous says:

    I have tried using this in console application , when i am trying to clcik on link_title its redirecting to the  

    @"C:linktodocumenttemplate.txt , i want it to redirect it to the url like

    string fileLinkUrl = "http://download.microsoft.com/documents/customerevidence/22174_GETS_–_Windows_XP_Tablet_PC.doc&quot;;

    how it can be achieved..

    Thanks in Advance..

    Please reply..

    Great Post..

  32. Anonymous says:

    here file link url are  external lin from internet, they are not existing on the sharepoint

    those links can be folder location or any files from  internet as well.

    for complete description read both comments from khush.

    Thanks

  33. Anonymous says:

    Is there a way to modify the link-to-document aspx so that the file may be opened in edit mode?  

    When i click a link to a document (a document that, when clicked separatedly, will ask me if i want edit or read-only mode), the normal IE dialogue opens (open, save, cancel) instead.  All link-to-document files open the file in read-only mode (in office 2007).

    thanks

  34. Trikes,

    I would look at the url that is generated when you go into edit mode on a document.  See if you can change the redirect url in the link to document to accomodate this.  There is nothing out of the box, and the reason it is happening is because you are redirecting directly to the document in question, as opposed to passing values or running javascript to indicate that you want to open the document in edit mode.

  35. Anonymous says:

    This is progress?  Hard coding file names? Editing txt files?

  36. Anonymous says:

    Where do I put or how do I use the code snippet above to actually create the Link to Document.  I assume it will go in a console application so the user can browse the document library and select which file(s) need shortcuts created, and then point to the document Library where "Links To Documents" are to be saved?

    Or can this run in a  Content Editor web part ?

    Obviously by this question you can see I do not have any experience with programming for SharePoint Document Libraries.  Any help you can provide or direction you may offer would be greatly appreciated.

    Harry Parsonage

  37. Harry,

    How you do this is up to you and your requirements.  Think about how your users would need to use this.  What I have here is simply an easy example to get the point across.  You could have a custom action on the site actions menu, a console app, javascript that calls a web service that has been added to the content editor web part, the list goes on.

    Take some time to get more experience working with SharePoint before you determine the best course of action.

  38. Anonymous says:

    Is there a way to create a link to a file without having to do programming code? If so please explain. Thanks

  39. Anonymous says:

    gooseegg …

    The Link to Document content type does exactly what you are asking.  Add it as a content type to the document library and then create a new item using the link to document content type.  It allows you to link to a file.

  40. Anonymous says:

    Hi Cliff,

    Your blog was of great help. I am facing one issue.

    Our requirement is to allow mailto: also in Link to document type along with http and https.

    for ex mailto:a@b.com

    And it comes but when we click Type and Name field on Allitems.aspx page of document library

    outlook client opens but the page also shows mailto:a@b.com  and goes blank.

    Please provide your inputs in this issue.

    Thanks

  41. Anonymous says:

    Solved using PowerShell : stackoverflow.com/…/15641493

  42. Anonymous says:

    Follow the simple steps in this document, its easy-peasy to do, no coding or XML messing about: http://www.sharepointology.com/…/link-to-a-document-in-another-document-library

  43. @Nina

    Yes, it's easy to do in the UI, that's why the content type Link to Document exists :-).  What this post addresses is how to do it using code where you don't have access to the UI or want to create a link to document in a workflow or something else.

    Thanks!

  44. Anonymous says:

    Any help with this thing will be greatly appreciated:

    sharepoint.stackexchange.com/…/sharepoint-reference-file-in-item-properties

    That's my first work with SharePoint and I think I am about to hate that thing…