Wednesday, September 22, 2010

upload file into sharepoint 2007 (copy.asmx)

There are many ways to do it:

  1. Customised web services
  2. Out-of-the-box web service (copy.asmx)
  3. WebDAV
Advantages of using Customised web services:
  • Ease of uploading (through personalised codes)
  • Ability to do many fine tuning (such as permissions, etc)
Disadvantages of using Customised web services:
  • Not all SharePoint owners are comfortable with customised webservices running on their server
Advantages of using Out-of-the-box web service (copy.asmx):
  • Using Microsoft "supported" API
  • No need to fear if the next service pack is going to screw up all the pre-patch programs
Disadvantages of using Out-of-the-box web service (copy.asmx):
  • Limited No way to set permissions of files
Advantages of using WebDAV:
  • Very easy to implement
Disadvantages of using WebDAV:
  • Unable to set any metadata
I had a recent job to do a migration from File System -> SharePoint Document Library. A short summary of what happened: 

I was told to migrate everything over with the same file names, permissions, taxonomy (folder structures), etc.

Initially, i chose to use SharePoint OOTB web service to do all the above, as i know that i can use it to create folders, upload items, set metadata, etc. Until i hit a problem: I can't fricking set the permissions. After a lot of negotiation with my stakeholders, there's only 2 choice for me (without breaching their microsoft gold support clauses). Deploy a customized web service written by me or skip the whole permission idea (they have to do it manually using cheap interns). Lucky for me, they chose to skip the permission thing, so i proceed to continue with the whole project with user-friendly user interface using just the Web Service of SharePoint. Another advantage of using it is, you can use it anywhere as long as you can achieve a connection to the SharePoint and File System, you do not need to be running on either servers.

I am still tweaking the project source codes for some eye candies before my next new assignment begins.

And for the copy.asmx to be consumed, you only have to do this:

public string UploadFile(string sourceFilePath, string destinationUrl)
{
            string msg = string.Empty;
            Copy c = new Copy(); 
            c.Url = this.spURL + "/_vti_bin/copy.asmx";
            Authenticate(c);

            byte[] myBinary = File.ReadAllBytes(sourceFilePath); 
            string[] destinationUrlColl = { destinationUrl };

            FieldInformation info1 = new FieldInformation(); 
            info1.DisplayName = "Title"; 
            info1.InternalName = "Title"; 
            info1.Type = FieldType.Text; 
            info1.Value = "new title"; 

            FieldInformation[] info = { info1 }; 
            CopyResult resultTest = new CopyResult(); 
            CopyResult[] result = { resultTest }; 

            try 
            { 
                //When creating new content use the same URL in the SourceURI as in the Destination URL argument

                c.CopyIntoItems(destinationUrl, destinationUrlColl, info, myBinary, out result); 
                 if (result[0].ErrorMessage != null)
                 {
                     msg = "Error: " + result[0].ErrorMessage;
                 }
                 else
                 {
                     msg = "Success";
                 }
            } 
            catch (Exception ex) 
            { 
                //TODO: logging & handling
            }
            return msg;
}

I written a simple authentication method to do the authentication properly -> Authenticate(c);

internal CookieContainer AuthenticateFBA()
        {
            CookieContainer cookies = new CookieContainer();
            using (GSPAuthenticationWS.Authentication authSvc = new GSPAuthenticationWS.Authentication())
            {
                authSvc.Url = this.spURL + "/_vti_bin/authentication.asmx";
                authSvc.CookieContainer = new System.Net.CookieContainer();     //create a new cookie container
                authSvc.AllowAutoRedirect = true;

                //set the FBA login information
                try
                {
                    GSPAuthenticationWS.LoginResult result = authSvc.Login(this.spAdminId, this.spAdminPw);
                    if (result.ErrorCode == GSPAuthenticationWS.LoginErrorCode.NoError)
                    {
                        CookieCollection cookieColl = authSvc.CookieContainer.GetCookies(new Uri(authSvc.Url));
                        //Get the specific cookie which contains the security token
                        cookies.Add(cookieColl[result.CookieName]);
                    }
                }
                catch (WebException wex)
                {
                    throw new NotImplementedException("Specified Sharepoint server is not FBA-enabled");
                }
                return cookies;
            }
        }

        internal NetworkCredential AuthenticateIWA()
        {
            return new NetworkCredential(this.spAdminId, this.spAdminPw, this.spAdminDomain);
        }

        private void Authenticate(SoapHttpClientProtocol SoapProtocol)
        {
            if (this.isFBAEnabled)
            {
                SoapProtocol.CookieContainer = AuthenticateFBA();
            }
            else
            {
                ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
                ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                {
                    //Here we can write code for implementing client side validation.
                    // This anonymous function is a call back function which is called once the SSL validation completes on WebServer.
                    return true;
                };
                SoapProtocol.Credentials = AuthenticateIWA();
            }
        }

A neat way to authenticate through the web service for both Form Based authentication and Integrated Windows authentication :)


1 comment:

  1. An update: visit http://gspmigrator.codeplex.com, I've released the source code of a win app to do migration

    ReplyDelete