Advantages and Disadvantages of Client Object Model

I have been implementing Client Object Model (COM) extensively in Silverlight as well as in ECMAScript. I have failed many times in accomplishing certain tasks and succeeded many times too. You may love or hate COM but you cannot ignore it if you are a SharePoint 2010 developer.

So, I’m going to list out the advantages and disadvantages of COM that I have been facing while implementing it. Let us look at the advantages first.

Advantages:

  1. As mentioned everywhere using COM we can access the SharePoint data from the client side browser itself with Silverlight and ECMAScript applications.
  2. Web parts with very rich user interface can be developed with the help of Silverlight and jQuery. For example, we can create web parts like video and image galleries with beautiful animations where the videos and the images can be stored in the SharePoint libraries and retrieved using COM.
  3. COM along with JavaScript or jQuery can be implemented with just a Content Editor Web part within the browser or from the SharePoint designer without opening the Visual Studio. You can read about it here on how to do that.
  4. When we save your site as a template. The application developed with ECMAScript or Silverlight application implemented with Client Object Model would come along with the template which would be very helpful during migrations though we need to take care of any hard coded values.
  5. No IISREST is required while deploying a Silverlight or an ECMAScript application implemented with COM.
  6. We can have SharePoint accessed from the client desktop using Windows forms or WPF applications implemented with COM. We can develop desktop gadget kind of applications which would be displaying the new announcements added to the “Announcements” list.
  7. No SharePoint installation is required in the development machine. Only the dll’s are required if you are going to develop Silverlight applications.

Disadvantages:

  1. We cannot elevate the privilege or Impersonate in COM as in Server Object Model. That is, we cannot use the RunWithElevatedPrivilege kind of a delegate. Therefore, the results retrieved using COM will always be security trimmed by default.
  2. The range of classes available to access SharePoint data is very limited in COM. For example, we do not have Classes for accessing User Profiles. We need to go for SharePoint web services.
  3. We cannot access the objects of another site collection in COM while implementing in Silverlight or in ECMAScript. We will get “The security validation for this page is invalid.” if we try to do so. So, we cannot develop applications to read the data from another site collection.
  4. Silverlight web parts fail to load by giving an error message saying Could not download the Silverlight application or the Silverlight Plugin did not load. To re-configure the Web Part or to provide a different Silverlight application (.xap), open the tool pane and then click Configure.when it takes more than 5 seconds to load.
  5. We cannot retrieve recurring events from a SharePoint calendar list in Client Object Model.

These are the advantages and disadvantages that I have faced. I will update more when I face any.

SharePoint Caveats – 2: Generating CAML query from LINQ to SharePoint

I was always thinking about how to compare 2 fields(columns) of a SharePoint list using CAML queries. But got to know that it can be accomplished using LINQ to SharePoint but not CAML. I have also blogged about it over here. You can read this blog on how to use the LINQ to SharePoint feature to query SharePoint lists. But it is said that the LINQ query itself would get converted in to a CAML query at run time. I saw this blog which explains about how to write a CAML query generated from LINQ to SharePoint in to a text file.

So, I thought of writing a LINQ query to compare 2 fields(columns) and see what CAML query gets generated from it. I wrote the below program which compares 2 fields(columns) in an SP List called Spwitter using LINQ to SharePoint and logs the CAML query to an XML file.

using (var dataContext = new MySPDataContext("http://localhost:1446/"))
            {
                    TextWriter textWriter = new StreamWriter(@"c:\caml.xml", false);
                    dataContext.Log = textWriter;
                    var result = from c in dataContext.SpwitterList
                                 where  c.Title != c.Spweet
                                 select c;

                    foreach (var item in result)
                    {
                        System.Console.WriteLine("{0}----{1}", item.Title, item.Spweeter);
                    }
           }

I opened the caml.xml file with an excitement to see what CAML query has got generated for comparing 2 fields(columns) and saw the below query in it 😦 which does not have anything related to comparing 2 SharePoint list fields.

<View>
  <Query>
    <Where>
      <BeginsWith>
        <FieldRef Name="ContentTypeId" /><Value Type="ContentTypeId">0x0100</Value>
      </BeginsWith>
    </Where>
  </Query>
  <ViewFields>
    <FieldRef Name="Spweet" /><FieldRef Name="Spweeter" />
    <FieldRef Name="ImageURL" /><FieldRef Name="ID" />
    <FieldRef Name="owshiddenversion" />
    <FieldRef Name="FileDirRef" />
    <FieldRef Name="Title" />
  </ViewFields>
  <RowLimit Paged="TRUE">2147483647</RowLimit>
</View>

Grand total in a Silverlight DataGrid

I see that my post here about creating Summary rows(sub totals) in  a Silverlight datagrid is getting a lots of hits. So, I have decided to write another post on getting Grand total in a Silverlight datagrid.

Let us get in to the action.

The below application that we are going to build is going to display Datagrid with data about the revenues of each Restaurant and finally the total Revenue value of all the Restaurants.

1. Create a Silverlight project. Add a DataGrid in to the MainPage.xaml.

2. Create a class called Revenue and add Properties in to it like Restaurant and Revenue as shown below.

<br /><%%KEEPWHITESPACE%%>  public class Revenues<br /><%%KEEPWHITESPACE%%>    {<br /><%%KEEPWHITESPACE%%>        public string Restaurant { get; set; }<br /><%%KEEPWHITESPACE%%>        public decimal Revenue { get; set; }<br /><%%KEEPWHITESPACE%%>    }<br />

3. Now, lets use ObservableCollection and add data to our Revenue class created above through ObservableCollection in the MainPage Constructor .
ObservableCollection(NameSpace : System.Collections.ObjectModel)

<br /><%%KEEPWHITESPACE%%>            OCRevenues.Add(new Revenues() { Restaurant = "McDonalds", Revenue = 3000 });<br /><%%KEEPWHITESPACE%%>            OCRevenues.Add(new Revenues() { Restaurant = "KFC", Revenue = 1000 });<br /><%%KEEPWHITESPACE%%>            OCRevenues.Add(new Revenues() { Restaurant = "Pizza Hut", Revenue = 12000 });<br />

4. Now, in order to calculate the Grand total of the values in the Revenues column, put the below line of code.

<br /><%%KEEPWHITESPACE%%>           OCRevenues.Add(new Revenues() { Restaurant = "Grand Total", Revenue = OCRevenues.Sum(o =&gt; o.Revenue) });<br />

5. In the above line we are adding a new data item to OCRevenues ObservableCollection with Restaurant value as “Grand Total”, and the Revenue value to be the sum of all the Revenue values in the OCRevenues using lambda expression.

6. Build and compile the application, you will get the output as shown below.

Untitled

7. Let us make it little a bit more attractive by coloring the Grand Total row alone grey, so that it gets highlighted.

8. This can be achieved by attaching a LoadingRow event to the DataGrid. So, attach LoadingRow event to the DataGrid and then in the event handler write the following code.

<br /><%%KEEPWHITESPACE%%>    private void dgGrandTotal_LoadingRow(object sender, DataGridRowEventArgs e)<br /><%%KEEPWHITESPACE%%>        {<br /><%%KEEPWHITESPACE%%>            Revenues revenueDetails = e.Row.DataContext as Revenues;<br /><br /><%%KEEPWHITESPACE%%>            if (revenueDetails.Restaurant.Contains("Grand Total"))<br /><%%KEEPWHITESPACE%%>            {<br /><%%KEEPWHITESPACE%%>                e.Row.Background = new SolidColorBrush(Colors.DarkGray);<br /><%%KEEPWHITESPACE%%>            }<br /><%%KEEPWHITESPACE%%>        }<br />

9. In the above coding we are checking if the value of the Restaurant property in the current row is “Grand Total” and then giving the row a Dark grey background. Once you build and execute the application you will get an output as shown below.

Untitled

Advantages and Disadvantages of LINQ to SharePoint over CAML Queries

The LINQ to SharePoint functionality which was available as a third party tool for free in codeplex for MOSS 2007 is available as an inbuilt functionality in SharePoint Server 2010.

I’m not going define what LINQ to SharePoint is as it is out of the scope of this post. I’m going to list out the advantages and the disadvantages of LINQ to SharePoint over CAML queries that I have been facing (though there are lots of blogs covering this topic). Let us see the advantages first.

Advantages:

1. As mentioned everywhere it provides strongly typed objects using which we get intellisense while coding. So, our code will be more bugs free unlike the CAML Queries where the result will be known only in the run time.

2. One more advantage not mentioned generally is that we can compare two columns (fields) of a SharePoint list in LINQ queries which is not possible in CAML queries.

3. We can also use LINQ to SharePoint to generate some complex CAML queries as shown in this blog

Disadvantages:

1. During the run time the LINQ query itself would get converted in to a CAML query which is an extra step ahead that takes some more time, which can be avoided if we straight away write a CAML query itself.

2.  Also, we generate a DataContext class using the SPMetal.exe. This class is the one which we use in our project to generate LINQ queries. This class does not get generated dynamically. So, if we do any changes in any of the lists or libraries in our site it does not get reflected in the DataContext class. So every time we have to generate a new class whenever we make any changes in the site.

3. LINQ to SharePoint has no use if we are going to access SharePoint data in Silverlight using Client Object Model unlike CAML queries.

4. Default fields like Created, CreatedBy, Modified and ModifiedBy of a SharePoint list are not created by SPMetal to be used in the LINQ queries.
Update: This article describes on how to achieve this.

5. LINQ to SharePoint cannot be implemented for an External list.

Getting the total number of characters (count) from a Silverlight text box.

Let’s say that we have a requirement where we should restrict the users to enter only a certain number of characters (let’s say 150) in a TextBox of a Silverlight usercontrol. We will see how to achieve that in Silvelright.

1. Create a Silverlight project and add a Text Box in to it as shown below.


<TextBox Height="100" Width="600" FontSize="20" HorizontalAlignment="Left" TextChanged="tbPost_TextChanged" Name="tbPost" AcceptsReturn="True" TextWrapping="Wrap" VerticalAlignment="Top"  />

as seen above we have set its height and width to a large number to make it look like a RichTextBox, we have also added a Event Handler called tbPost_TextChanged for TextChanged Event and also the AcceptsReturn has been set to true for multiline functionality.

2. Add a TextBlock below the TextBox to display the number of characters being entered in to the TextBox.

<TextBlock FontFamily="Tahoma" Name="tblkCharLeft" Width="150" HorizontalAlignment="Left" FontSize="12" FontWeight="Light" >
 </TextBlock>

3. In the MainPage.xaml.cs write the following code in the tbPost_TextChanged  event.

private void tbPost_TextChanged(object sender, TextChangedEventArgs e)
        {
            count = 150 - tbPost.Text.Count();
            tblkCharLeft.Text = Convert.ToString(count);

            tblkCharLeft.Foreground = count  > 150 ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Black);
        }

4. In the above code, we are getting the number of characters in the Text Box and subtracting it from 150(which is the total number of characters allowed) and storing the result in an Integer variable called count. And then display the number in the Text Block.

5. In the last line we are changing the Foreground of the Text block to Red color after checking if the value of the integer variable count is greater than 150 using tertiary operator.

6. When you build and run the application. You can see that, as you type in the text box the number of characters in the text box gets displayed in the text block.

7. The color of the text in the text block gets changed when the number goes more than 150 as shown in the below screenshot.

Untitled