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 :)


Tuesday, September 14, 2010

iOS 4.1 development

I'm currently picking up a little on Objective-C to do some iOS development, for school project though. Since i have a MacBook (late 2009), apple developer account (free) and iPhone 3GS, it should not be that hard.. (i assumed)

I had very little C and C++ experience and knowledge, i'm just a hello world-level developer for both languages. That didn't stop me from downloading the 2.9 GB Xcode IDE and iOS4.1 SDK and try to write my first Hello World.

Followed a few guides like this and this, it wasn't that hard to print a hello world using the Interface Builder:
Just follow the guides step-by-step and try to grasp a few of the IDE (which is rather different from Visual Studio, NetBeans & SharePoint Designer)





After messing around with a few UIKit controls, i met a problem of not able to retract the keyboard on the simulator. Went around some forums and found that Apple gave a very good tutorial: UICatalog, which included most, if not all of the controls available in the API.

However, when i loaded the xcodeproj file, the compiler keep giving me the message: "Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain"
You can bring the build results up by pressing: command+shift+B










After a few attempts to search around the net for the solution, many suggested setting up Keychain Access (windows equivalent of the certificate manager) so that you have Apple Worldwide Developer Relations Certification, and the iPhone developer certificate, iPhone distributor certificate (if you want to put apps into iTunes), there are lots of things to do and pay (for distributing), but hey, i'm just trying to mess around with iOS 4.1, i'm not yet ready to go through all these.

I tried to set the code signing options under the project settings, but it still doesn't let me compile and run the simulator. Then for no reason, i looked at the build results window and saw that the build option was targetted for "device" instead of "simulator". I didn't change it to device (which requires you to do the above certificate signing set-up), it was the default setting, i changed it to "Simulator" then pressed command+B and everything went well, finally.

I'll be messing around more with Xcode and hope to be able to produce something and decide if i'll sign up for a distributor package with Apple @ US$99/yr. Stay tuned.