It seems like everything I work on these days is new technology and I guess there’s not a lot of love out there for VB.Net programmers. I spend a lot of time looking for code and it’s always in C# which I have to convert and the converters don’t always get it right. I know I’m not alone in this based on the number of updates a day I have to download to keep my third party software up to date.
So, my VB.Net brothers and sisters, if you’ve been trying to get a handle on uploading a document from your local machine through DotNetNuke to SharePoint using the SharePoint Copy Web Service, well, this is your lucky post.
Recently, I had to build an interface in DotNetNuke to upload files and save them in the SharePoint environment. To accomplish this we used the Users and Roles from DotNetNuke, an authorization cookie, and the SharePoint Copy Service. I was able to cobble together code from demo sites, but it was all in C#. I’ve done the conversion to VB.Net for you. Enjoy!
Prerequisites:
You’ve already built, or know how to build, a custom module and put the File Upload control on the page.
You’ve already set up your SharePoint site to use DotNetNuke security and Forms authentication.
For the sake of this project add the following controls to your page:
1. FileUpload; ID=fUpload
2. Button; ID=btnUpload, Text=”Upload”
3. Label; ID=lblErr
Part 1: Add the Web Service and Authentication Service
The services should be added as a Web References (not a References, or a Service References)
The authenication service will be located at http://{your SharePoint domain}//_vti_bin/Authentication.asmx. When naming the service use your own naming conventions, but for this demo it’s called “AuthSvc”. See the AuthenticateFBASite function in step 4.
The copy service will be located at http://{your SharePoint domain}//_vti_bin/Copy.asmx. When naming the service use your own naming conventions, but for this demo it’s called “CopySvc”. See the UploadService function in step 5.
Part 2: Upload the File to the Web Server
You don’t simply upload the file directly to SharePoint. The file needs to be saved to the Web Server and then sent to SharePoint.
Create a dump folder, save the file from the Upload control to the dump folder.
Dim mErr as string = "" 'rudimentary error trapping Function UploadDocument() as Boolean 'Gather the username and password from DotNetNuke Dim UserName = UserInfo.Username Dim objUser As MembershipUser objUser = Membership.GetUser(UserInfo.Username) Password = objUser.GetPassword() 'Set up the document variables Dim fDocName As String = "" Dim fDocExt As String = "" Dim fsourceURL As String = "" Dim fdumpFolder as string = "http://webdomain/subfolder/" 'DotNetNuke Domain 'Share Point Folder Path Dim fFolderPath as string = "/YourSharePointLibraryName/SubFolder/ Try If fUpload.HasFile Then fDocName = System.IO.Path.GetFileNameWithoutExtension(fUpload.FileName).ToString fDocExt = System.IO.Path.GetExtension(fUpload.FileName).ToString fsourceURL = Server.MapPath(fdumpFolder & fDocName & fDocExt) fUpload.SaveAs(sourceURL) 'Upload to SharePoint Code Goes Here If Not UploadToSharePoint({SharePoint Domain}, UserName, Password, fsourceURL, fFolderPath & "/" & fDocName & fDocExt) Then Throw New Exception(mErr) Else 'Successful move to SharePoint. Delete temp file If System.IO.File.Exists(sourceURL) Then System.IO.File.Delete(sourceURL) End If End If Catch ex as Exception 'report the error to your page End Try End Function
3. Establish Authentication and Call the SharePoint Upload Service
Public Function UploadToSharePoint(siteURL As String, UserName As String, Password As String, docSourceURL As String, docDestinationFolder As String) As Boolean Try ' Call Auth Service And Get Cookie to autheticate Dim myAuthCookie As Cookie Dim myNetworkCredentials As New NetworkCredential() myAuthCookie = AuthenticateFBASite(siteURL, UserName, Password, myNetworkCredentials) ' Use Auth Cookie to call List Service Dim myCopySvcResponse As Boolean myCopySvcResponse = UploadService(myAuthCookie, docSourceURL, {siteURL & docDestinationFolder}) If myCopySvcResponse > 0 Then Throw New Exception(ControllerError) Return True Catch ex As Exception mErr = "Upload Document error: " & ex.Message Return False End Try End Function
4. Authentication
Private Function AuthenticateFBASite(AuthenticationSiteURL As String, UserName As String, Password As String, Credential As NetworkCredential) As Cookie Dim CurrentSiteCookie As Cookie = Nothing Using authSvc As New AuthSvc.Authentication() authSvc.Url = AuthenticationSiteURL + "/_vti_bin/authentication.asmx" 'Create A New Cookie Container authSvc.CookieContainer = New System.Net.CookieContainer() ' Set the FBA Login Information authSvc.AllowAutoRedirect = True authSvc.PreAuthenticate = True authSvc.Credentials = Credential Dim result As AuthSvc.LoginResult result = authSvc.Login(UserName, Password) If result.ErrorCode = Pierson.SharePoint.AuthSvc.LoginErrorCode.NoError Then Try Dim cookies As New CookieCollection() cookies = authSvc.CookieContainer.GetCookies(New Uri(AuthenticationSiteURL)) CurrentSiteCookie = cookies(result.CookieName) Return CurrentSiteCookie Catch ex As Exception Return CurrentSiteCookie End Try ElseIf result.ErrorCode = SharePoint.AuthSvc.LoginErrorCode.PasswordNotMatch Then Return CurrentSiteCookie Else Return CurrentSiteCookie End If End Using End Function
5. Upload to SharePoint
Public Function UploadService(ByVal Cookie As Cookie, copySource As String, copyDest As String(), fileError As String) As Int32 ', fileBytes As Byte(), destinationMapPath As String Try Dim fErr As String = "" Dim fDocName As String = "" 'no extension Dim fDocExt As String = "" 'Create Instance Of Lit Service Dim myCopyService As New CopySvc.Copy() 'Create Cookie Container myCopyService.CookieContainer = New CookieContainer() ' Add Authentication Cookie to Container myCopyService.CookieContainer.Add(Cookie) Dim FirstResult As CopySvc.CopyResult = New CopySvc.CopyResult() Dim SecondResult As CopySvc.CopyResult = New CopySvc.CopyResult() Dim copyResultArray As CopySvc.CopyResult() = {FirstResult, SecondResult} Dim fieldInfo As CopySvc.FieldInformation = New CopySvc.FieldInformation() fieldInfo.DisplayName = "Description" fieldInfo.Type = CopySvc.FieldType.Text fieldInfo.Value = copySource Dim fieldInfoArray As CopySvc.FieldInformation() = {fieldInfo} Dim objStream As FileStream = New FileStream(copySource, FileMode.Open, FileAccess.Read) Dim Contents As Byte() = New [Byte](objStream.Length - 1) {} Dim r As Byte() = New [Byte](objStream.Length - 1) {} Dim Read As Integer = objStream.Read(Contents, 0, Convert.ToInt32(objStream.Length)) Dim copyresult As UInteger = myCopyService.CopyIntoItems(copySource, copyDest, fieldInfoArray, Contents, copyResultArray) Return copyresult Catch ex As Exception mErr = "Upload Service error: " & ex.Message Return False End Try End Function
That should get you most of the way there. If you find a bug, drop me a line in the comments.
2 comments for “The SharePoint Copy Service, DotNetNuke, and VB Haters”