Showing posts with label API. Show all posts
Showing posts with label API. Show all posts

Friday, February 6, 2009

SharePoint API: A Client-side Object Model - Demo Application

Back in November we released HubKey's Client-side API for SharePoint. This API wraps many of SharePoint Server 2007's Web Services (Lists Web Service, Webs Web Service, etc.) to provide a familiar object model that can be used on remote client machines without having to process XML requests and responses.

We've recently made a few updates and have included a demonstration application which is shown running in the screen capture below. This demo app creates a new list on a remote test site with a quick launch link, creates a "test person" list scoped content type, adds a number of randomly generated people records, and then adds a new default view with a custom query returning people below age 65. This list data is then browsable and editable by a DataGridView hosted in a Windows form. In addition, paging is demonstrated by using the SPListItemCollectionPosition object.

You can download a demo copy of the API - click here for details.

Monday, December 22, 2008

Get Distinct Lookup Values

Here's another code example using HubKey's Client-side API for SharePoint. In this case 2 lists are created, a document library and a generic list. A lookup field (Subject) is added to the document library which looks up values in the Title column on the second list. The example also demonstrates getting distinct rows (in this case lookup values) by using the DataView.ToTable() method.

using System;
using System.Collections.Generic;
using System.Text;
// using HubKey's Remote SharePoint API instead of the native object model so we can update a remote server
using HubKey.Web.Services.SharePoint;
//using Microsoft.SharePoint;
using System.Data;
 
namespace DevHoleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //always use a test server and site with this beta API
            SPWeb web = new SPSite("http://remoteserver/testsite001/").OpenWeb();
 
            Guid subjectsListId = web.Lists.Add("HubKey Subjects", "A temporary list.", SPListTemplateType.GenericList);
            SPList subjectsList = web.Lists[subjectsListId];
 
            // note that using the SPList.Items property here with the HubKey API returns all the items in the list
            // which can be expensive if the list contains many items already. See the following code example for a 
            // better way to add items to a list specific to the HubKey API:
            // http://www.hubkey.com/Documents/HubKeySPAPI/html/60759825-9963-20e4-c31e-ae93ea608330.htm
            SPListItemCollection subjects = subjectsList.Items;
 
            SPListItem item1 = subjects.Add();
            item1["Title"] = "SharePoint";
            item1.Update();
 
            SPListItem item2 = subjects.Add();
            item2["Title"] = "Microsoft CRM";
            item2.Update();
 
            SPListItem item3 = subjects.Add();
            item3["Title"] = "Microsoft CRM";
            item3.Update();
 
            Guid booksDocLibId = web.Lists.Add("HubKey Books", "A temporary document library.", SPListTemplateType.DocumentLibrary);
            SPList booksDocLib = web.Lists[booksDocLibId];
 
            booksDocLib.Fields.AddLookup("Subject", subjectsListId, false);
            booksDocLib.Update();
            SPFieldLookup subjectLookup = new SPFieldLookup(booksDocLib.Fields, "Subject");
            subjectLookup.LookupField = "Title";
            subjectLookup.Update();
 
            // build the query to get a list of subjects
            // (pretend we are starting from scratch)
            SPFieldLookup subjectLookup2 = (SPFieldLookup)booksDocLib.Fields["Subject"];
            SPList subjectsList2 = web.Lists[new Guid(subjectLookup2.LookupList)];
 
            SPQuery query = new SPQuery();
            query.ViewFields = "<FieldRef Name='" + subjectLookup2.LookupField + "'/>";
 
            // here we use a data table so that we can get distinct titles (subjects)
            // if you're not woried about distinct values you could ignore this, but it's
            // also a convenient way to query the list items (e.g. see the RowFilter below)
            DataTable subjectsTable = subjectsList2.GetItems(query).GetDataTable();
 
            DataView dataView = new DataView(subjectsTable);
            DataTable groupedSubjectsTable = dataView.ToTable(true, "Title");
 
            SPFieldLookupValue lookupValue = null;
 
            // here we're looping through 2 distinct title rows ('SharePoint' and 'Microsoft CRM')
            foreach (DataRow row in groupedSubjectsTable.Rows)
            {
                string title = (string)row[0];
 
                // get the ID of the first row that matches the title
                dataView.RowFilter = "Title = '" + title + "'";
                int firstId = (int)dataView.ToTable(true, "ID").Rows[0][0];
 
                // create a new lookup value (we'll use the 2nd row's lookupValue below)
                lookupValue = new SPFieldLookupValue(string.Format("{0};#{1}", firstId, title));
            }
 
            SPFile file = booksDocLib.RootFolder.Files.Add("test.txt", Encoding.ASCII.GetBytes("A test document."));
 
            // update the subject with the 2nd lookup value;
            file.Item["Subject"] = lookupValue;
            file.Item.Update();
 
            // clean up - pause here if you want to view the results on the server.
            subjectsList.Delete();
            booksDocLib.Delete();
 
        }
    }
}

Wednesday, November 26, 2008

SharePoint API: A Client-side Object Model

One common issue (see question #2) that developers using Microsoft's SharePoint platform are faced with is that the SharePoint object model can only be used when the application is run on a server in the SharePoint farm.

The following is code that demonstrates using HubKey's Client-side API for SharePoint. This API wraps many of SharePoint Server 2007's Web Services (Lists Web Service, Webs Web Service, etc.) to provide a familiar object model that can be used on remote client machines without having to process XML requests and responses. In this case the code from the MSDN article How to: Upload a File to a SharePoint Site from a Local Folder was copied verbatim, and it compiles and runs successfully on a client computer, even though the SharePoint DLLs are not referenced or installed.

Update: You can download a demo copy of the API - click here for information.

Update II: The API now includes a demo application - see this post for details.



using System;
using System.IO;
// Using HubKey.Web.Services.SharePoint in place of Microsoft.SharePoint
using HubKey.Web.Services.SharePoint;
 
namespace HubKey.DevelopmentHole
{
    class Program
    {
        static void Main(string[] args)
        {
            Program program = new Program();
            program.RunDemo();
        }
 
        public void RunDemo()
        {
            string webUrl = "http://remoteserver";
            SPSite site = new SPSite(webUrl);
            SPWeb web = site.OpenWeb();
 
            //create a new document library
            Guid id = web.Lists.Add("Temp Doc Lib", "A temp document library.", SPListTemplateType.DocumentLibrary);
            SPList list = web.Lists[id];
 
            //add a field
            list.Fields.Add("Upload Source", SPFieldType.Text, false);
            list.Update();
 
            string fileUrl = webUrl + "/Temp Doc Lib/New Folder/test.txt";
            string localFileName = @"D:\Temp\test.txt";
 
            string localFileContents = "A temp file uploaded by HubKey's SharePoint client-side API.";
 
            File.WriteAllText(localFileName, localFileContents);
 
            //Upload the file using the API code from 'How to: Upload a File to a SharePoint Site from a Local Folder'
            //see http://msdn.microsoft.com/en-us/library/ms454491.aspx
            UploadFile(localFileName, fileUrl);
 
            //Check out
            SPFile file = web.GetFile(fileUrl);
            file.CheckOut();
 
            //update the title and new upload source field by using the file's SPListItem property...
            file.Item["Title"] = "A temp title";
            file.Item["Upload Source"] = "HubKey's SharePoint client-side API.";
            file.Item.Update();
 
            //Check in
            file.CheckIn("Checked in by HubKey's SharePoint client-side API");
 
            //Get the file contents
            string serverFileContents = web.GetFileAsString(fileUrl);
            System.Diagnostics.Debug.Assert(string.Equals(localFileContents, serverFileContents));
 
            //Tidy up
            list.Delete();
        }
 
        public void UploadFile(string srcUrl, string destUrl)
        {
            if (!File.Exists(srcUrl))
            {
                throw new ArgumentException(String.Format("{0} does not exist",
                    srcUrl), "srcUrl");
            }
 
            SPWeb site = new SPSite(destUrl).OpenWeb();
 
            FileStream fStream = File.OpenRead(srcUrl);
            byte[] contents = new byte[fStream.Length];
            fStream.Read(contents, 0, (int)fStream.Length);
            fStream.Close();
 
            EnsureParentFolder(site, destUrl);
            SPFile file = site.Files.Add(destUrl, contents);
            SPFolder folder = file.ParentFolder;
        }
 
        public string EnsureParentFolder(SPWeb parentSite, string destinUrl)
        {
            destinUrl = parentSite.GetFile(destinUrl).Url;
 
            int index = destinUrl.LastIndexOf("/");
            string parentFolderUrl = string.Empty;
 
            if (index > -1)
            {
                parentFolderUrl = destinUrl.Substring(0, index);
 
                SPFolder parentFolder
                    = parentSite.GetFolder(parentFolderUrl);
 
                if (!parentFolder.Exists)
                {
                    SPFolder currentFolder = parentSite.RootFolder;
 
                    foreach (string folder in parentFolderUrl.Split('/'))
                    {
                        currentFolder = currentFolder.SubFolders.Add(folder);
                    }
                }
            }
            return parentFolderUrl;
        }
    }
}