Using a CURRENT USER FILTER on a list

Simple instruction on adding a 'current user filter' to filter a list web part on a sharepoint 2010 page.
For these instructions we will assume you have:
First we need to slightly modify the list.
Click on the link to your list in the quick launch bar on the left hand side or navigate to your sites lists and select it from there.
navigate to list sharepoint 2010
 Click on the list settings button on the list tools>list ribbon.
list settings sharepoint 2010
Click on the 'person' type column that you wish to filter by current user, then under the 'additional column settings' options ensure that the 'Show field' dropdown is set to 'account'.
show field share point 2010
 Navigate back to your page that has the list added as a web page and click the edit page icon. Then on the editing tools > Insert ribbon click the web part button.
web part insert sharepoint 2010
 From the options that appear select the Current User Filter from the filters folder and click add. Then click the save page button to save where we are up to.
current user filter
This is where it can get a bit tricky. The Current user web part does not appear immediately on the screen nor does it have any immediate affect until we configure it.
In order to configure the web part from here seems a bit poorly thought out but here is how I go about it.
Click the edit page button then hover over your list web part and click the edit web part select from the arrow dropdown at the very right hand site of the list web part.
list web part edit
 This will now make the current user filter appear on the page.
Now from the dropdown on the Current user filter web part select Connections > Send filter values to > #your list name#.
web part connections
 In the dialog that pops up ensure that 'Get filter values from' is selected in the dropdown and press configure.
 configure connections
If a "Confirm dialog preference" pops up press cancel. Then in the next popup ensure your 'person' type field that we modified earlier is selected then press Finish. Save the page.
configure web part connection
 You should be left with a list that only has items filtered to the current user....
filter current user

Enable Anonymous Access in SharePoint 2010

It is not much different then SharePoint 2007 set up, the only difference is the GUI or the Ribbon.
1. Starting in Central Administration, under Application Management, click on the Manage web applications.
Anonymous Access Set Up Step 1
2. Make sure you select the site you want to enable anonymous access and click on the Authentication Providers icon.
Anonymous Access Set Up Step 2
3. On the Authentication Providers pop-up window click on the Default zone.
Anonymous Access Set Up Step 3
4. Under Edit Authentication, check Enable anonymous access and click Save.
Anonymous Access Set Up Step 4
5. Going back to Web Application Management click on the Anonymous Policy icon.
Anonymous Access Set Up Step 5
6. Under Anonymous Access Restrictions select your Zone and set the Permissions to None – No policy and click Save.
Anonymous Access Set Up Step 6
7. Now, web application will allow anonymous access to be set. So, navigate to your top level site collection for the web application. Click the Site Actions > Site Settings. Under Users and Permissions click Site permissions.
Anonymous Access Set Up Step 7
8. Under Permission Tools, click Anonymous Access icon and set the permissions to Entire Web site and click OK.
Anonymous Access Set Up Step 8
Anonymous Access Set Up Step 8
Anonymous Access Set Up
That’s all, folks! If you followed these steps properly you should have now Anonymous Access enabled.

Customize the ribbon programmatically from web parts and field controls

  1. Customizing the ribbon – creating tabs, groups and controls
  2. Adding ribbon items into existing tabs/groups
  3. Ribbon customizations – dropdown controls, Client Object Model and JavaScript Page Components
  4. Customize the ribbon programmatically from web parts and field controls
In contrast to my earlier posts, this article isn’t a detailed walkthrough – rather, it is a compendium of techniques and information which should help you implement ribbon customizations for web parts, custom field controls or indeed, any other kind of page control. At the time of writing I haven’t really seen a great deal written on this, aside from a couple of resources I’ll mention. I would have loved to have written detailed walkthroughs here, but alas I can’t because a) Microsoft have recently published some good info for one of the scenarios, so I’d prefer to point you to that, b) To run through all the scenarios here in depth would take weeks and c) Because if I don’t stop writing about the ribbon soon I’ll still be on this topic this time next year, and frankly I have a  book chapter to write on a completely different area of SharePoint 2010 which I need to crack on with! So we’ll look at each requirement and I’ll discuss what I think are the key techniques you’d use along with some observations from me.
Note that due to the general lack of documentation so far on this topic (and the fact I haven’t bottomed everything out in all the scenarios), a couple of things here are speculation rather than hard fact. I’ll make these items clear, and will endeavour to come back to this article and add updates as new information emerges. 
Before we dive in, remember that if you’re abiding by ribbon design principles you should most likely be working with a ContextualGroup (discussed towards the end of Adding ribbon items into existing tabs/groups) – this is the container to use for ribbon elements which are only relevant depending on what the user is doing (shown visible but not active here):
ContextualGroup
If this isn’t what you want, note that things are probably easier if you just need to add some controls on an existing tab or group which get activated under certain circumstances. In this case you can just supply some JavaScript to the ‘EnabledScript’ attribute of your controls – I showed this in my Notifications/Status demo in Customizing the ribbon (part 1) – creating tabs, groups and controls. The rest of this article focuses on how you might get a contextual group (see image above) to show in different scenarios.
 Adding ribbon items from a web part
In SharePoint 2010 the web part framework now has special provision for ribbon customizations, which means a couple of things are taken care of for you. Microsoft have now published some guidance on this scenario in the form of an article on the SharePoint Developer Documentation blog – How to Create a Web Part with a Contextual Tab. There’s a lot of golden info in there, but I’ll distil the main points here:
  • Using server-side code, the ‘RegisterDataExtension’ method of SPRibbon can be used to pass XML to the ribbon framework.
    • This is an alternative to the fully declarative approach using the CustomAction element. As far as I can tell, either technique can be used for ribbon customizations specific to a certain control only (as opposed to ribbon customizations for say, all lists of a specific type where CustomAction is the way to go).
  • Your web part needs to implement the newIWebPartPageComponentProvider interface and it’sWebPartContextualInfo property
    • This allows you to specify information about the associated ribbon customization(s) and the ID of the associated page component (which we discussed last time) for your custom bits.This allows the ribbon framework to ‘link’ your web part with your ribbon changes – meaning that certain things are taken care of for you e.g. firing commands only when your web part has focus on the page (if you specified this behaviour by use of ‘getFocusedCommands’ in your page component). Without this you would have to write JavaScript code to manually handle page events for controls emitted by your web part e.g. the click event for a textbox.
Adding ribbon items from a field control
Like web parts, I think (speculating here) there is special provision in the framework for ribbon customizations from a field control. Consider that, like web parts, field controls should typically only show their contextual ribbon options when they have focus – since this would be the case for all field controls, it makes sense to me that Microsoft might abstract some handling around this for us. If not, you would be responsible for writing JavaScript to detect when the user clicked into your field so that you could show your ContextualGroup.
Digging around, I notice that all SharePoint field controls have 4 new properties (since they are implemented on one of the base classes,Microsoft.SharePoint.WebControls.FormComponent):
  • RibbonTabCommand
  • RibbonContextualGroupCommand
  • RibbonGroupCommand
  • RibbonCommand
I’m surmising that these control properties would be set declaratively in the hosting page and are designed to match up with commands specified in an accompanying page component – this would enable you to run client-side code similar to my sample last time, perhaps to initialize data for your ribbon controls and so on. However, when I try to implement these commands, my page component’s ‘handleCommand’ method never receives these commands. So either I’m doing something wrong or this theory is incorrect. In which case, not to worry ribbon customizations for field controls should still be entirely possible, there will just be more work to do. Read on.
Using server-side code to show ribbon items
Thinking outside of any ‘framework support’ for where our ribbon customizations are targeted at, we can always write server-side or client-side code to show a contextual group. In fact, I already showed the server-side code for this in Adding ribbon items into existing tabs/groups (ribbon customization part 2):
protected override void OnPreRender(EventArgs e)

{

    SPRibbon currentRibbon = SPRibbon.GetCurrent(this.Page);

    currentRibbon.MakeTabAvailable("COB.SharePoint.Ribbon.ContextualTab");

    currentRibbon.MakeContextualGroupInitiallyVisible("COB.SharePoint.Ribbon.ContextualGroup", string.Empty);

    

    base.OnPreRender(e);

}
This is probably only appropriate if your stuff is contextual-ish – an application page would be a good example of this. In this example all we care about is that the user is on our page, then we can show our options. It doesn’t matter which control has focus, effectively our options are OK to show by default when the page loads. However, if you need page-level ‘contextuality’ (I may have just invented that word by the way – use it in a sentence to your boss today) then most likely you’ll be wanting to use JavaScript to show your contextual group when the user is doing something specific on the page e.g. editing a certain field. You’d then be looking to some client-side code to detect this and respond accordingly.  
Using client-side code to show ribbon items
So, final scenario – what if you need to show ribbon items from something which isn’t a web part or field control (or like me you couldn’t get there with anything in the field control framework which may or may not be designed to help), and it has to be done client-side to be fully contextual? Well, disappointingly I’m drawing another blank here so far – I’d love to hear from anyone who knows the answer to this. In case you’re doing ribbon development and are interested, here’s a summary of my journey:
  • Checked SP.Ribbon namespace in Client OM
  • Spent many happy hours in the debugger and various out-of-the-box JavaScript files, looking for examples of where the core product does this (e.g. calendar, rich text editor to name a couple)
  • Found some interesting methods on the CUI.Ribbon object, such as showContextualGroup(‘foo’) and selectTabByCommand(‘bar’)
    • Noted that across the entire SharePoint root, these methods are only called by the RTE, not globally across the SharePoint codebase
    • Noted that the RTE code gets a CUI.Ribbon instance from a property (RTE.RichTextEditorComponent.$3b() – N.B. most of the JS is obfuscated or machine-generated* down here)
  • Tried to use SP.Ribbon.PageManager.get_instance().get_ribbon() (used elsewhere in the OOTB codebase) to get me a CUI.Ribbon instance, however this gave me a null
  • Tried to use the ‘_ribbon’ page level variable, however this appears not to be of type CUI.Ribbon as the debugger shows it does not have the methods I’m trying to call
  • Tried a couple of other things which I’ve forgotten now
Needless to say, I’d love to hear what I’m missing on this. If nothing else, hopefully MS will release some more information soon which will shed some light on how to handle this scenario.
Summary
This post doesn’t claim to have all the answers, but it might serve as a “leg up” if you’re trying to build any of these scenarios now. I’m hoping that the lack of deep information in this area is a reflection on the fact that RTM is still some time away, and that ribbon dev will get some love in the SDK between now and then. The key scenarios I discussed here are displaying custom ribbon elements from web parts and field controls, but also the more generic cases of displaying customizations with server or client-side code.

SharePoint 2010: Get Full or Relative Url of web using EcmaScript

Sometimes from client side, you need to know the current web url. And for this little information you don’t want to call EcmaScript’s load function to get information from server side. Actually the information can be found without any server call. You can access the information from ClientContext as shown below.
var context = new SP.ClientContext();
var relativeWebUrl = context.get_url();
Remember the get_url method will only return relative url of the site. As shown in the following table:
Site Collection UrlSite Urlcontext.get_url() response
http://mysite.comhttp://mysite.com/
http://mysite.comhttp://mysite.com/site1/site1
http://mysite.com/siteshttp://mysite.com/sites/site1/sites/site
So if you need to know the full url of the site you can do so easily with the following script:
function getFullWebUrl() {
    var context = new SP.ClientContext();
    var relativeWebUrl = context.get_url();
    var fullWebUrl = window.location.protocol + '//' + window.location.host + relativeWebUrl ;
    alert(fullWebUrl);
} 

SharePoint 2010: Conditional Scope

In Client Object Model, if you need to load data based on some condition. But if the condition is based on some server side values then you need to use two different requests. First request will be to get the values from the server to check the condition. Second request will be to load data or not, based on the condition expression value.
In SharePoint Client Object Model API, there’s a new class called ConditionalScope to load data conditionally. Here’s how to use the ConditionalScope:
  • In ConditionalScope constructor pass the ClientContext instance as first parameter. In the second parameter, pass the condition to be evaluated on the server. As shown below, the condition to check is whether the list is hidden or not.
var conditionalScope = new ConditionalScope(clientContext, () => !list.Hidden);
  • The second step is to put the load expression in ConditionalScope’s StartScope method. As shown below, if the list is not hidden, then load the Title of the list.
using (conditionalScope.StartScope())
{
    clientContext.Load(list, ol => ol.Title);
}
In the above statement, the load will be executed if the condition specified in ConditionalScope’s constructor is true (in this case, not hidden).
  • Finally, after executing ClientContext.ExecutQuery method, you need to find out if the expression passed in Coditional Scope was true or false. If condition was true then u know the data has been loaded (in this case the title of the list). If the condition was not true then data was not loaded. To check whether the condition evaluated true of false, check conditional scope’s TestResult. Remember, you will only get this property value after executing Executing query to the server.
clientContext.ExecuteQuery();
if (conditionalScope.TestResult.HasValue && conditionalScope.TestResult.Value)
{
    Console.WriteLine("Title:" + list.Title);
}
As shown in the code snippet above, if the TestResult has been evaluated to true then the title property is available.
The whole code will look like below:
var clientContext = new ClientContext(siteUrl);
var web = clientContext.Web;
var list = web.Lists.GetByTitle(listName);

var conditionalScope = new ConditionalScope(clientContext, () => !list.Hidden);

using (conditionalScope.StartScope())
{
    clientContext.Load(list, ol => ol.Title);
}

clientContext.ExecuteQuery();
if (conditionalScope.TestResult.HasValue && conditionalScope.TestResult.Value)
{
    Console.WriteLine("Title:" + list.Title);
}

 

Limitations

You can not use Conditional scope in all cases for all operations:
  • You can only load data using Conditional Scope. You can not however call any method or set properties in Conditional Scope’s StartScope method. If you use the ConditionalScope to set properties or to call server side method, you may get the following error:
Incorrect usage of conditional scope. Some actions, such as setting a property or invoking a method, are not allowed inside a conditional scope.
  • expression passed in ConditionalScope’s second argument has restrictions. You can not use all kinds of expressions. For example you can not use expression like, list.Fields.Count. However, you can use List.ItemCount. I have not found any documentation on MSDN with the supported expression for ConditionalScope.
  • Before using ConditionalScope.TestResult in your decision to access data, you need to execute Query.

SharePoint 2010 Client Object Model: Manipulate Choice, Lookup field

After my few posts on Client Object Model, I had come to questions on how to manipulate choice and lookup field. I’ve tried to explain a bit on how you can manipulate these field values with Client Object Model.

Manipulate Choice Field Value (Single Choice)

You can manipulate the single choice field value as like string. For example, let’s consider a field, ProductStatus in Product list. The field values might be “In Stock, Out of Stock, Invalid” as shown below:
image
Figure 1: Single Choice Field (ProductStatus) in product list.
To access the value of the field using Client Object Model, you can use code shown below:
  • Get Field value: You can just get the field value as string
    var productStatus = productItem["ProductStatus"].ToString();
  • Set Field value: You can use any of the following statement to set the field value
    productItem["ProductStatus"] = "In Stock";
    productItem["ProductStatus"] = "Out of Stock";
    productItem["ProductStatus"] = "Invalid";

Manipulate Choice Field Value (Multiple Choice)

If the choice field support multiple values then you need to use string array to manipulate field values. For example, consider there’s a field ‘product types’  in product list whose values can be Foods, electronics, Cars etc. Also consider the field values can be multiple, that’s mean a product types can be more than one type. The following figure shows the field
image
Figure 2: Multiple Choice Field
In that case you need string array to access the multiple choice field value as shown as shown below:
  • Get Field Value:
    var productTypes = (string[]) (productItem["ProductType"]);
  • Set Field Value:
    productItem["ProductType"] = new string[] { "Furniture", "Toys" };

Manipulate Lookup Field Value

To manipulate lookup field you need to use the code as shown below:
  • Get Field Value:
    var lookupFieldValue = (productItem["FieldName"] as FieldLookupValue);
  • Set Field Value
    //100 here is the lookup field id value
    productItem["FieldName"] = new FieldLookupValue(){LookupId = 100};
The FieldLookupValue is part of SharePoint Client OM 

Use ECMAScript to manipulate (Add/Delete/Update/Get) List Items

In SharePoint 2010 there are three different types of Client Object Model extension you can use. They are Managed Client Object Model, ECMAScript and silverlight extension. In one of my post I have described how to manipulate list items using Managed Client Object Model. Today I’ll go through how to use ECMAScrip to manipulate list items. Fist of all make sure your page/webpart is ready to use ECMAScript as I have described inanother post.

How to Get ECMAScript Intellisence

When you’ll use ECMAScript library in Visual Studio, it’s possible to get intellisense for ECMAScript. There are three ways you may need to enable the intellisense:
  1. Get Intellisense in Application Page: In the case you want to put  your javascript in aspx file as inline, you need to add the following lines in the markup file. However, this will not work for webpart file. For webpart file you need to put your javascript in another js file as described in option 2.<script type=”text/ecmascript” src=”/_layouts/SP.debug.js” />
    <script type=”text/ecmascript” src=”/_layouts/SP.Debug.js” />
    <script type=”text/ecmascript” src=”/_layouts/SP.Runtime.Debug.js” />

    <script type=”text/javascript”>
          //you’ll get intellisense here
    </script>
  2. Get Intellisense in js file: If you want to get intellisense in js file then you need to add the following lines in the top of the js file. As shown in the snippet below, the first reference is to MicrosoftAjax.js file. This is mandatory to have this js file reference at the top. Then I have added two other references. The two files (SP.Core.Debug.js and SP.debug.js) have basic SharePoint namespaces. However, if you need more functionalities try to add more js file reference from the path “C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS”
    /// <reference name="MicrosoftAjax.js" />
    /// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
    /// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
  3. Get Intellisense in webpart: To get intellisense in webpart you need to add the following two lines in the webpart ascx file:
    <script type="text/javascript" src="/_layouts/MicrosoftAjax.js" ></script>
    <script type="text/javascript" src="/_layouts/SP.debug.js" />
    However, I have found the MicrosoftAjax.js file is not located in “/_layouts/MicrosoftAjax.js” and for that the above intellisense will not work. So to get intellisense you need to copy the file in the Layouts folder. You can try to find the MicrosoftAjax.js file from location “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplatesCache\VisualBasic\Web\1033\EmptyMvcWebApplicationProjectTemplatev2.0.vb.zip\Scripts” if exists. Or you can download the file from the location below where I have uploaded the file: http://cid-04d8f6d0dd4e7214.office.live.com/self.aspx/Public/MicrosoftAjax.js 

A Sample List I have used

For this blog I have used a sample product list with the properties as shown in the following image.
image
Figure 1: Product List

 

Add a new List Item

The code snippet below shows that  you need to get the current SharePoint Context first. Then get the current web from the context. And then you need to get the list from the web. Then I have used ListItemCreationInformation object. There are two important properties of ListItemCreationInforamtion:
  • ListItemCreationInformation.folderUrl: this property defines in which location you want to add the item. The url should start with forward slash(/). For example for the web myweb and list product and for the folder ‘myfolder’ in the product list the url will be ‘/myweb/Lists/product/myfolder’.
  • ListItemCreationInformation.UnderlyingObjectType: this value identity the type of object to create. The possible values are File,Folder, Web and Invalide. The values can be found in ‘SP.FileSystemObjectType’.
The addProduct method below takes few arguments that represents the product list’s fields.
function addProduct(productName, productDesc, productLaunchDate, productAvailQty, productType) {
    try {
        var context = new SP.ClientContext.get_current();        
        var web = context.get_web();
        var list = web.get_lists().getByTitle('product');

        var listItemCreationInfo = new SP.ListItemCreationInformation();
        var newItem = list.addItem(listItemCreationInfo);
        newItem.set_item('Title', productName);
        newItem.set_item('ProductName', productName);
        newItem.set_item('ProductDescription', productDesc);
        newItem.set_item('LaunchDate', productLaunchDate);
        newItem.set_item('AvailableQuantity', productAvailQty);
        newItem.set_item('ProductType', productType);

        newItem.update();
        context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
    }
    catch (e) {
        alert('error:' + e.Message);
    }
}
If you look a bit closer in the above code snippet you can find that ClientContext.executeQueryAsync takes two function delegates. The first one will be invoked when the ECMAScript get executed successfully. The second one will be invoked otherwise. The two methods are defined below:
function success() {
    alert('success');
}
function failed(sender, args) {
    alert('failed. Message:' + args.get_message());
}

 

Delete a List Item

To delete a product by product id the following code snippet can be used:
function deleteProduct(productId) {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getByTitle('product');
    var itemToDelete = list.getItemById(productId);
    itemToDelete.deleteObject();
    context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
To delete an object in Client Object Model you need to invoke the deleteObject method of that object.

 

Get Item By Id

To get an item using ECMAScript, you need to share a common variable between the method that execute the ECMAScript (getProductById method in the following code snippet) and callback method (productReceived, failed in the snippet below). Only for this reason I have defined a variable productin the first line of the code snippet below.
var product;
function getProductById(productId) {
    try {
        var context = new SP.ClientContext.get_current();
        var web = context.get_web();
        var list = web.get_lists().getByTitle('product');
        this.product = list.getItemById(productId);
        context.load(product, 'ProductName', 'ProductDescription', 'ProductType', 'LaunchDate', 'AvailableQuantity');
        context.executeQueryAsync(Function.createDelegate(this, this.productReceived), Function.createDelegate(this, this.failed));
    }
    catch (e) {
        alert(e);
    }
}
function productReceived() {
    alert('got product');
    gotProduct(this.product);
}
function failed(sender, args) {
    alert('failed. Message:' + args.get_message());
}
In the code snippet above, the Context.Load method has taken the item to load (product) as the first parameter. And a comma separated list of columns to load for this item are passed then to the load method. If you want to load all properties of the item (which is not recommended) you can just call the context.load method with only first parameter.

Search Items from a List

In the code snippet below Caml Query is used for searching a product by title. I have used Caml Query to search product by title. Notice here that the load takes a second parameter (wrapped with ‘include’) specifying all properties to load for items.
var productcollection;
function getProducts(title) {
    try {
        var context = new SP.ClientContext.get_current();
        var web = context.get_web();
        var list = web.get_lists().getByTitle('product');
        var query = '<View Scope=\'RecursiveAll\'>'+
                        '<Query>'+
                            '<Where>'+
                            '<Contains>'+
                                '<FieldRef Name=\'ProductName\'/>' +
                                '<Value Type=\'Text\'>' + title +'</Value>'+
                            '</Contains>'+
                            '</Where>'+
                        '</Query>'+
                             '</View>';
        var camlQuery = new SP.CamlQuery();
        camlQuery.set_viewXml(query);

        this.productcollection = list.getItems(camlQuery);
        context.load(this.productcollection, 'Include(ProductName, ProductDescription, ProductType, LaunchDate, AvailableQuantity)');
        context.executeQueryAsync(Function.createDelegate(this, this.productsReceived), Function.createDelegate(this, this.failed));
    }
    catch (e) {
        alert(e);
    }
}
function productsReceived() {
    alert('got products');
    prcessProducts(this.productcollection);
}
function failed(sender, args) {
    alert('failed. Message:' + args.get_message());
}

 

Update a list item

The code snippet below shows how to update a product item. The list item’s set_item(propertyname, propertyvalue) method is used to update the field values.
function updateProduct(productid, productName, productDesc, productLaunchDate, productAvailQty, productType) {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getByTitle('product');
    var product = list.getItemById(productid);
    product.set_item('ProductName', productName);
    product.set_item('ProductDescription', productDesc);
    product.set_item('ProductType', productType);
    product.set_item('LaunchDate', productLaunchDate);
    product.set_item('AvailableQuantity', productAvailQty);
    product.update();
    context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));

}

Points to Remember

1. FormDigest Control: If you write code that modifies data on server, include a FormDigest control to create a digest for security validation of the page. The formdigest control can be added in master page and then all content pages will get it automatically.
<SharePoint:FormDigest runat="server" />
2. Get and Set Property: For the scrip used, when you need to get a property, you need to add get_ as prefix. For example the web has the property title. So if you want to get the title property of web then you need to use the syntax web.get_title(). Similary, if you want to set the title value then you need to invoke web.set_title(‘title’).
2. ClietContext.Load: ClientContext’s load method is used to load object. The first parameter to the load method is the object to load. The second parameter vary depending on whether the first parameter is a single object or collection.
  • If the first parameter is a single object then the following syntax is used to load properties:
context.load(objectToLoad,’property1’,’property2’,………….,’propertyN’)
  • If the first parameter is a collection then the following syntax is used
context.load(objectCollectionToLoad,’Include(property1, property2,……….,propertyN)’)

SharePoint 2010: Attach files to List/Library using Managed Client Object Model

Client Objet Model (OM) is a great new addition in SharePoint 2010. I have discussed before how to manipulate lists and list items using Managed Object Model. Today I’ll discuss on how to attach file to list item or add file to library using Managed Client Object Model.

Upload File in Library

The following code snippet shows how to upload file in document library:
public void UploadFileInLibrary(string siteUrl, string webName, string libraryName, string subfolderPath, string fileName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {

        string uploadLocation = Path.GetFileName(fileName);
        if (!string.IsNullOrEmpty(subfolderPath))
        {
            uploadLocation = string.Format("{0}/{1}", subfolderPath, uploadLocation);
        }
        uploadLocation = string.Format("/{0}/{1}/{2}", webName, libraryName, uploadLocation);
        var list = clientContext.Web.Lists.GetByTitle(libraryName);
        var fileCreationInformation = new FileCreationInformation();
        fileCreationInformation.Content = System.IO.File.ReadAllBytes(fileName);
        fileCreationInformation.Overwrite = true;
        fileCreationInformation.Url = uploadLocation;
        list.RootFolder.Files.Add(fileCreationInformation);
        clientContext.ExecuteQuery();
    }
}
In the above code snippet, I have constructed the full path to the update location by concatenating the subfolderpath with library location. The site url is the spsite location whereas web name is name of the web site. To upload a file I have use FileCreationInformation object which is part of Client Object Model. To use the above method you can call the method as shown below. The instance is the class instance which has the method. Here the subfolderpath is the folder location inside the library where the document will be uploaded.
Instance.UploadFileInLibrary("http://mysite","mywebname", LibraryName,"folder1/folder2", @"c:\myfiles\LibraryItem.xlsx");

 

Download File From Library

The following code snippets shows how to download file from library:
public void DownloadFileFromLibrary(string siteUrl, string webName, string libraryName, string subfolderPath, string fileName, string downloadPath)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        string filePath = string.Empty;
        if (!string.IsNullOrEmpty(subfolderPath))
        {
            filePath = string.Format("/{0}/{1}/{2}/{3}", webName, libraryName, subfolderPath, fileName);
        }
        else
        {
            filePath = string.Format("/{0}/{1}/{2}", webName, subfolderPath, fileName);
        }

        var fileInformation = File.OpenBinaryDirect(clientContext, filePath);
        var stream = fileInformation.Stream;
        IList<byte> content = new List<byte>();
        int b;
        while ((b = fileInformation.Stream.ReadByte()) != -1)
        {
            content.Add((byte)b);
        }
        var downloadFileName = Path.Combine(downloadPath, fileName);
        System.IO.File.WriteAllBytes(downloadFileName, content.ToArray());
        fileInformation.Stream.Close();
    }
}
As above code shows, we can use Microsoft.SharePoint.Client.File.OpenBinaryDirect method to download file directly from SharePoint. However, SharePoint open the file as binary stream so you need read the full stream before processing the file. The subfolderpath is same as described in ‘Upload File in Library’ section.

Delete File From Library

The following code snippet shows how to delete file from library:
public void DeleteFileFormLibrary(string siteUrl, string webName, string listName, string subfolder, string attachmentFileName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        string attachmentPath = string.Empty;
        if (string.IsNullOrEmpty(subfolder))
        {
            attachmentPath = string.Format("/{0}/{1}/{2}", webName, listName, Path.GetFileName(attachmentFileName));
        }
        else
        {
            attachmentPath = string.Format("/{0}/{1}/{2}/{3}", webName, listName, subfolder, Path.GetFileName(attachmentFileName));
        }
        var file = clientContext.Web.GetFileByServerRelativeUrl(attachmentPath);
        file.DeleteObject();
        clientContext.ExecuteQuery();
    }
}
As the above code , the DeleteObject method is invoked on file object to delete the file.

Attach File to ListItem

The following code snippet shows how to attach file to list item. The attachments in list are places in a folder whose location is like “http://siteurl/lists/[listname]/Attachments/[ListItemID]/[filename]”. So I have constructed the attchment location first and use Microsoft.SharePoint.Client.File.SaveBinaryDirect method to upload the file. Here in the method, Item id is the list item id that I want to attach the file to.
public void AttachFileToListItem(string siteUrl, string webName, string listName, int itemId, string fileName, bool overwrite)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        FileStream fileStream = new FileStream(fileName, FileMode.Open);
        string attachmentPath = string.Format("/{0}/Lists/{1}/Attachments/{2}/{3}", webName, listName, itemId, Path.GetFileName(fileName));
        File.SaveBinaryDirect(clientContext, attachmentPath, fileStream, overwrite);
    }
}

 

Download File from ListItem

The following code snippet shows how to download file that is attached with list item.
public void DownloadAttachedFileFromListItem(string siteUrl, string webName, int itemId, string attachmentName, string listName, string downloadLocation)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        string attachmentPath = string.Format("/{0}/lists/{1}/Attachments/{2}/{3}", webName, listName, itemId, Path.GetFileName(attachmentName));
        var fileInformation = File.OpenBinaryDirect(clientContext, attachmentPath);
        IList<byte> content = new List<byte>();
        int b;
        while ((b = fileInformation.Stream.ReadByte()) != -1)
        {
            content.Add((byte)b);
        }
        var downloadFileName = Path.Combine(downloadLocation, attachmentName);
        System.IO.File.WriteAllBytes(downloadFileName, content.ToArray());
        fileInformation.Stream.Close();
    }
}
As said before, the attachment location is “http://siteurl/lists/[listname]/Attachments/[itemid]/[filename]”. So I have used Microsoft.SharePoint.Client.File.OpenBinraryDirect to download the file.

Delete Attached File From ListItem

The following code shows how to delete a file that is attached with list item.
public void DeleteAttachedFileFromListItem(string siteUrl, string webName, int itemId, string attachmentFileName, string listName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        //http://siteurl/lists/[listname]/attachments/[itemid]/[filename]
        string attachmentPath = string.Format("/{0}/lists/{1}/Attachments/{2}/{3}", webName, listName, itemId, Path.GetFileName(attachmentFileName));
        var file = clientContext.Web.GetFileByServerRelativeUrl(attachmentPath);
        file.DeleteObject();
        clientContext.ExecuteQuery();
    }
}

Conclusion

The code snippet above just provide you the gist. One point to notice that the File class used in the code not from System.IO. This is from Microsoft.SharePoint.Client and the full name is “Microsoft.SharePoint.Client.File”.

SharePoint 2010: Add/Delete/update/search list items with Managed Client Object Model

Managed client Object model is a rich extension to SharePoint 2010. You can almost perform all kinds operations against SharePoint using Client OM. In this post I’ll show you how to use Managed client Object Model (OM) to manipulate list items. The code snippet I’ll use in the examples below is depend on a product list. The product list has four fields: Product Name, Product Description, Product launch date, available quantity. The product list is represented with a class as shown below:
public class Product
{
    public string ProductName { get; set; }
    public int ProductID { get; set; }
    public string ProductDescription { get; set; }
    public DateTime LaunchDate { get; set; }
    public int AvailableQuantity { get; set; }
}

Add new list item

To add a new item in a list you may or may not need to pass ListItemCreationInformation.  Let me explain when you need to pass ListItemCreationInformation or when not:
  • If you need to add item at the root (not under a subfolder) then you can ignore ListItemCreationInformation by passing null in place of ListItemCreationInformation.
  • If you need to add item somewhere inside subfolder then you need to create an instance of ListItemCreationInformation and set it’s Folderurl to url of the folder you want to save the list item.
The code snippet below add a new list item (Product item in my case):
public void AddNewProduct(string siteUrl, string folderPath, Product product)
{
    const string listName = "Product";
    using (var clientContext = new ClientContext(siteUrl))
    {
        var list = clientContext.Web.Lists.GetByTitle("Product");

        ListItemCreationInformation listItemCreationInformation = null;
        if (!string.IsNullOrEmpty(folderPath))
        {
            listItemCreationInformation = new ListItemCreationInformation();
            listItemCreationInformation.FolderUrl = string.Format("{0}/lists/{1}/{2}", siteUrl, listName, folderPath);
        }

        var listItem = list.AddItem(listItemCreationInformation);
        listItem["ProductName"] = product.ProductName;
        listItem["ProductDescription"] = product.ProductDescription;
        listItem["LaunchDate"] = product.LaunchDate;
        listItem["AvailableQuantity"] = product.AvailableQuantity;
        listItem.Update();
        clientContext.ExecuteQuery();

    }
}
The method in above code snippet takes a site url  and optional folder url and a product. If you want to add item in the root folder then you can pass folderPath parameter empty or null in the above method. Depending on whether you have passed folderPath or not, the ListItemCreationInformation will be initialized or not. If you don’t pass folderPath, the ListItemCreationInformation variable will be null. but if you want to add item in a specific subfolder then pass the folder name as parameter and the ListItemCreationInformation will be initialized and teh FolderUrl of the instance will be set with parameter folderaPath.

Delete list item

In the code snippet below, I have used the same product list. I have passed the product Id as parameter and the get the list item by id. Once I get the list item, I have invoked the DeleteObject method of the list item.
public void DeleteProduct(string siteUrl, int productId)
{
    using (var clientContext = new ClientContext(siteUrl))
    {
        var list = clientContext.Web.Lists.GetByTitle("Product");
        var product = list.GetItemById(productId);
        product.DeleteObject();
        clientContext.ExecuteQuery();
    }
}

Update List Item

The following code snippet shows how to update a product list.
public void UpdateProduct(string siteUrl, Product product)
{
    using (var clientContext = new ClientContext(siteUrl))
    {
        var list = clientContext.Web.Lists.GetByTitle("Product");
        var productToModify = list.GetItemById(product.ProductID);
        productToModify["ProductName"] = product.ProductName;
        productToModify["ProductDescription"] = product.ProductDescription;
        productToModify["LaunchDate"] = product.LaunchDate;
        productToModify["AvailableQuantity"] = product.AvailableQuantity;
        productToModify.Update();
        clientContext.ExecuteQuery();
    }
}

Get a single List Item

To get a lsit item you need to specify the fields you want to retrieve from the list item.
public Product GetProductById(string siteUrl, int productId)
{
    Product product = null;
    try
    {

        using (var clientContext = new ClientContext(siteUrl))
        {
            var list = clientContext.Web.Lists.GetByTitle("Product");
            var productItem = list.GetItemById(productId);
            clientContext.Load(productItem, pi => pi.Id, pi => pi["ProductName"], pi => pi["ProductDescription"], pi => pi["AvailableQuantity"], pi => pi["LaunchDate"]);
            clientContext.ExecuteQuery();
            product = new Product();
            product.AvailableQuantity = Convert.ToInt32(productItem["AvailableQuantity"]);
            product.LaunchDate = Convert.ToDateTime(productItem["LaunchDate"]);
            product.ProductDescription = productItem["ProductDescription"].ToString();
            product.ProductID = productItem.Id;
            product.ProductName = productItem["ProductName"].ToString();
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception.Message);

    }
    return product;
}
As shown in the example below, the field values I like to retrieve are passed in the ClientContext.Load method. If you want to retrive all fields (which is not recommended) then call the Load method with the list item, as shown below:
clientContext.Load(productItem);

Get Collection of List Items

To get a list of items as per any condition, you can use CAML  query (or in Linq to SharePoint extension). I’ve covered in another post on how to use Linq to SharePoint. One important point to notice here in the code snippet below is that if you want to look for items inside subfolders thenyou need to add an extra attribute Scope=’RecursiveAll’ in view tag.
public IList<Product> FindProductsByName(string siteUrl, string productName, bool includeSubfolder)
{
    IList<Product> products = new List<Product>();
    try
    {
        string scope = string.Empty;
        if (includeSubfolder)
        {
            scope = "Scope='RecursiveAll'";
        }

        using (var clientContext = new ClientContext(siteUrl))
        {
            List list = clientContext.Web.Lists.GetByTitle("Product");
            CamlQuery query = new CamlQuery();
            query.ViewXml = string.Format(@"<View {0}>
                                <Query>
                                    <Where>
                                    <Contains>
                                        <FieldRef Name='ProductName'/>
                                        <Value Type='Text'>{1}</Value>
                                    </Contains>
                                    </Where>
                                </Query>
                                </View>", scope, productName);
            ListItemCollection listItems = list.GetItems(query);
            clientContext.Load(listItems, li => li.Include(pi => pi.Id, pi => pi["ProductName"], pi => pi["ProductDescription"], pi => pi["AvailableQuantity"], pi => pi["LaunchDate"]));
            clientContext.ExecuteQuery();

            foreach (var productItem in listItems)
            {
                var product = new Product();
                product.AvailableQuantity = Convert.ToInt32(productItem["AvailableQuantity"]);
                product.LaunchDate = Convert.ToDateTime(productItem["LaunchDate"]);
                product.ProductDescription = productItem["ProductDescription"].ToString();
                product.ProductID = productItem.Id;
                product.ProductName = productItem["ProductName"].ToString();
                products.Add(product);
            }
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception.Message);

    }
    return products;
}
You can notice that I have passed the fields I want to load as per the query result in ClientContext.Load’s li.Include extension method. If you want to load all properties then you can call the Load method in a way as shown below:
clientContext.Load(listItems, li => li);

If you don’t specify a field to load but try to access it then you will get an exception of type ‘PropertyOrFieldNotInitializedException’ with the following message:
The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.