WHAT YOU WILL LEARN IN THIS CHAPTER
You can do the activities in this chapter with either JavaScript or Silverlight, with the exception of querying the SharePoint Client Object Model using LINQ to Objects. LINQ is only supported in Silverlight via LINQ to Objects. LINQ to SharePoint is only supported with the Server Object Model.
Silverlight gives you the ability to build applications rich with functionality and usability far beyond what is possible in JavaScript alone. With Silverlight, you can create C# and VB.Net applications that run in the browser as part of your SharePoint site. Like JavaScript, Silverlight has its own libraries for accessing SharePoint via the Client Object Model. Whether you are using JavaScript or Silverlight, they both communicate with SharePoint via the client.svc web service. The URL for this web service is located at http://yoursiteurl_vti_bin/client.svc
where yoursiteurl
is the URL of your SharePoint site.
One of the advantages of the Client Object Model is that you can supplement the functionality of the sandbox solutions in SharePoint. In some environments, developers do not need or are restricted from using certain, possibly-unsafe functionality in their SharePoint code. SharePoint addresses these problems by providing a "sandbox" inside which a developer's code can run. This sandbox runs outside of the main SharePoint web application and protects the web site from being unavailable if the developer's code crashes or uses too many server resources. To safely circumvent some of the restrictions of sandbox solutions, you could include JavaScript or Silverlight code that uses the Client Object Model.
Another reason to use Silverlight is its ability to process and display large amounts of data on the screen, and generally, it performs faster than JavaScript. The real trade-off is your ramp-up time to become proficient in Silverlight versus using the JavaScript experience you already have. Now that you have a good understanding of some of the issues and opportunities around using Silverlight inside SharePoint, continue to the next section to get started.
Before you jump in and get busy with Silverlight, you must install a few things:
Microsoft Silverlight 4 Tools for Visual Studio 2010 http://www.microsoft.com/downloads/details.aspx?FamilyID=40ef0f31-cb95-426d-9ce0-00dcfabf3df5
Silverlight Toolkit http://silverlight.codeplex.com—contains
many useful, free controls for your Silverlight projects.
If you are new to Silverlight development, visit www.silverlight.net/getstarted/
for videos, tutorials, and other resources to get you up and running quickly.
The Silverlight.net website has many free samples, examples, and tutorials available for your use. If you do not have much experience with Silverlight, doing the tutorials on the website before continuing further in the chapter would be a good idea.
After you have installed the requisite software, the last thing you need is the Silverlight Client Object Model, which is contained in these two files:
Microsoft.SharePoint.Client.Silverlight.dll
Microsoft.SharePoint.Client.Silverlight.Runtime.dll
These files are located on your SharePoint server at C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTSClientBin
. Copy these files to your local machine because you will need to use them in your Silverlight projects.
To create a new Silverlight application, follow these steps:
Open Visual Studio 2010 from your Start menu, and select File
Depending on which settings you chose when you first opened Visual Studio, your New Project dialog may look different from the one shown in Figure 14-1.
Select Silverlight from the templates on the left, and select Silverlight Application from the list of projects.
Enter a name for your project and click the OK button. The New Silverlight Application dialog shown in Figure 14-2 appears.
Uncheck the "Host the Silverlight application in a new Web Site" checkbox and ensure Silverlight 4 is selected in the Silverlight Version drop-down list. Click the OK button.
If you get the message "An update to Microsoft Visual Studio is required to target Silverlight 4" when the project opens, make sure you have installed Microsoft Silverlight 4 Tools for Visual Studio 2010.
After the project is created, the screen shown in Figure 14-3 appears. Notice the Toolbox pane containing the available Silverlight controls on the left side of the screen. Depending on whether you installed the Silverlight Toolkit or controls from a third-party vendor, you may have more or fewer controls.
On the right side of the screen, you see the Solution Explorer pane, which contains the files in the Silverlight project. Underneath the Solution Explorer pane, the Properties pane shows you the properties of the object you have selected in the IDE. When designing controls in Silverlight, you use the Properties pane to configure the controls you use in the project.
The center of the screen contains the Error List pane at the bottom and the design area at the top. The Error List pane displays any errors, warnings, or messages from Visual Studio while you write code and whenever you compile the project. The design area displays the documents you have open. When you open an XAML file, the design area is split into two sections: the WYSIWYG (What You See Is What You Get) designer and the text editor containing the corresponding XML. In the WYSIWYG designer, the Silverlight screens you design in Visual Studio will look the same as when they run in the browser.
Whenever you want to test your code, you must compile it and deploy it to a SharePoint document library. To compile your project, select Build
When you compile a Silverlight application project, it creates an XAP file, which contains the code and resources of your project. Any zip file–compatible application can open this XAP file.
The location of the XAP file is located in the BinDebug
or BinRelease
folder under the folder where your project is located. If you chose to compile your code in Debug mode, your XAP file will be in the BinDebug
folder. Otherwise, it will be in the BinRelease
folder.
If you compile the project in Debug mode, you can attach Visual Studio to your project and debug the project. The drawback of Debug mode is that the XAP file will be much larger and the code will run slower due to the inclusion of the information Visual Studio needs to allow you to debug your code. When you are satisfied with your project, compile the project in Release mode before you deploy it to production.
You can easily get the location of the XAP file by clicking the Show All Files button in the toolbar of the Solution Explorer pane. The Bin
folder will appear, and you can navigate to the XAP file. When you select the XAP file, the Properties pane displays the full path to the file. Copy this path to paste into the upload file dialog in SharePoint.
After you have uploaded the XAP file to a document library in your site, you must add your Silverlight control to a web page. SharePoint has a convenient way to display Silverlight controls: the Silverlight Web Part. The Silverlight Web Part allows you to add your Silverlight control to any web part page. To add the Silverlight Web Part to a page, follow these steps:
Navigate to a web part page in your site and select Edit Page from the Site Actions menu to put the page in Edit mode.
Select Web Part from the Insert tab on the ribbon. The web part catalog appears, as shown in Figure 14-4.
Choose Media and Content from the Categories list and select Silverlight Web Part from the Web Parts list.
Select the appropriate location from the Add Web Part To drop-down list and click the Add button. The Silverlight Web Part dialog shown in Figure 14-5 appears.
Enter the URL to the XAP file you uploaded earlier and click the OK button. After the web part is added, a page similar to the one shown in Figure 14-6 appears. By default, the web part has a height of 300 pixels and a width of 400 pixels. If your web part is larger than these dimensions, edit the web part's properties and adjust accordingly.
If your Silverlight application needs initialization parameters configured, you can scroll to the bottom of the web part properties window and put them in the Custom Initialization parameters textbox, shown in Figure 14-7.
Every now and then, you may need to debug your Silverlight code. You cannot just run your Silverlight project by choosing Debug
Deploy your XAP file to a document library and add it to a web part page as shown previously in the chapter.
Select Debug
Choose the "Debug these code types" radio button and ensure that only Silverlight is selected in the list box. This makes Visual Studio load fewer debug symbol files after you attach to your browser.
Click OK to return to the Attach to Process dialog shown in Figure 14-8. In the Available Processes list box, select all the processes for your browser where Silverlight is listed in the Type column. If you are using Internet Explorer, look for processes named iexplore.exe. If you are using Firefox, look for processes named firefox.exe.
Click the Attach button. You are ready to debug.
The code you write to retrieve data in Silverlight is almost the same as the code you write in JavaScript. The main difference is that in JavaScript, you must access the properties of an object by calling set_propertyname
and get_propertyname
styled methods. In Silverlight, you only need to use the name of the property itself.
As in JavaScript, you must get an instance of the ClientContext
class before you can do anything with the Client Object Model. To get the current ClientContext
object, call the Current
property of the ClientContext
class:
ClientContext context = ClientContext.Current;
If you want to get a different ClientContext
object, you can use the following code snippet, supplying the full URL of the site:
ClientContext context = new ClientContext(fullsiteurl
);
After you get the ClientContext
object, you can use the following methods and properties:
You may notice that the names of all properties and methods in the Silverlight Client Object Model are proper cased. One interesting feature of the Client Object Model in Silverlight is that you can use LINQ in a very limited manner to query lists and libraries. Without LINQ, you would write the following code snippet to query the Tasks list:
ClientContext context = ClientContext.Current; Web site = context.Web; List tasks = site.Lists.GetByTitle("MyTasks"); this.items = tasks.GetItems(new CamlQuery()); context.Load(this.items); context.ExecuteQueryAsync(OnSuccess, OnFailure);
You get the list and call the GetItems
method, passing in an instance of the CamlQuery
class. Notice that a blank CamlQuery
class was passed into the method. That just means that SharePoint will return all items from the list. With LINQ, you could write the following code snippet instead:
ClientContext context = ClientContext.Current; Web site = context.Web; this.tasks = site.Lists.GetByTitle("MyTasks"); ListItemCollection items = tasks.GetItems(new CamlQuery());var query = from t in items
select t;
this.results = context.LoadQuery(query); context.ExecuteQueryAsync(OnSuccess, OnFailure);
In the code snippet, the LINQ query is highlighted. Essentially, it creates a query that returns all the items in the list. You could add a filter to the query based on one of the built-in properties of the ListItem
class. You cannot add a filter on one of the columns in the list, though. Here is an example of using LINQ to return the item whose ID equals 5:
var query = from t in items where t.Id == 5 select t;
After you get your results back from SharePoint, you may be tempted to bind the list of ListItem
objects directly to a control like the DataGrid control. That will not work because the list item's field values are actually stored in the ListItem
's default property, which is actually a Dictionary
object. You cannot bind to a Dictionary
object, but you can convert it to something else using LINQ.
To bind to your list items, create a class with similar properties and data types as their parent list. Here is an example for a few columns from a Task list:
public class Task { public int Id { get; set; } public string Title { get; set; } public string Status { get; set; } public string Priority { get; set; } }
With the Task
class, you can use LINQ to convert the ListItem
objects to Task objects, which you can bind to a control such as the DataGrid control. The following code snippet shows this in action:
var data = from t in this.results select new Task { Id = t.Id, Title = (string)t.FieldValues["Title"], Status = (string)t.FieldValues["Status"], Priority = (string)t.FieldValues["Priority"] }; dataGrid1.ItemsSource = data;
One additional caveat is that Silverlight is multi-threaded, which is great for performance, but it requires you to add some additional code before you can bind your data. All controls in the UI run on the main thread, which is the first thread created when the application starts. When you call SharePoint, the Client Object Model creates a background thread to send the request to SharePoint and wait for a response. After the call succeeds or fails, the corresponding method you passed to the ExecuteQueryAsync
method of the ClientContext
class executes. The execution occurs on the background thread instead of the main UI thread, and you cannot update the UI from a background thread.
To resolve this problem, you can use a control's Dispatcher
property to execute your code and update the UI. The Dispatcher
will run the code you give it on the main UI thread. The Dispatcher
class has the BeginInvoke
method you use to supply the code to execute. You only need to give it the name of a method in your class or an anonymous method. Delivering your code via an anonymous method is faster because you can add your code on the spot instead of creating a new method and passing the method to the BeginInvoke
method. The following code snippet shows using an anonymous method with the Dispatcher
property:
dataGrid1.Dispatcher.BeginInvoke(delegate() { var data = from t in this.results select new Task { Id = t.Id, Title = (string)t.FieldValues["Title"],
Status = (string)t.FieldValues["Status"], Priority = (string)t.FieldValues["Priority"] }; dataGrid1.ItemsSource = data; });
In the code snippet, delegate() {}
creates an anonymous method that is passed to the BeginInvoke
method of the Dispatcher
class. You need only place your UI-updating code between the two curly braces. One neat feature of anonymous methods is that you can still access the local variables and parameters of the method containing this code. In the following activity, you use these classes to query a SharePoint list.
The Client Object Model also allows you to create, modify, and delete lists and document libraries in your SharePoint site. To get a list of the lists and libraries in a site, you use the Lists property of the Web class. You can also use LINQ to filter the lists and libraries returned from the site by using the following code snippet:
var query = from l in site.Lists where !l.Hidden select l; this.listResults = context.LoadQuery(query);
In general, avoid displaying hidden lists and libraries to the user because modifying them could irreparably break functionality in your site.
In the code snippet, the Lists
property is filtered for only the lists and libraries that are not hidden in the browser UI. Afterwards, the LINQ query is passed to the LoadQuery
method for retrieval from SharePoint. In the following code snippet, the result of the query from SharePoint is bound directly to a DataGrid control:
listsDataGrid.Dispatcher.BeginInvoke(delegate() { listsDataGrid.ItemsSource = listResults; });
Note that you must still use the Dispatcher
property of a control to update it from the background thread that called your OnSuccess
method. Unlike the ListItem
class, the List
class has many useful properties that you can directly bind to. In the following table, you can see some of the most common properties and methods that you will use when dealing with lists and libraries.
The following table displays commonly used List properties:
NAME | DESCRIPTION |
---|---|
If true, the content types associated with the list or library can be managed via the browser. | |
Indicates which list template was used to create the list. A list of common list template types appears later in the chapter. | |
| The collection of |
When the list or library was created. | |
The description for the list or library. | |
If true, the list supports attaching files to list items. Only applies to lists, not document libraries. | |
If true, users can create folders inside the list or library. | |
The collection of | |
If true, the list is an external list. | |
If true, the list does not appear in the browser. | |
| The GUID identifier of the list. |
The number of items or documents in the list or library. | |
Specifies the last time a list or document was deleted from the list. This is useful for checking if you need to refresh your data from SharePoint. | |
Specifies the last time the list or its contents was modified. This is useful for checking if you need to refresh your data from SharePoint. | |
If true, the list will appear in the Quick Launch bar on the left side of the screen. | |
The root folder of the list. Use this to get the files and folders in a document library. | |
The display name of the list. |
The following table displays commonly used List methods:
NAME | DESCRIPTION |
---|---|
Adds an item to the list. | |
Deletes the list permanently. | |
Gets an item from the list using the item's ID. | |
Gets a collection of items based on the supplied | |
Sends the list to the Recycle Bin. This is what happens when you delete a list via the browser. | |
Saves your changes to the list, which are applied the next time |
To create a new list or library, you use the ListCreationInformation
class. The ListCreationInformation
class has various properties you must populate before passing it to the Add
method on the Lists
collection of the site. At a minimum, you must populate the Title
and TemplateType
properties as shown in the following code snippet:
ListCreationInformation info = new ListCreationInformation(); info.Title = "My New List"; info.TemplateType = (int)ListTemplateType.Tasks; site.Lists.Add(info); context.ExecuteQueryAsync(OnListCreated, OnFailure);
In the code snippet, the new list is named "My New List" and the template type is Tasks. After the ListCreationInformation
object is configured, pass it to the Add
method on the site's Lists
property. After the ExecuteQueryAsync
method is called, SharePoint will create the list. Notice that the TemplateType
property is set to the ListTemplateType.Tasks
enumeration value. You must cast the ListTemplateType
enumeration value to the int
(integer) data type when setting the value of the TemplateType
property. The following table lists the values of the ListTemplateType
enumeration and their descriptions:
NAME |
|
---|---|
Announcements | Announcements |
Calendar | Events |
Contacts | Contacts |
Custom List | GenericList |
Discussion Board | DiscussionBoard |
Document Library | DocumentLibrary |
Form Library | XMLForm |
Issue Tracking | IssueTracking |
Links | Links |
Picture Library | PictureLibrary |
Project Tasks | GanttTasks |
Survey | Survey |
Tasks | Tasks |
Wiki Page Library | WebPageLibrary |
To modify a list or library, you must call the GetByTitle
method of the Lists collection to get the List
object. Afterwards, you can modify the list's properties and call the list's Update
method to save your changes. To delete a list, call the Recycle
method of the list, which sends the list to the Recycle Bin. To permanently delete the list, call the DeleteObject
method instead.
Other than managing the items or documents in a list or library, managing the fields in a list or library will be your most common list-related task. The Fields
property on the List
class returns a collection of field properties that you can use to add new fields, remove fields, or access the properties of the fields themselves. All Field
objects have the following properties and methods:
PROPERTY | |
---|---|
If true, the field can be removed from the list. | |
The default value, if any, for the field. | |
| The description for the field. |
The type of field. There is a list of field types later in the chapter. | |
If true, the field can be used to filter the list. Some fields, including "Multiple lines of text" fields, cannot be used as filters. | |
If true, the field does not appear in the browser UI. | |
| The GUID identifier for the field. |
The original name of the field. The internal name can never be changed after the field is created. | |
If true, the field is read-only. | |
If true, the field cannot be deleted or modified in any way. | |
If true, the field can be used to sort the list. Some fields, including "Multiple lines of text" fields, cannot be used to sort the list. | |
The display name of the field. | |
| The display name for the field's type. |
METHOD | DESCRIPTION |
---|---|
| Deletes the field permanently from the list. |
Saves your changes to the field, which are applied the next time |
You may have noticed that the previous tables of field properties and methods did not include any of the settings you have used to add a field via the browser. This is because the Field
class is the parent or base class of the various classes used to create fields. When you want to add or modify a field in a list, you use one of the following classes that matches the type of your field:
To add a field to a list, you must call the AddFieldAsXml
method on the list's Fields
collection. The AddFieldAsXml
method takes primarily a string parameter with the XML of the field definition and returns a Field
object that you can cast to one of the classes in the previous table to configure extra settings. The AddFieldAsXml
method also takes a Boolean parameter for adding the field to the list's default view and an AddFieldOptions
value to specify additional options for the field. Consider the following code snippet:
Field field = list.Fields.AddFieldAsXml(@"<Field DisplayName='My New Field' Type='Note' />", true, AddFieldOptions.DefaultValue); FieldMultiLineText textField = context.CastTo<FieldMultiLineText>(field); textField.NumberOfLines = 6; textField.RichText = true; textField.Update(); context.ExecuteQueryAsync(OnFieldCreated, OnFailure);
The AddFieldAsXml
method is called to create a rich text field using the field XML string with the default options. The field is added to the list and its default view. The AddFieldAsXml
method returns a Field
object, which is subsequently cast to a FieldMultiLineText
object by calling the CastTo<>
method on the ClientContext
class. The previous table contains a list of the valid values you use for the Type
attribute in your field XML.
Using the FieldMultiLineText
object, the number of lines and rich text support is configured for the field as in the browser UI. Finally, the Update
method is called on the field to save your changes. After the ExecuteQueryAsync
method is called, SharePoint adds the field to the list.
To modify a field, you call either the GetByInternalNameOrTitle
or GetByTitle
method on the Fields
property of the list. Afterwards, you can cast it to the appropriate field class as shown in the previous code snippet. When you are finished with your changes, call the Update
method on the field and the ExecuteQueryAsync
method on the ClientContext
class. To delete a field, you call the DeleteObject
method on the field. In the next activity, you will use these List
and Field
classes to display, modify, and create lists in your site.
There is no Recycle
method on the Field
class so when you delete the field, it is permanent. When you delete a field, the values for the deleted field in the existing items and documents are permanently deleted, too.
In Figure 14-12, you see the virtual file system of SharePoint that appears when you pin the All Files window in SharePoint Designer. Many files and folders do not appear in the UI. At times, you may need to manipulate files and folders using the Client Object Model, especially if you want to upload documents or create folders inside a document library.
In the Client Object Model, folders are represented by the Folder
class and files are represented by the File
class. Not all files and folders are in a document library but you can still access them using the Client Object Model. You can get a Folder
object by using one of the following:
Calling the Web
class's RootFolder
property, which returns the folder at the root of the SharePoint site.
Calling the List
class's RootFolder
property, which returns the folder at the root of the SharePoint list.
Calling the Web
class's GetFolderByServerRelativeUrl
method, passing in the server-relative URL of the folder.
If you already have a Folder
object, you can get its parent folder using the ParentFolder
property or its subfolders using the Folders
property. The Folder
class also has a Files
property that returns a list of File
objects for the files in the folder.
You create a folder by calling the Add
method on the Folders
property on an existing Folder
object, passing in the name of the new folder. The Add
method returns a Folder
object, which you can use to create subfolders or add files.
To rename a folder, you get the Folder
object representing the folder and modify its Name
property. Afterwards, you call the Folder
object's Update
method. To delete a folder, you call the Folder
object's Recycle
method, which sends the folder to the Recycle Bin. To permanently delete a folder, call the DeleteObject
method instead, which also permanently deletes the folder's contents.
The File
object represents a file in the virtual file system whether the file is located in a document library or not. The File
object is interesting because you can modify its properties, including its name, and you can modify its contents. The File
class has the following properties and methods:
PROPERTY | DESCRIPTION |
---|---|
Author | The user who created the file |
CheckedOutByUser | The user who has the file checked out |
CustomizedPageStatus | Whether the page has been customized or not |
Level | |
MajorVersion | The major version of the file |
MinorVersion | The minor version of the file |
ModifiedBy | The user who last modified the file |
Name | The name of the file |
ServerRelativeUrl | The URL of the file relative to the server name |
Title | The display name of the file |
Versions | The previous versions of the file |
METHOD | DESCRIPTION |
---|---|
Checks in the file. | |
Checks out the file so nobody else can modify it. | |
Copies the file to another location. | |
| Deletes the file permanently. |
Returns a | |
Moves a file. | |
Gets the contents of the file itself. | |
| Publishes the file for approval. |
| Sends the file to the Recycle Bin. |
Method | Description |
Updates the contents of an existing file. | |
Reverses a checkout and any pending file changes. | |
If the file is submitted for approval, this method un-submits the file. Otherwise, this method rolls back to the previous major version of the file. |
To add a file to a folder, you create a FileCreationInformation
object and configure its properties. Afterwards, you call the Add
method on the Files
property for a Folder
object passing in the FileCreationInformation
object. The following code snippet shows this in action:
foreach (System.IO.FileInfo file in files) { using (System.IO.FileStream fs = file.OpenRead()) { byte[] b = new byte[fs.Length]; fs.Read(b, 0, (int)fs.Length); fs.Close(); FileCreationInformation info = new FileCreationInformation(); info.Content = b; info.Overwrite = false; info.Url = file.Name; folder.Files.Add(info); } } context.ExecuteQueryAsync(OnUploadedSuccess, OnFailure);
In the snippet, a foreach
loop is used to iterate a list of FileInfo
objects that represent files on a workstation. Inside the loop, the OpenRead
method is called on the FileInfo
object to get a FileStream
object and load the file's contents into a byte array. Next, the FileCreationInformation
object is created and populated with the file's name and contents. The FileCreationInformation
object is also configured to not override an existing file. Finally, the FileCreationInformation
object is added to the Folder
object's Files
property via the Add
method. Like everything else in this chapter, you still must call the ExecuteQueryAsync
method for SharePoint to process any of these operations.
To modify a file, you loop through the Files
property on a folder or, more commonly, call the GetFileByServerRelativeUrl
method on the Web
class, passing in the server relative URL of the file. With the File
object, you can rename it using the Name
property, read its contents using the OpenBinaryDirect
method, or update its contents using the SaveBinary
method. Afterwards, call the Update
method to save your changes. With the File
and Folder
classes, you can create a tree displaying the content and structure of your site as shown in the following activity.
Calling the Update
method on a File
object is the same as clicking the Save button in SharePoint Designer when a file is opened in Advanced mode. This causes the file to become customized. For updating files in a document library, this is normal behavior. But using this method to update ASPX or master pages can negatively impact performance, especially on sites with heavy usage.
If you are wondering why you used the HTML Form Web Part instead of the Silverlight Web Part, here is the reason: the Silverlight Web Part configures the Silverlight object tag to run in windowless mode. This allows the web part menu to appear on top of the Silverlight control when the menu is displayed. If the Silverlight object tag were not running in windowless mode, the web part menu would appear behind the Silverlight control the same way an HTML element does when it overlaps space with a listbox or drop-down list. One of the disadvantages of running in windowless mode is that drag-and-drop events are not supported. You still can use the Silverlight Web Part to host the control from this activity, and all the functionality will still work except for dragging and dropping files.
You can also use the object model to modify the Quick Launch and Top Navigation bars in your site. You access the Quick Launch and Top Navigation bars via the following code snippet:
ClientContext context = ClientContext.Current; Web site = context.Web;
context.Load(site.Navigation.QuickLaunch); context.Load(site.Navigation.TopNavigationBar); context.ExecuteQueryAsync(OnSuccess, OnFailure);
When the OnSuccess
method is called, the site.Navigation.QuickLaunch
and site.Navigation.TopNavigationBar
properties are populated with the NavigationNode
objects that correspond to the clickable items on both bars. The NavigationNode
object has the following properties and methods:
PROPERTY | DESCRIPTION |
---|---|
| The text displayed for the navigation node |
The URL for the navigation node's hyperlink | |
The list of child navigation nodes |
METHOD | DESCRIPTION |
---|---|
| Deletes the navigation node and its children |
| Saves your changes to the navigation node |
When you start using the Client Object Model to modify these bars, determining where to put the nodes to make them appear where you want on the screen may be a little difficult. Take a look at Figure 14-14.
In the figure, the Quick Launch bar is organized with Libraries, Lists, and Discussions at the top levels and the individual lists and libraries underneath the appropriate top level. If you look at the tree control for the Quick Launch, you will notice that it matches the structure of the Quick Launch bar except that it does not display any nodes lower than two levels deep. The node named Level3 does not appear at all under Site Pages in the Quick Launch bar.
If you look at the Top Navigation bar, you see these four tabs:
Home
Level2(Home)
Level1
Level2
But in the tree control for the Top Navigation bar, you see only the Home and Level1 nodes at the top level. This means that all nodes at levels 1 and 2 will appear as tabs on the Top Navigation bar. Nodes at level 3 will appear as menu items under their parent node's tab. Nodes at levels 4 and below will not appear at all.
To create a navigation node, you must create a NavigationNodeCreationInformation
object. The NavigationNodeCreationInformation
class has the same properties as the NavigationNode,
including the following additional properties:
NAME | DESCRIPTION |
---|---|
If true, the | |
Specifies the node after which the new node should be inserted. | |
If you set this to true, the node is added at the end of the list. Otherwise, it is added at the beginning of the list if |
After you have configured the NavigationNodeCreationInformation
object, you call the Add
method on the Children
property of a NavigationNode
object or the Add
method on the Navigation.QuickLaunch
or Navigation.TopNavigation
properties of the Web
object.
To update a NavigationNode
, you will need to programmatically traverse the NavigationNode
objects until you get to your target. Then, you can update its properties and call the Update
method to save your changes. To delete a NavigationNode
, simply call its DeleteObject
method. Now that you have been introduced to the Navigation
and NavigationNode
classes, you can modify your site's navigation by following the steps in the next activity.
No discussion about any functionality this powerful would be complete without covering its limitations. Whether you are using JavaScript or Silverlight, these are some of the limitations you will face:
Your code can access any site collection as long as it is in the same SharePoint web application as the one where the code is running.
Only Windows, Forms Based, and Anonymous authentication are supported.
If you are using Silverlight and the site uses Forms Based Authentication, you must manually change the authentication mode of the ClientContext class and specify a username and password as shown in the following code snippet:
ClientContext context = ClientContext.Current; context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication; clientContext.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo("yourusername
", "yourpassword
");
The username and password are sent in "clear text" and can be viewed by anybody monitoring your server or network traffic. If you must use Silverlight in conjunction with Forms Based Authentication, make sure you secure the site with an SSL certificate to encrypt the traffic between the web server and the user's browser.
If you query an external list using the Client Object Model, you must specify the columns to return in your CAML query and the call to the Load
method of the ClientContext
class. Otherwise, you will get the error message "The given key was not present in the dictionary."
If you are using JavaScript with the Client Object Model, you must include the FormDigest control in the master page. By default, this control is already in the site's master pages, but it could be accidently removed or you could create a page that does not use the site's master page.
If you intend to update list items or documents in the site, you may need to re-query the list or library before performing your update. Another user may have updated your list item or document after you queried the list or library but before your code tried to execute an update. If that is the case, you will get an error message stating the item or document has been updated since you last retrieved it.
In this chapter, you have seen how to use Silverlight to greatly extend the functionality of your SharePoint sites. Practically nothing has been taken off the table in terms of what you are able to do in the Client Object Model versus the Server Object Model. With the Client Object Model, your SharePoint sites no longer have to be used out-of-the-box, even if they are hosted by a third party that does not allow the traditional methods of customization used by SharePoint developers. With the techniques you learned in this chapter, you should be able to increase the ROI value of your SharePoint investment by several orders of magnitude.
3.141.38.121