Monday, June 16, 2014

CSOM in Sharepoint 2013


CSOM made accessible through client.svc

Direct access to client.svc not supported

Calls to client.svc must go through supported entry points

Supported entry points:
Silverlight
JavaScript
.NET


In Sharepoint 2013 Client.svc is extented to REST(HTTP GET, PUT, POST requests) API also.

that means Client.svc is accepts HTTP GET, PUT, POST requests

OData Protocal is also implemented.

Sharepoint 2013  CSOM Support following server side functionality.

User Profiles

Search

Taxonomy

Feeds

Publishing

Sharing

Workflow

E-Discovery

IRM

Analytics

Business Data



Sharepoint 2010 CSOM diagram:




Sharepoint 2013 CSOM Diagram:


ListData.svc added REST support for reading & writing to SharePoint lists in SharePoint 2010

it is still present in SP 2013 for backward capability.

SP 2013 new development is done through REST or OData API.



In Sharepoint 2010 CSOM Development following DLL we need to add

Microsoft.Sharepoint.Client.dll
Microsoft.Sharepoint.Client.Runtime.dll

in Sharepoint 2013 CSOM Development( REST   is new features).


Microsoft.Sharepoint.Client.dll
Microsoft.Sharepoint.Client.Runtime.dll

Microsoft.Sharepoint.Client.DocumentManagement.dll
Microsoft.Sharepoint.Client.Publishing.dll
Microsoft.Sharepoint.Client.Taxonomy.dll
Microsoft.Sharepoint.Client.UserProfiles.dll


Example :

            ClientContext SSite = new ClientContext("http://localhost");
            SSite.Credentials = CredentialCache.DefaultCredentials;
            Web site = SSite.Web;
            ListCollection lists = site.Lists;

            // load site info

            SSite.Load(site, SiteTitle => SiteTitle.Title);
            SSite.ExecuteQuery();
            Console.WriteLine("Site Title: " + site.Title);
         
            // create list

            ListCreationInformation newList = new ListCreationInformation();
            newList.Title = "Clients";
            newList.Url = "Lists/Clients";
            newList.QuickLaunchOption = QuickLaunchOptions.On;
            newList.TemplateType = (int)ListTemplateType.Contacts;
            site.Lists.Add(newList);

             // lists collection
            SiteTitle.Load(lists);


            SiteTitle.ExecuteQuery();
            foreach (List list in lists)
            {
                Console.WriteLine(list.Title);
            }



CSOM Using Java script  :

var ctx;
var web;
var lists;
$(onPageLoad);
function onPageLoad() {
    ExecuteOrDelayUntilScriptLoaded(LoadSiteCSOM, "sp.js");
}
function LoadSiteCSOM() {
    // here we can't pass site URL ,due to cross site scripting.
    
    ctx = SP.ClientContext.get_current();
    web = ctx.get_web();
    ctx.load(web);
    ctx.load(web.get_currentUser());
    lists = web.get_lists();
    ctx.load(lists);
    ctx.executeQueryAsync(onDisplaySiteInfo, onError);
}
function onDisplaySiteInfo() {
    var siteTitle = web.get_title();
    var siteId = web.get_id().toString();
    var siteUrl = web.get_url();
    var currentUser = web.get_currentUser().get_loginName();
}
function onError(sender, args) { alert(JSON.stringify(args)); }


CSOM URL is Changes in with respective Sp2010 and Sp2013

SP 2010 : http://localhost/_vti_bin/client.svc/web

sp 2013 : http://localhost/_api/web

SharePoint 2013 REST and OData fundamentals



OData URIs :











URI has three significant parts – service root URI up to entry point, resource path for SharePoint list or SQL Server table, Query string parameters
Service URL –http://services.odata.org/odata/odata.svc, Resource – category(1)/products, and Query Option – $top=2&$orderby=name
REST URLs in SharePoint 15








Making REST calls with C# and JavaScript for SharePoint 2013
  • Returning ATOM XML vs JSON
    • SharePoint returns REST based data in two formats – ATOM XML and JSON
    • ATOM XML is preferred format in .NET Managed code and JSON is preferred format in JavaScript
    • To get ATOM XML, response use MIME type “application/atom+xml”, This is ideal for .NET managed code, you can also use in JavaScript but use XSLT in conjunction with parsing XML to format it properly
    • To get JSON, response use MIME type “application/json”, ideal in JavaScript in conjunction with jQuery
    • Response data format selected in ACCEPT header, ATOM XML is default option for data format returned by REST based calls in SharePoint, for JSON response, you must pass “application/json” MIME type in ACCEPT header
  • REST Query from Managed code – Tips for making REST calls from managed code
    • in .NET 4.0 or later, use the HTTPWebRequest and HTTPWebResponse objects instead of WebRequest or WebResponse classes which would allow you to specify Accept property for required MIME string
    • Use LINQ-to-XML to get data from XML in response body by loading XML response stream in XDocument object and using XDocument.Descendants method to query data
  • REST Query using JavaScript and jQuery
    • Use #.getJSON to request the JSON response if you are using jQuery
  • Updating using REST based API and Form Digest
    • Updates using REST requires Form Digest to protect against replay attack
    • Form Digest is available on the SharePoint since MOSS 2007 days, Form Digest is a special value created using cryptography, SharePoint Pages have control holding Form Digest
    • The Form Digest control does this by using cryptography to create a special value that is passed to the client browser. This value must be passed back to SharePoint and validated on requests that update objects or content within a SharePoint site
    • Add X-RequestDigest header which includes value of form digest
      • In the Managed code, form digest can be acquired through _vti_bin/sites.asmxand pass it to the REST based call,
      • In the JavaScript, assign the value from the control – $(“#_REQUESTDIGEST).val()
XML Syntax:
ACCEPT = application/atom+xml
JSON  Syntax:
ACCEPT = application/json;odata=verbose
REST calls from Managed code :
           // build request
            Uri uri = new Uri(siteUrl + "/_api/web/lists/getByTitle('Documents')/?&select=Title");
            HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
            request.Credentials = CredentialCache.DefaultCredentials;
            request.Accept = "application/atom+xml";

            // send request

            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            // use LINQ to XML to get data

            XDocument doc = XDocument.Load(response.GetResponseStream());
            XNamespace nsDataService = "http://schemas.microsoft.com/ado/2007/08/dataservices";
            string title = doc.Descendants(nsDataService + "Title").First().Value;
 REST call from Java script :
 $(onPageLoad);
function onPageLoad() {
    $("#GetSiteInfo").click(onGetSiteInfo);
}
function onGetSiteInfo() {
    var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/Web?$select=Title";
    // execute AJAX request
    jqxhr = $.getJSON(requestUri, null, OnDataReturned);
    jqxhr.error(onError);
}
function OnDataReturned(data) {
    var odataResults = data.d
    var siteTitle = odataResults.Title;
    $("#results").html("Title: " + siteTitle);
}
function onError(err) {
    $("#results").text("ERROR: " + JSON.stringify(err));
}
Creating List with Managed code and REST API :
// build request
Uri uri = new Uri(siteUrl + "/_api/web/lists");
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.Accept = "application/atom+xml";
request.Headers["X-RequestDigest"] = FormDigest;
request.Method = "POST";
string body = Properties.Resources.CreateList_atom;
body = body.Replace("@Title", listTitle);
request.ContentLength = body.Length;
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(body);
writer.Flush();
// send request
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Reference : http://nikpatel.net/2012/09/23/whats-new-in-sharepoint-2013-csom-and-rest-apis/

http://msdn.microsoft.com/en-us/library/office/fp142380(v=office.15).aspx




More Information :






Sharepoint Elements :

_spPageContextInfo  this will be very useful while doing app model development.

spPageContextInfo, you’ll find it very helpful when writing SP JavaScript code







By using IE we can inspect  _spPageContextInfo   values.












Sunday, June 15, 2014

Server side Developerment using CAML and Linq

Server side API is only supported in Farm solution and sandbox solution.'

Client side(Sharepoint Apps) code development requires  ECMAScript library such as jQuery or Microsoft AJAX .

Debugging Tools : IE developer Tools, firefox  fire bug adon.

Server side Development :
CAML (Collaborative Application Markup Language (CAML) is an XML-based language)
LINQ (Language-Integrated Query)

Most common object in  CAML  : SpQuery,SpSiteDataQuery

Search API is usefull when you query against cross site or large list.

Example of Spquery :

 
 using (SPWeb web = site.OpenWeb())
            {
               // Build a query.
               SPQuery query = new SPQuery();
               query.Query = string.Concat(
                              "<Where><Eq>",
                                 "<FieldRef Name='Status'/>",
                                 "<Value Type='CHOICE'>Not Started</Value>",
                              "</Eq></Where>",
                              "<OrderBy>",
                                 "<FieldRef Name='DueDate' Ascending='TRUE' />",
                                 "<FieldRef Name=’Priority’ Ascending='TRUE' />",
                              "</OrderBy>");                   

               query.ViewFields = string.Concat(
                                   "<FieldRef Name='AssignedTo' />",
                                   "<FieldRef Name='LinkTitle' />",
                                   "<FieldRef Name='DueDate' />",
                                   "<FieldRef Name='Priority' />");

               query.ViewFieldsOnly = true; // Fetch only the data that we need.
               // Get data from a list.
               string listUrl = web.ServerRelativeUrl + "/lists/tasks";
               SPList list = web.GetList(listUrl);
               SPListItemCollection items = list.GetItems(query);

               // Print a report header.
               Console.WriteLine("{0,-25}  {1,-20}  {2,-25}  {3}",
                  "Assigned To", "Task", "Due Date", "Priority");

               // Print the details.
               foreach (SPListItem item in items)
               {
                  Console.WriteLine("{0,-25}  {1,-20}  {2,-25}  {3}",
                     item["AssignedTo"], item["LinkTitle"], item["DueDate"], item["Priority"]);
               }
            }
         }
 using (SPWeb web = site.OpenWeb())
            {
               // Build a query.
               SPQuery query = new SPQuery();
               query.Query = string.Concat(
                              "<Where><Eq>",
                                 "<FieldRef Name='Status'/>",
                                 "<Value Type='CHOICE'>Not Started</Value>",
                              "</Eq></Where>",
                              "<OrderBy>",
                                 "<FieldRef Name='DueDate' Ascending='TRUE' />",
                                 "<FieldRef Name=’Priority’ Ascending='TRUE' />",
                              "</OrderBy>");                   

               query.ViewFields = string.Concat(
                                   "<FieldRef Name='AssignedTo' />",
                                   "<FieldRef Name='LinkTitle' />",
                                   "<FieldRef Name='DueDate' />",
                                   "<FieldRef Name='Priority' />");

               query.ViewFieldsOnly = true; // Fetch only the data that we need.
               // Get data from a list.
               string listUrl = web.ServerRelativeUrl + "/lists/tasks";
               SPList list = web.GetList(listUrl);
               SPListItemCollection items = list.GetItems(query);

               // Print a report header.
               Console.WriteLine("{0,-25}  {1,-20}  {2,-25}  {3}",
                  "Assigned To", "Task", "Due Date", "Priority");

               // Print the details.
               foreach (SPListItem item in items)
               {
                  Console.WriteLine("{0,-25}  {1,-20}  {2,-25}  {3}",
                     item["AssignedTo"], item["LinkTitle"], item["DueDate"], item["Priority"]);
               }
            }
         }



SpsiteDataQuery:

This is used to get the data frorm multiple list across multiple sites.


SPSiteDataQuery query = new SPSiteDataQuery();
            query.Webs = "<Webs scope='SiteCollection' />";
            query.ViewFields = @"<FieldRef Name='Title' /> <FieldRef Name='FirstName' />";
            query.Query = @"<Where> <FieldRef Name='ContentType'/> <Value Type='Computed'>Contact</Value> </Where>";
            DataTable results = SPContext.Current.Web.GetSiteData(query);
            foreach (DataRow item in results.Rows)
            {
               Console.Write(item["FirstName"].ToString());
            }



Linq query will return IEnumerable<T> interface. Example :


All collection will implement IEnumerable<T>

// string array


String[] Col1 = new string[] { "a", "b", "c" };
// list collection
List<string> Col2 = new List<string>()
{ "a", "b", "c"};
// queue collection
Queue<string> Col3 = new Queue<string>();

Col3.Enqueue("a");Col3.Enqueue("bCol3.Enqueue("c);

Displaycol1(Col1); // This method will  IEnumerable type.
Displaycol1(Col2);
Displaycol1(Col3);




Linq Extension method :

Extension methods feature added to .NET 3.0
Allows developers to extend existing types
LINQ adds extension methods to IEnumerable<T>

Out put of Extension method :










Linq default it provide nearly 50 extension methods .



More Enumerable Methods method are found in : http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods%28v=vs.110%29.aspx




Where Condition in LinQ can be used in following technique.


Anonymous Delegate
Lambda expression
Explicit delegate
 



            IEnumerable<string> cal1, cal2, cal3, cal4;
            cal1 = new List<string>() { "a", "b", "c", "d" };

   // technique : named delegate & WHERE method

            Func<string, bool> delegateFilterMethod = StringHasFourCharacters;
            cal2 = cal1.Where(delegateFilterMethod);
 
    // technique : anonymous delegate
    
            cal3 = cal1.Where(delegate(string value)
            {
                return (value.Length == 4); }
            );
   // technique : lambda
            cal4 = cal1.Where(value => value.text =="txt" );
        }

Linq support  custom object :

class Customer
{
    // Auto-Impl Properties for trivial get and set 
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }
}


OLD way of creaating initial objects 


 Customer c2 =new  customer();
c2.TotalPurchases ="34.45";
c2.Name="text";
c2.CustomerID=20;


New way of creaating initial objects 
Customer c2 =new customer
{
c2.TotalPurchases ="34.45";
c2.Name="text";
c2.CustomerID=20;
};




LinQ Sample Example  : 

 Click Here  : http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b







Linq to Sharepoint  :


SPMetal.exe generate strongly-typed entity classes

Each entity class represents one SharePoint list

SPMetal.exe also generates DataContext class


Some Example :



// Get DataContext from page context
DataContext data = new DataContext(SPContext.Current.Web.Url);

// Get the SharePoint list
EntityList<Customer> Customers = data.GetList<Customer>("Customers");

// Query for customers from London
var londonCustomers = from customer in Customers
                      where customer.City == "London"
                      select customer;

foreach (var londonCust in londonCustomers)
{
    Console.Writeline("id = {0}, City = {1}",
                      londonCust.CustomerId,
                      londonCust.City);
}



The following is an example of using LINQ to add an item to a SharePoint Foundation list




// Get DataContext from page context
DataContext data = new DataContext(SPContext.Current.Web.Url);

// Get the SharePoint list
EntityList<Customer> Customers = data.GetList<Customer>("Customers");

// Create the item to be added
Customer newCustomer = new Customer() { CustomerId=36, City=”Madrid” };

// Mark the item to be added on the next call of Submit
Customers.InsertOnSubmit(newCustomer);

// Submit all changes
data.SubmitChanges();

More information About Linq to sharepoint : http://msdn.microsoft.com/en-us/library/office/ee535491(v=office.14).aspx



Sharepoint 2010\2013 List ,Libraries and Events

Agenda for Sharepoint 2010\2013

1.List Instances
2.Document Libraries
3.Events in SharePoint 2013
4.Server-Side Event Receivers
5.Remote Event Receivers

List instances :

SharePoint 2010 introduced the capability to have a relationship behavior enforced by Lookup columns

New investments:

Projected fields into child lists
Joins
Relational integrity between parent & child lists

Introduces new security considerations and possible issues

Projected Fields

1.Extra field pulled from parent list into view of child list
2.Via browser interface, users add a lookup from another list
3.Then, user can select a secondary lookup field to pull into the child list

Join in List :


1.With relational lists, SharePoint Foundation 2010 added support for joins
2.Joins can only be implemented by developers using the API, CAML or SharePoint Designer

3.Join related properties on SPQuery:

SPQuery.Join
SPQuery.ProjectedFields

4.Maximum number view fields selected for a joined of joins on a list view = 6

     Exception thrown if user tries to select fields from more than six fields from the joined lists
     If no view fields specified (maximal view), only the first 6 pulled

Tip: Use LINQ to SharePoint instead of CAML to join two lists in code

Large List :



SharePoint 2010 added self-monitoring protection against expensive queries

Expensive query: one that returns lots of data

Platform Investments:
Configuration options for administrators per Web application

Site collection & list administrators can request privileged operations (expensive queries)


SPList.IsThrottled: when true, list contains more items than the configured limit to be considered a “large list



Enables developers to ignore query safety checks and run an unsafe query via SPQuery or SPSiteDataQuery

Requires special priv. 2 different limits:

Normal user – 5,000 items
Super user – 20,000 items

Configure time window when to allow expensive queries



Document Library :

SPDocumentLibrary inherits from SPList


SPWeb site = SPContext.Current.Web;

        foreach (SPList list in site.Lists)

{

if (list is SPDocumentLibrary && !list.Hidden)

{

SPDocumentLibrary library = list as SPDocumentLibrary;

SPFolder folder = library.RootFolder;

TreeNode libraryNode = new TreeNode

(

library.Title, library.DefaultViewUrl,
"~/_layouts/15/images/icons/folder.png");

LoadFolderNodes(folder, libraryNode); treeSitesFiles.Nodes.Add(libraryNode);

} }


 
Adding document programmatically :

 SPSite siteCollection = SPContext.Current.Site;
SPWeb site = SPContext.Current.Web;
Guid libraryID = new Guid(lstTargetLibrary.SelectedValue);
SPDocumentLibrary library = site.Lists[libraryID] as SPDocumentLibrary;

String dcumentName = txtFileName.Text;string libraryRelativePath = library.RootFolder.ServerRelativeUrl;
string libraryPath = siteCollection.MakeFullUrl(libraryRelativePath);
string documentPath = libraryPath + "/" + documentName;

Stream documentStream = new MemoryStream();
StreamWriter writer = new StreamWriter(documentStream);
writer.Write(txtDocumentBody.Text);
writer.Flush();

Hashtable docProperties = new Hashtable(); docProperties["vti_title"] = "This is a test title";
docProperties["Color"] = "Green";site.Files.Add(documentPath, documentStream, docProperties, true);

Response.Redirect(libraryPath);



Provisioning Document Libraries
 

<?xml version="1.0" encoding="utf-8"?>
<ListInstance Id="Proposals"
TemplateType="101"
Title="Proposals"
Description="Document Library for proposals"
OnQuickLaunch="True"
Url="Proposals">
</ListInstance>
<Module Name="TestData" List="101" Path="TestData" Url="Proposals" >
    <File Url="Adventure Works Proposal.docx" Type="GhostableInLibrary" />
    <File Url="Contoso Proposal.docx" Type="GhostableInLibrary" />
    <File Url="Wingtip Toys Proposal.docx" Type="GhostableInLibrary" />
</Module>

<Module Name="WordTemplate" List="101" Url="Proposals/Forms">
   <File Url="ProposalTemplate.dotx" Type="Ghostable" />
</Module>


Events in SharePoint 2013

Sharepoint 2013 is having 2 types of  events
1. Server side events.
2.Remote events.

Server side events :
     Pre-Action & Post-Action Events
       Site Collection & Site Events
       Feture Events
       List & Library Events
       Schema Events
       List Item Events
       Workflow Events

Remote Events  :
   
      Introduced in SharePoint 2013
      App Lifecycle Events
      Events within Apps
      External Content Type Events

Server-Side Events
 
Site
Features
List\Library
List\Library schema
List Item
 
Workflow
Create
Move
Delete
Install
Uninstall
Activate
Deactivate
 
Create
Delete
 
 
Create
Update
Delete
 
 
Create
Update
Delete
Move
CheckIn
UnCheckIn
CheckOut
Attachment Added
Attachment Removed
File Moved
File Converted
 
 
Start
Postpone
Complete
 

 
Events are useful :

Data validation
Processes that are not longer-running in duration
Processes that do not require user or external system input or involvement
Apps do not permit server-side events


Remote Event Receivers
 
Many events have a pre & post side to them
Many pre-events cancellable with message / error page
 
Site
List / Library
List / Library Schema
List item
SharePoint App
Create
 Move
 Delete
 
Create
 Delete
 
Create
 Update
 Delete
 
Create
 Update
 Delete
 Move
 CheckIn
 UnCheckIn
 CheckOut
 Attachment Added
 Attachment Removed
 File Moved
 File Converted
 
Install
 Update
 Uninstall
 
 

List Event Registration

Declaratively or programmatically register remote event receivers with a list definition

Unlike server-side events, use URL for endpoint rather than assembly & type containing event


using (SPSite site = new SPSite(url))
{
using (SPWeb web = site.RootWeb)
{
      SPList list = web.Lists[listName];

         list.EventReceivers.Add(            SPEventReceiverType.ItemAdded,rEndpoint);

}

}

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers ListTemplateId="10000">
    <Receiver>
      <Name>AnnouncementItemAdding</Name>
      <Type>ItemAdding</Type>
      <SequenceNumber>10000</SequenceNumber>
      <Url>~remoteAppUrl/AnnouncementItemAddingRER.svc</Url>
    </Receiver>
  </Receivers>
</Elements>

App Lifecycle Event Registration

Declaratively register remote event receivers
Definitions found in AppManifest.xml

 
<Properties>
  <Title>App Lifecycle Event</Title>
  <StartPage>~appWebUrl/Pages/Default.aspx?{StandardTokens}</StartPage>
  <InstalledEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</InstalledEventEndpoint>
  <UninstallingEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</UninstallingEventEndpoint>
  <UpgradedEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</UpgradedEventEndpoint>
</Properties>

IRemoteEventService Interface

Synchronous & asynchronous events are supported


public class AppEventReceiver : IRemoteEventService

{

public SPRemoteEventResult ProcessEvent(RemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
result.Status = SPRemoteEventServiceStatus.Continue;

return


result;

}
public

void ProcessOneWayEvent(RemoteEventProperties properties)

{

}


Sharepoint 2013 Remote event receivers