Display SharePoint Documents On Your Company Internet Site

I was recently working on a small POC project. Basically I had an internal MOSS 2007 server site and an locally hosted public facing website. I wanted to have the ability to add files to various MOSS document libraries and then give outside website visitors the ability to view and download these documents. So, what I did was:

  1. Created a document library in MOSS with Version and Content Approval enabled. I also added additional custom fields to the document library that could  display along with the document on the public web.
  2. Created a user control that I could drag to the public pages to display the documents and wired up the user control to access SharePoints webservices to rectrieve and display the document libraries specifics. (SEE CODE BELOW)

This is only a POC so bare with me.  You should be able to follow the basics of what I am doing.  Nothing is rocket science.

  1. Create a new WebSite in Visual Studio.
  2. Add a new web_reference. Point it at your SharePoint server (http://<Your SharePoint Server>/_vti_bin/List.asmx)
  3. Add a new user control to your website. (SEE CODE BELOW)
  4. Add a new webpage and drag on your user control to it. Run and enjoy.

Imports System.Net

Imports System.IO

Imports MOSS 'THIS IS YOUR WEB_REFERENCE

 

Partial Class SPDocuments

    Inherits System.Web.UI.UserControl

 

    'THIS IS THE KEY TO IT ALL. THIS USER MUST HAVE READ ONLY CREDENTIALS

    'TO THE DOCUMENT LIBRARY. THAT WAY THE SEE THE LATEST PUBLISH DOCUMENT ONLY.

    Dim networkCredential As New NetworkCredential("username", "password")

 

 

    Private _DocumentLibraryID As String

    Public Property DocumentLibraryID() As String

        Get

            Return _DocumentLibraryID

        End Get

        Set(ByVal value As String)

            _DocumentLibraryID = value

        End Set

    End Property

 

    Private _DocumentLibrary As String

    Public Property DocumentLibrary() As String

        Get

            Return _DocumentLibrary

        End Get

        Set(ByVal value As String)

            _DocumentLibrary = value

        End Set

    End Property

 

    Private _FileServer As String

    Public Property FileServer() As String

        Get

            Return _FileServer

        End Get

        Set(ByVal value As String)

            _FileServer = value

        End Set

    End Property

 

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)

        MyBase.OnInit(e)

        If DocumentLibraryID Is Nothing Then

            DocumentLibraryID = GetListID(DocumentLibrary)

        Else

            DocumentLibrary = GetListID(DocumentLibraryID)

        End If

        BindLiteral()

    End Sub

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then

 

        End If

    End Sub

 

    Private Sub BindLiteral()

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

        ' Assign values to the string parameters of the GetListItems method, using GUIDs for the listName and viewName

        'variables. For listName, using the list display name will also work, but using the list GUID is recommended. For

        'viewName, only the view GUID can be used. Using an empty string for viewName causes the default view

        'to be used.

        Dim listName As String = DocumentLibraryID

        Dim viewName As String = ""

        Dim rowLimit As String = "1000"

 

        'Use the CreateElement method of the document object to create elements for the parameters that use XML.*/

        Dim query As System.Xml.XmlElement = xmlDoc.CreateElement("Query")

        Dim viewFields As System.Xml.XmlElement = xmlDoc.CreateElement("ViewFields")

        Dim queryOptions As System.Xml.XmlElement = xmlDoc.CreateElement("QueryOptions")

 

        'To specify values for the parameter elements (optional), assign CAML fragments to the InnerXml property of each element.*/

        query.InnerXml = QueryCAML()

        viewFields.InnerXml = "<FieldRef Name=""DocIcon"" /><FieldRef Name=""ProgId"" /><FieldRef Name=""FileRef"" /><FieldRef Name=""Public_x0020_Title"" /><FieldRef Name=""Public_x0020_Description"" /><FieldRef Name=""LinkFilename"" /><FieldRef Name=""Modified"" /><FieldRef Name=""Author"" /> "

        queryOptions.InnerXml = ""

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, Nothing)

        nodeListItems.Normalize()

 

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "rs:data" Then

                For Each childNode As System.Xml.XmlNode In node.ChildNodes

                    If childNode.Name = "z:row" Then

                        'For i As Integer = 0 To childNode.Attributes.Count - 1

                        '    strHTML += childNode.Attributes(i).Name & "<br />"

                        'Next

                        Dim strDocIcon As String = childNode.Attributes("ows_DocIcon").Value

                        Dim strLinkFilename As String = childNode.Attributes("ows_LinkFilename").Value

                        Dim strLinkFileRef As String = childNode.Attributes("ows_FileRef").Value.Replace(childNode.Attributes("ows_ProgId").Value, "")

                        Dim strLastModified As String = childNode.Attributes("ows_Modified").Value

                        'CUSTOM FIELD

                        Dim strPublicTitle As String = childNode.Attributes("ows_Public_x0020_Title").Value

                        'CUSTOM FIELD

                        Dim strPublicDescription As String = childNode.Attributes("ows_Public_x0020_Description").Value.Replace(childNode.Attributes("ows_ProgId").Value, "")

                        'Dim strBody As String = childNode.Attributes("ows_Body").Value

                        'strBody = System.Text.RegularExpressions.Regex.Replace(strBody, "<[^>]*>", "")

 

                        Dim ib As ImageButton = New ImageButton()

                        ib.ImageUrl = GetIcon(strDocIcon)

                        ib.CommandArgument = strLinkFilename

                        AddHandler ib.Click, AddressOf ImageButtonGetFile

 

                        Dim lb As LinkButton = New LinkButton()

                        lb.Text = strPublicTitle

                        lb.CommandArgument = strLinkFilename

                        AddHandler lb.Click, AddressOf LinkButtonGetFile

 

                        Me.phDocuments.Controls.Add(ib)

                        Me.phDocuments.Controls.Add(lb)

                        Me.phDocuments.Controls.Add(New HtmlGenericControl("br"))

                    End If

                Next

            End If

        Next

    End Sub

 

    Private Function QueryCAML() As String

        'Use this tool to build the CAML for you http://www.codeplex.com/SPCamlViewer

        Dim oSb As New System.Text.StringBuilder

 

        oSb.Append("         <OrderBy>")

        oSb.Append("              <FieldRef Name=""Public_x0020_Title"" />")

        oSb.Append("         </OrderBy>")

        oSb.Append("         <Where>")

        oSb.Append("              <And>")

        oSb.Append("                   <Eq>")

        oSb.Append("                        <FieldRef Name=""Publicly_x0020_Available"" />")

        oSb.Append("                        <Value Type=""Boolean"">1</Value>")

        oSb.Append("                   </Eq>")

        oSb.Append("                   <Eq>")

        oSb.Append("                        <FieldRef Name=""_ModerationStatus"" />")

        oSb.Append("                        <Value Type=""ModStat"">Approved</Value>")

        oSb.Append("                   </Eq>")

        oSb.Append("              </And>")

        oSb.Append("         </Where>")

 

        Return oSb.ToString()

    End Function

 

    Private Sub ImageButtonGetFile(ByVal sender As Object, ByVal e As ImageClickEventArgs)

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE DOCUMENT LIBRARY

        Dim ib As ImageButton = CType(sender, ImageButton)

        GetFile(ib.CommandArgument)

    End Sub

 

    Private Sub LinkButtonGetFile(ByVal sender As Object, ByVal e As EventArgs)

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE DOCUMENT LIBRARY

        Dim lb As LinkButton = CType(sender, LinkButton)

        GetFile(lb.CommandArgument)

    End Sub

 

    Private Sub GetFile(ByVal strFileName As String)

 

        Dim strURI As String = String.Format("http://{0}/{1}/{2}", FileServer, DocumentLibrary, strFileName)

        Dim request As WebRequest = WebRequest.Create(New Uri(strURI))

 

        request.Credentials = networkCredential

        Dim webResponse As WebResponse = request.GetResponse()

        Dim webStream As Stream = webResponse.GetResponseStream()

 

        System.Web.HttpContext.Current.Response.ClearHeaders()

        System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"

        System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName)

 

        Dim binaryReader As BinaryReader = New BinaryReader(webStream)

        Dim buffer As Byte() = binaryReader.ReadBytes(webResponse.ContentLength)

        System.Web.HttpContext.Current.Response.OutputStream.Write(buffer, 0, webResponse.ContentLength)

        System.Web.HttpContext.Current.Response.Flush()

 

        webResponse.Close()

        webStream.Close()

 

    End Sub

 

    Private Function GetIcon(ByVal strDocIcon As String) As String

        'THIS IS JUST FOR FANCY DISPLAY

        Dim imgLocation As String = ""

        Select Case strDocIcon

            Case "doc", "rtf", "wps", "txt", "docx", "dot"

                imgLocation = "~/images/word.png"

            Case "xls", "csv", ".xlw", "xlt", "xlsx"

                imgLocation = "~/images/excel.png"

            Case "ppt", "pptx"

                imgLocation = "~/images/powerpoint.png"

            Case "pdf"

                imgLocation = "~/images/pdf.png"

            Case "zip", "rar", "gzip"

                imgLocation = "~/images/zip.png"

            Case Else

                imgLocation = "~/images/default.png"

        End Select

        Return imgLocation

    End Function

 

    Function GetListID(ByVal strListName As String) As String

        Dim strListID As String = ""

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.*/

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListCollection()

        nodeListItems.Normalize()

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "List" AndAlso node.Attributes("Title").Value = strListName Then

                strListID = node.Attributes("ID").Value

                Exit For

            End If

        Next

        Return strListID

    End Function

 

    Function GetListName(ByVal strListID As String) As String

        Dim strListName As String = ""

        'THE USER CREDENTIALS HERE SHOULD HAVE READ ONLY ACCESS ACCROSS THE LIST LIBRARY

 

        'Declare and initialize a variable for the Lists Web service

        Dim listService As MOSS.Lists = New MOSS.Lists()

 

        'Authenticate the current user by passing their default

        'credentials to the Web service from the system credential cache.

 

        listService.Credentials = networkCredential

 

        'Set the Url property of the service for the path to a subsite.

        listService.Url = String.Format("http://{0}/_vti_bin/Lists.asmx", FileServer)

 

        ' Instantiate an XmlDocument object

        Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()

 

 

        ' Declare an XmlNode object and initialize it with the XML response from the GetListItems method. The last parameter specifies the GUID of the Web site containing the list. Setting it to null causes the Web site specified by the Url property to be used.*/

        Dim nodeListItems As System.Xml.XmlNode = listService.GetListCollection()

        nodeListItems.Normalize()

        For Each node As System.Xml.XmlNode In nodeListItems

            If node.Name = "List" AndAlso node.Attributes("ID").Value = strListID Then

                strListName = node.Attributes("Title").Value

                Exit For

            End If

        Next

        Return strListName

    End Function

 

End Class


    <div>

        <pcoe:SPDocuments ID="SPDocuments1" runat="server" FileServer="<SERVER NAME>/<SITE NAME>" DocumentLibrary="<DOC LIB NAME>" />

    </div>


Like I said this is only a POC I created to demostrate how it can be done. I am sure there are several ways to achomplish the same task. I would be interested in hearing them.

No Comments