Tuesday 22 December 2015

Client OM Architecture / Client Object model in sharepoint 2010




As can be seen in the above diagram all versions of the Client OM go through the WCF Web Service named Client.svc. This Web Service is located, along with all other SharePoint Web Services, in the folder [SharePoint Root]\ISAPI. The Client OM is responsible for packaging any requests into XML and calling the Web Server, however, when this call takes place is controlled by the developer as you will see. The response from the Client.svc Web Service is sent as JSON and the Client OM is responsible for transforming this into appropriate objects for use in the environment the call was made from.

                        /Client.svc/ProcessQuery                                      


The Client.svc Web Service has one method, ProcessQuery which takes a Stream object, an XML formatted stream as indicated above, and returns a Stream, JSON formatted

The implementation for this method can be found in the assembly Microsoft.SharePoint.Client.ServerRuntime.dll and the private class ClientRquestServiceImpl. Delving into this method, the first thing you find is an authentication check.

When would I use Feature upgrade?


Feature upgrade is useful in the following scenarios (though there may be more!):
  • To make changes to existing site collections or sites, or something inside – for example:
    • Making changes to existing items e.g. adding a new column to a content type/list
    • Adding new elements to existing sites e.g. a new list
    • Any change which involves doing something to a site using the API e.g. using code to modify the navigation settings for many sites
  • To add new functionality into an existing Feature, rather than create a new one – perhaps because that’s the most logical factoring
  • Where some functionality will be upgraded several times during its lifecycle, possibly in a situation where the changes are not rolled out to every site, or are rolled out at different times


Monday 21 December 2015

Using CAML to query Sharepoint lists over Lookup fields

When lookup fields are created, SharePoint stores them as ID;#Value format in related list.

For example, in the list “Contacts” there is column called “Country”. There is item in contact with value “India” assigned in Country, having item ID=10.
Now for another list “List2” when column “Country” is stored as Lookup column named “refCountry”; and for certain data item “India” is selected from combo box, SharePoint stores it in,
10;#India in  “List 2” -> “refCountry” column

List Name:                          List1                                       List2
Column Name:                  Country                               refCountry à lookup for the “country” in list1
Column Value:                   India                                      10;#India

When we query List2 using CAML, The typical query looks like
<Query>
<Where>
<Eq>
<FieldRef Name=”RefCountry”  />
<Value Type=”Lookup”>India</Value>
</Eq>
</Where>
</Query>

The disadvantage of this way is, If the list Contacts is having more than one entry (item or row) having value India for Country it will return the only first one. This may give inconsistent data for further.
To avoid this query should be based on ID not by Value.
This can be achieved through:

<Query>
<Where>
<Eq>
<FieldRef Name=”RefCountry” LookupId=”TRUE” />
<Value Type=”Lookup”>10</Value>
</Eq>
</Where>
</Query>


where 10 is the ID for item having country=”India”

Create and Deploy Custom Timer Job Definition in SharePoint Programatically

What is Timer Job?
Timer Job is a background process that is run by SharePoint on specific time intervals.
In Central Administration, select Monitoring link from the main page, and then select Review job definitions link under the Timer Jobs section, then you will see the list of scheduled timer job definitions.
Central Administration à Monitoring à Timer Jobs  à Review job definitions 

How to Create Custom Timer Job?
It is as simple as inheriting a class and override the existing function.
Basic steps involved in creating and deploying timer jobs are:
1.        Create a class and inherit from “SPJobDefinition”
2.       Ensure that the below namespaces are added to you file.
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
3.       Add the following constructors
public CustomTimerJob() : base() { }

public CustomTimerJob(string jobName, SPService service):
          base(jobName, service, null, SPJobLockType.None)
{
    this.Title = "Your timer job name";
}

public CustomTimerJob(string jobName, SPWebApplication webapp):
        base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
    this.Title = " Your timer job name";
}

4.      Override the Execute() method to do your stuff. Whenever timer job executes, it will run the code written inside Execute() method.
public override void Execute(Guid targetInstanceId)
{
                    SPWebApplication webApp = this.Parent as SPWebApplication;
                    // write down your code here
}


Registering/Deploying Timer Job Definition
5.       Add a new feature to register our custom timer job.
6.      Give Scope this feature to "Web Application".
7.       For this, double click on CustomTimerJobFeature  and choose scope "Web Application". Now press F4 so it will open property window of feature. Select False in "Activate on Default".
8.      Add Feature event receiver for this feature. Right click on CustomTimerJobFeature and select "Add Event Receiver".
9.      Write the following code to CustomTimerJobFeatureEventReceiver.cs class.
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
namespace TimerJobApplication.Features.CustomTimerJobFeature
{
[Guid("e6ea0027-1187-419d-b357-306244d0ae37")]
    public class CustomTimerJobFeatureEventReceiver : SPFeatureReceiverimer
    {
        const string JobName = "New Task Timer";
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                    SPSite site = properties.Feature.Parent as SPSite;
                    DeleteExistingJob(JobName, parentWebApp);
                    CreateJob(parentWebApp); 
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private bool CreateJob(SPWebApplication site)
        {
            bool jobCreated = false;
            try
            {
                CustomTimerJob job = new CustomTimerJob(JobName, site);
                SPMinuteSchedule schedule = new SPMinuteSchedule();
                schedule.BeginSecond = 0;
                schedule.EndSecond = 59;
                schedule.Interval = 15;
                job.Schedule = schedule;
 
                job.Update();                
            }
            catch (Exception)
            {
                return jobCreated;
            }
            return jobCreated;
        }
        public bool DeleteExistingJob(string jobName, SPWebApplication site)
        {
            bool jobDeleted = false;
            try
            {
                foreach (SPJobDefinition job in site.JobDefinitions)
                {
                    if (job.Name == jobName)
                    {
                        job.Delete();
                        jobDeleted = true;
                    }
                }
            }
            catch (Exception)
            {
                return jobDeleted;
            }
            return jobDeleted;
        }
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
 
            lock (this)
            {
                try
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                        DeleteExistingTimerJobFromSite(this.JobName, parentWebApp);
                    });
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
    }
}
 
10.    Deploy the solution and activate the timerjob feature.
 
11.     Go to the Review Timer job page and check your timerjob.

 To debug the timer job, follow the below link.
http://jaysp2010.blogspot.in/2015/03/debugging-timer-job-in-sharepoint-2010.html