Wednesday, October 19, 2011

Client Object Model Use Nesting Include To Improve Performance

In Client Object Model if we want to call LoadQuery method, we can specify multiple levels of properties to load. This will help in reducing the number of round trips to the server to retrieve the required Data. Now below example retrieve all lists and associated fields. This will print on console if list or field is hidden.


Download Working Example



 static void Main(string[] args)
        {
            ClientContext _context = new ClientContext("http://anmol-pc");
            
            IEnumerable<List> allLists = _context.LoadQuery(
                _context.Web.Lists.Include(
                    myList => myList.Title,
                    myList => myList.Hidden,
                    myList => myList.Fields.Include(
                        myField => myField.Title,
                        myField => myField.Hidden)));


            _context.ExecuteQuery();


            foreach (List myList in allLists)
            {
                Console.WriteLine("{0}List: {1}",
                    myList.Hidden ? "Hidden " : "", myList.Title);
                foreach (Field myField in myList.Fields)
                    Console.WriteLine("  {0}Field: {1}",
                        myField.Hidden ? "Hidden " : "",
                        myField.Title);
            }


            Console.ReadLine();
        }

Tuesday, October 18, 2011

Client Object Model Access Large Lists

If you want retrieve large list using Client Object Model. You can use the ListItemCollectionPosition class to implement paging list item retrieval according to the position of items relative to their collection. Use the RowLimit element to specify the number of items to return per page.


Download Working Example



 static void Main(string[] args)
        {
            ClientContext clientContext = new ClientContext("http://anmol-pc");


            List list = clientContext.Web.Lists.GetByTitle("Tasks");


            ListItemCollectionPosition itemPosition = null;
            while (true)
            {
                CamlQuery camlQuery = new CamlQuery();
                camlQuery.ListItemCollectionPosition = itemPosition;
                camlQuery.ViewXml = @"<View>
                                        <ViewFields>
                                          <FieldRef Name='Title'/>
                                        </ViewFields>
                                        <RowLimit>1</RowLimit>
                                      </View>";


                ListItemCollection listItems = list.GetItems(camlQuery);
                clientContext.Load(listItems);
                clientContext.ExecuteQuery();
                
                itemPosition = listItems.ListItemCollectionPosition;
                
                foreach (ListItem listItem in listItems)
                    Console.WriteLine("Item Title: {0}", listItem["Title"]);
                
                if (itemPosition == null)
                    break;
                
                Console.WriteLine(itemPosition.PagingInfo);
                Console.WriteLine();
            }


            Console.ReadLine();
        }

Monday, October 10, 2011

Safe Control Entries in Web Config File

There may come a situation where we want to add a custom new safe control entry in web.config file. 


Create New Empty SharePoint Project.


Add new "Empty Element" in project.


Select the newly created element and press F4 to open properties window.


Click ellipse button against the "Safe Control Entries" property as shown in below image.




The safe control entry dialog opens as shown below.




Click "Add" This will add a new safe control entry. Set properties 
Name: name of safe control entry
Assembly: A strong assembly name, such as: MyFirstProject.MyFirstAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=11e9bce111e9418c.
NameSpace: The fully-qualified namespace for the class/control
Safe: True



Add as many entries as you like.

SharePoint Using Custom Page with visual web part as Default View

Download Sample Project


We may encounter a situation where we want a custom view to show list and another web part on same page.  To achieve this on custom list definition created using visual studio, we need to follow the instructions listed below.

Create new "Empty SharePoint Project". Use trust level as "Deploy as Farm Solution".

Add new "List Definition" named "CustomListDefinition". Choose type of List Definition as "Custom List" or whatever you require.

Add new mapped folder "Template\Layouts"

Add new folder in Layouts folder named "CustomDefaultView". Add new Application page named "CustomListForm.aspx" inside this folder.

Add new Visual web part named "MyVisualWebpart". Design your visual web part as required.

Now edit "CustomListForm.aspx". Remove "AutoEventWireup" and "CodeBehind" attributes from Page directive. In code behind file inherit your page from "WebPartPage" instead of LayoupPageBase. 

Register "Microsoft.SharePoint.WebPartPages" namespace as 


<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


Register your visual part inside webpage as 

<%@ Register Tagprefix="MyWebParts" Namespace="CustomDefaultView.MyVisualWebpart" Assembly="$SharePoint.Project.AssemblyFullName$" %>

Inside PlaceHolderMain add this code


<MyWebParts:MyVisualWebpart runat="server" ID="SearchIndividualsWebPart" >

        </MyWebParts:MyVisualWebpart>

Add web part zone below the above line

 <WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" />

Open "Schema.xml" file under "CustomListDefinition". Find View Element  as highlighted in below image

now replace SetupPath="pages\viewpage.aspx"  with 
SetupPath= "layouts\CustomDefaultView\CustomDefaultView.aspx".

We replaced "pages\viewpage.aspx" this with our custom layout page. So now the when list default view is created SharePoint will use our custom layout page.

Now we need to register our custom aspx page in web.config as safe control. For this create "Empty Element". Select empty element and press F4 to open properties window. In Safe Control Entries property dialog create your safe entry. For more information on this visit Safe Control Entries in Confog File.

Build your project and deploy. Now create new List from your custom definition. You will see visual web part over the list. 

Thursday, October 6, 2011

How to create Terms and Term Set programmatically (using code)?

How to create Terms and Term Set programmatically?

Add reference of "Microsoft.SharePoint.Taxonomy" assembly to your project. Include namespace "Microsoft.SharePoint.Taxonomy". And use the code as listed below.


 using (SPSite site = new SPSite("http://anmol-pc"))
            {
                TaxonomySession _TaxonomySession = new TaxonomySession(site);

                //Get instance of the Term Store 
                TermStore _TermStore = _TaxonomySession.TermStores["My Term Store"];

                //Now create a new Term Group
                Group _Group = _TermStore.CreateGroup("My New Group");

                //Create a new Term Set in the new Group
                TermSet _TermSet = _Group.CreateTermSet("My New Termset");

                //Add terms to the term set
                Term _term1 = _TermSet.CreateTerm("First Term", 1033);
                Term _term2 = _TermSet.CreateTerm("Second Term", 1033);
                Term _term3 = _TermSet.CreateTerm("Third Term", 1033);
                Term _term4 = _TermSet.CreateTerm("Last Term", 1033);

                //commit changes
                _TermStore.CommitAll();

            }

Tuesday, October 4, 2011

How to create SharePoint Views (SPView) Programmatically?

How to create SharePoint Views (SPView) Programmatically?

Please see below code:

SPWeb web = SPContext.Current.Web;
SPList list = web.Lists["My List"];

SPViewCollection allListViews = list.Views;
string viewName = "My New View";

StringCollection newviewFields = new StringCollection();
viewAllContactFields.Add("Edit");
viewAllContactFields.Add("LinkTitleNoMenu");
viewAllContactFields.Add("Field1");
viewAllContactFields.Add("Field2");
viewAllContactFields.Add("Field3");


string myquery = "<OrderBy><FieldRef Name='LinkTitle' Ascending='TRUE' /><FieldRef Name='EffectiveDate' Ascending='TRUE' /></OrderBy>";

allListViews.Add(viewName, newviewFields, myquery, 30, true, false);

Monday, October 3, 2011

Using People Picker control in edit web part Properties

How to use People Picker control in edit web part Properties?

First Create a "Empty SharePoint Project". Add New "Web Part" named "TestWebpart". Create a new webpart property in this, as shown below.

private string _ImpersonateUser = null;

[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(false)]
[System.ComponentModel.Category("Custom Properties")]
[WebDisplayName("Impersonate User")]
[WebDescription("User for impersonation")]
        public string ImpersonateUser
        {
            get
            {
                return _ImpersonateUser;
            }
            set
            {
                _ImpersonateUser = value;
            }
        }


Leave this as it is, we will come back to this again.


Add new class named "PeoplePickerEditor.cs" to this project. Your class should look like:

namespace SP.Anmol.Customization
{
    public class PeoplePickerEditor: EditorPart
    {
        private PeopleEditor _peoplePicker;

        public PeoplePickerEditor(string webPartID)
        {
            this.ID = "PeoplePickerEditor" + webPartID;
            this.Title = "Impersonate User";
        }


        protected override void CreateChildControls()
        {
            _peoplePicker = new PeopleEditor();
            _peoplePicker.ID = "pe1";
            _peoplePicker.AllowTypeIn = true;
            _peoplePicker.AllowEmpty = false;
            _peoplePicker.MultiSelect = false;
            _peoplePicker.Width = Unit.Pixel(250);
            _peoplePicker.SelectionSet = PeopleEditor.AccountType.User.ToString();

            Controls.Add(_peoplePicker);
        }


        public override bool ApplyChanges()
        {
            EnsureChildControls();
            TestWebpart.TestWebpart webPart = WebPartToEdit as TestWebpart.TestWebpart;
            if (webPart != null)
            {

                //set value of web part property
                webPart.ImpersonateUser = _peoplePicker.CommaSeparatedAccounts;
            }
            return true;
        }


        public override void SyncChanges()
        {
            EnsureChildControls();
            TestWebpart.TestWebpart webPart = WebPartToEdit as TestWebpart.TestWebpart;
            if (webPart != null)
            {

                //set value back to people picker control
                _peoplePicker.CommaSeparatedAccounts = webPart.ImpersonateUser;
            }
        }


    }
}

Now get back to web part code file. Implement the interface IWebEditable. Your web part code looks like:

namespace SP.Anmol.TestWebpart
{


    [Guid("84B6AF3B-9BA4-440A-AA4A-9657A5D67798")]
    public class TestWebpart : Microsoft.SharePoint.WebPartPages.WebPart, IWebEditable
    {
        public AnonymousUpload()
        {
            this.ExportMode = WebPartExportMode.All;
        }

      
        private string _ImpersonateUser = null;

      
        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(false)]
        [System.ComponentModel.Category("Custom Properties")]
        [WebDisplayName("Impersonate User")]
        [WebDescription("User for impersonation")]
        public string ImpersonateUser
        {
            get
            {
                return _ImpersonateUser;
            }
            set
            {
                _ImpersonateUser = value;
            }
        }

      
        protected override void CreateChildControls()
        {
                 //Place your logic here
        }


 

        //Methods to be implement for interface IWebEditable        EditorPartCollection IWebEditable.CreateEditorParts()
        {
            List<EditorPart> editors = new List<EditorPart>();
            editors.Add(new PeoplePickerEditor(this.ID));

            return new EditorPartCollection(editors); 
        }

        object IWebEditable.WebBrowsableObject
        {
            get { return this; }
        }


    }
}

Sunday, October 2, 2011

Client Object Model Exception Handling Scope

When we perform the operations on client side, we need to make a require to execute some operations that depend on the presence of an exception or not. We all have used try and catch blocks so far.
Lets take an example to understand: if you want to access a specific list in the SharePoint 2010 site in order to modify its property to allow Folder creation and versioning.

public void AllowFolderAndVersionCreation(string listName)
        {
            ClientContext context = new ClientContext("
http://anmol-pc");
            using (context)
            {
                List myList = null;
                try
                {
                    myList = context.Web.Lists.GetByTitle(listName);
                    context.Load(myList);
                    context.ExecuteQuery();

                }
                catch
                {
                    ListCreationInformation info = new ListCreationInformation();
                    info.Title = listName;
                    info.TemplateType = (int)ListTemplateType.GenericList;

                    myList = context.Web.Lists.Add(info);
                    context.ExecuteQuery();
                }
                finally
                {
                    myList.EnableVersioning = true;
                    myList.EnableFolderCreation = true;
                    myList.Update();
                    context.ExecuteQuery();
                }

            }
        }



Issue with Try and Catch Block
If you see the above i am first trying to get a list by Title in try block, and if list not found in catch block i tried to create a new list and Then in finally block i updated "EnableFolderCreation", "EnableVersioning" properties of list. To acheive this I require to send three commands to the server. So in SharePoint 2010 Client Object Model it is not convenient to use the try and catch blocks in the operations. The reason why is very easy to understand: we are in a client-side context and we have to pay attention to the number of queries to the server in order to execute our operations.

How ExceptionHandlingScope comes to rescue?
SharePoint 2010 Client object Model provides a class ExceptionHandlingScope for exception management. It exposes basic four methods StartScope(), StartTry(), StartCatch() and StartFinally().
Exception Handling scope begins with Startscope() and other three as three difrent sections inside

 public void AllowFolderAndVersionCreation(string listName)
        {
            var context = new ClientContext("
http://anmol-pc");
            var _ExceptionHandlingScope = new ExceptionHandlingScope(context);

            using (_ExceptionHandlingScope.StartScope())
            {
                using (_ExceptionHandlingScope.StartTry())
                {
                    // the code you want to try
                }
                using (_ExceptionHandlingScope.StartCatch())
                {
                    //code to run on error
                }
                using (_ExceptionHandlingScope.StartFinally())
                {
                    // the code that will execute finally
                }

           }
    }

lets place our example code inside this structure


public static void AllowFolderAndVersionCreation(string listName)
        {
            var context = new ClientContext("
http://anmol-pc");
            var _ExceptionHandlingScope = new ExceptionHandlingScope(context);
            List myList = null;

            using (_ExceptionHandlingScope.StartScope())
            {
                using (_ExceptionHandlingScope.StartTry())
                {
                    myList = context.Web.Lists.GetByTitle(listName);
                    context.Load(myList);
                    // context.ExecuteQuery() not required here
                }
                using (_ExceptionHandlingScope.StartCatch())
                {
                    ListCreationInformation info = new ListCreationInformation();
                    info.Title = listName;
                    info.TemplateType = (int)ListTemplateType.GenericList;
                    myList = context.Web.Lists.Add(info);
                    // context.ExecuteQuery() not required here
                }
                using (_ExceptionHandlingScope.StartFinally())
                {
                    myList.EnableVersioning = true;
                    myList.EnableFolderCreation = true;
                    myList.Update();
                    // context.ExecuteQuery() not required here
                }
            }
            context.ExecuteQuery();
        }


So you can notice that same thing can be acheived using ExceptionHandlingScope using less calls to the server.


Use of the "Try and catch" block:
  • Definetly more than 1 call
  • The debug operations are more complicated.
  • Easily understandable code as we are known to this type of code.
     
Use of the "ExceptionHandlingScope" class:
  • With one call to server we can acheive our goal.
  • The debug operations are much easier.
  • The code may not look that clear.

Client Object Model Add,Update and delete List Items

Creating, Updating, Deleting List items using Client Object Model, is almost similar to doing this using Server Object Model.

Create List Items
Create List item, set its properties and update the object.

string siteUrl = "http://anmol-pc";
ClientContext clientContext = new ClientContext(siteUrl);
SP.List oList = clientContext.Web.Lists.GetByTitle("Test");

ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = oList.AddItem(itemCreateInfo);
oListItem["Title"] = "My First Item!";
oListItem["FirstName"] = "Anmol Rehan";

oListItem.Update();
clientContext.ExecuteQuery();
//-----------------------------------------------------------------------------------------------

Update List Items
To update List item, get the item by id using GetById() method. Then set the properties and update the object.

string siteUrl = "http://anmol-pc";
ClientContext = new ClientContext(siteUrl);
SP.List oList = clientContext.Web.Lists.GetByTitle("Test");

ListItem oListItem = oList.GetItemById(6);
oListItem["FirstName"] = "Anmol";
oListItem["LastName"] = "Rehan";
oListItem.Update();

clientContext.ExecuteQuery();

//-----------------------------------------------------------------------------------------------

Delete List Item
To update List item, get the item by id using GetById() method. Then call objects deletion method DeleteObject().

string siteUrl = "http://anmol-pc";
ClientContext = new ClientContext(siteUrl);
SP.List oList = clientContext.Web.Lists.GetByTitle("Test");

ListItem oListItem = oList.GetItemById(6);
oListItem.DeleteObject();
clientContext.ExecuteQuery();

Popular Posts