Monday, March 18, 2013

AJAX Supporting Sharepoint Web parts with JSONP WCF Services

What is AJAX ?

AJAX = Asynchronous JavaScript and XML.
AJAX is a technique for creating fast and dynamic web pages.
AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
Classic web pages, (which do not use AJAX) must reload the entire page if the content should change.
Examples of applications using AJAX: Google Maps, Gmail, Youtube, and Facebook tabs.

Click here for AJAX Tutorial

In this post , we are going to create a share point page with AJAX Supporting web parts which invokes JSONP services to get data from Server.

1. Create JSONP WCF Services(How to create?)


Format of the Result

Link : 
http://ServerName:PorNumber/Service.svc/jsp/GetEmployeMoreDetailsByUserName?method=JsonPCallBack&logInName=User1

Result :

JsonPCallBack(
{
    "DateOfBirth":"\/Date(969042600000+0530)\/",
    "AboutMe":"This is all About Me",
    "CurrentATC":"CMB ATC",
    "Department":"OIG--CMB-VPL-Shared Services-Center Management",
    "Experience":16.2,
    "Interests":["UX Design","SharePoint","Photography"],
    "Languages":[""],
    "NoofPastProjects":33,
    "PermanentATC":"CMB ATC",
    "ReportingManager":"Domain\\UserName",
    "Tier":0,
    "Since":"\/Date(852057000000+0530)\/"
}
);

 
2. Create Empty/Visual Web part project and create web parts.

3. In aspx page create client side controls (Button , Label , text box ...etc)

<div>

Search Employee : <input id="SearchEmpName" type="text" name="SearchEmpName"  value=""/>
<input id="btnWCFREST" type = "button" value = "Search" /><br/>

<b>Reporting Manager:</b> <label id = "EmpReportlbl" ></label><br/>
<b>Department:</b> <label id = "EmpDepartlbl" ></label><br/>
<b>Tier:</b> <label id = "EmpTierlbl" ></label><br/>
<b>Permanent Office:</b> <label id = "EmpPermAtclbl" ></label><br/>
<b>Current Office:</b> <label id = "EmpCurrAtclbl" ></label><br/>
<b>Interests:</b> <label id = "EmpIntelbl" ></label><br/>
<b>Date Of Birth:</b> <label id = "EmpDOBlbl" ></label><br/>
<b>Languages:</b> <label id = "Emplanglbl" ></label><br/>
<b>Experience:</b> <label id = "EmpExpelbl" ></label><br/>

</div>



4. Add reference to the project in order to use JQuery in Web parts

<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.min.js"></script> 

5. Use the JQuery to invoke the WCF Services in AJAX.
Check this for more about JQuery :  JQuery, Write Less, do more

<script type="text/javascript">
    jQuery.support.cors = true;

    $(document).ready(function () {
        $("#btnWCFREST").click(function () {
            $.ajax({
                url: 'http://ServerName:PortNumber/Service.svc/jsp/GetEmployeMoreDetailsByUserName?logInName=' + $("#SearchEmpName").val() + '&method=?',
                type: 'GET',
                dataType: 'jsonp',
                error: function (x, t, r) { alert("Error In Employee More Details"); },
                success: function (data) {
                    document.getElementById('EmpReportlbl').innerText = data.ReportingManager;
                    document.getElementById('EmpDepartlbl').innerText = data.Department;
                    document.getElementById('EmpTierlbl').innerText = data.Tier;
                    document.getElementById('EmpPermAtclbl').innerText = data.PermanentATC;
                    document.getElementById('EmpCurrAtclbl').innerText = data.CurrentATC;
                    document.getElementById('EmpIntelbl').innerText = data.Interests;
                    document.getElementById('EmpDOBlbl').innerText = Date(data.DateOfBirth);  
                    document.getElementById('Emplanglbl').innerText = data.Languages;
                    document.getElementById('EmpExpelbl').innerText = data.Experience;
                }
            });


        });
    });
</script>


6. check whether AJAX is working or not by putting breakpoints in VS project in Page load method and attach appropriate process.

Follow Best Practises On WCF Services

If we organize the creation of WCF Services into this way , it will be efficient and can be changed in future without much efford.

1.  Create ServiceContract
     - Create Interface
2.  Create OperationContract under that ServiceContract
     - 
3.  Create Business Object (eg : employee)
     It has all required business parameters

4.  Return Data Transfer Objects (DTO) (eg : employeeDto)
     it has only the required parameters for that service. every services can have it's own Dto objects.

5.  Create Data Access Objects (DAO) (eg : employeeDao)  
     It is the object directly involve with data layer to get required data then process the data and map  it to business objects.

6. Create Object Mapper class (eg : ObjectMapper) and Mapper functions (eg : EmployeeDaoToDto) between DTO and DAO.
    Before send the objects to client side browser , services must convert the business objects to Data transfer objects. So mapping functions map the Data transfer object with business object.

WCF With JSONP

Before start with JSONP we should know what is REST ? and how it differ from other protocols? - Learn REST

What is JSONP ?

 JSONP or "JSON with padding" is a communication technique used in JavaScript. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the same origin policy.

By default WCF Services will not return JSON objects as result. if we want to get JSON objects , we have to define at Service implementation level.

If you are new to WCF , check this to get basic understanding about WCF!!!  -  Simple Steps to create the WCF Service

1.  Create WCF Library (WCF Service Library Template)

      a. Create Service contracts

          [OperationContract]
          [WebGet(ResponseFormat = WebMessageFormat.Json)]
          [JSONPBehavior(callback = "method")]
      
          EmployeeWorkDto GetEmployeMoreDetailsByUserName(string logInName);

       

      b. Create Service Implementations (Check this for more details)

Create Business object (employee), Data transfer objects (employeeDto), Data access objects  (employeeDao) , object mapper class(CoreObjectMapper) and mapping   functions(EmployeeDaoToDto).

"GetEmployeByUserName" is the function do all processing and return the result as "employee". then mapper function maps the "employee" object with "employeeDto". finally "employeeDto" will be send as response of that Service call.

         public EmployeeWorkDto GetEmployeMoreDetailsByUserName(string logInName)
        {

              // Do all Your implementation here, but return as "EmployeeWorkDto" Data transfer object
              EmployeeDao empDao = new EmployeeDao();
              return  CoreObjectMapper.EmployeeDaoToDto(empDao.GetEmployeByUserName(logInName));

        }


2. Create WCF Hosting Application (WCF Service Application Template)

      a. Modify Web.config

     i. create new end point

      <endpoint address="jsp"
          binding="customBinding"
          bindingConfiguration="jsonpBinding"
          behaviorConfiguration="restBehavior"
          contract="CoreService.IEmployeeService" />


     and specify binding , binding configuration and behavior configuration

     <endpointBehaviors>
           <behavior name="restBehavior">
              <webHttp />
          </behavior>        

    </endpointBehaviors>

    <customBinding>
           <binding name="jsonpBinding" >
               <jsonpMessageEncoding />
              <httpTransport manualAddressing="true"/>
          </binding>

   </customBinding>

and Host the Service and Check whether it is working or not by invoking the services in Browser.
Use the breakpoints for debug the application (Attach appropriate Processes - IIS App pool process and w3wp.exe  )

Service Url: 
http://ServerName:portNumber/Service.svc/jsp/GetEmployeMoreDetailsByUserName?method=JsonPCallBack&logInName=User1

Result :

JsonPCallBack(
{
    "DateOfBirth":"\/Date(969042600000+0530)\/",
    "AboutMe":"This is about Me ",
    "CurrentATC":"CMB ATC",
    "Department":"Delivery",
    "Experience":8.3,
    "Interests":["UX Design","SharePoint","Photography"],
    "Languages":[""],
    "NoofPastProjects":16,
    "PermanentATC":"CMB ATC",
    "ReportingManager":"Domain\\UserName",
    "Tier":2,
    "Since":"\/Date(852057000000+0530)\/"
}
);








Friday, March 8, 2013

Push Newsfeed to Sharepoint 2013 Site From External Sources

SharePoint 2013 comes with a lot of new features especially for Social Networking. News Feed is one of those features. SharePoint 2010 also has that feature but External systems can't send external feeds to the SharePoint farm. SharePoint 2013 has defined some libraries (API) to push feeds from outside to SharePoint farm.
In addition to that there are some different between 2010 newsfeed and SharePoint 2013 Newsfeed.
 
Prerequisites

1. Configured SharePoint 2013 Farm  
2. MySiteHost URL or Team Site URL
3. Visual Studio 2012 installed in machine

Steps to create the Project to send Newsfeed to SharePoint My site or Team site


1. Create New Class library in Visual Studio 2012 and named it as "NewsFeedPushLib"


2. Create a file and named it as "NewsFeedPushClass.cs"

3. Add below dlls as reference to that project 


4. write the following code into that class.


a. Check for accessibility - Need to ensure that that user has enough rights to push feeds into share point site.
 
          System.Net.NetworkCredential cred = new System.Net.NetworkCredential("UserName", "Password");
          ClientContext clientContext = new ClientContext("siteURL");
          clientContext.Credentials = cred;


b. Get the thread owner from the PeopleManager object.

          Microsoft.SharePoint.Client.UserProfiles.PersonProperties owner = new Microsoft.SharePoint.Client.UserProfiles.PeopleManager(clientContext).GetPropertiesFor(
"UserName");
 

c. Get the MicrofeedManager object.

                MicrofeedManager microfeedManager = new MicrofeedManager(clientContext);


d. Register the requests that you want to run.
                // The first call requests only the DisplayName and AccountName
                // properties of the owner object.


                clientContext.Load(owner, o => o.DisplayName, o => o.AccountName);
                clientContext.Load(microfeedManager);


e. Run the requests on the server.
                clientContext.ExecuteQuery();


f. Define defenitionName

 MicrofeedPostOptions postOptions = new MicrofeedPostOptions();
postOptions.DefinitionName = "defenitionName";

Eg : "Microsoft.SharePoint.Microfeed.UserPost" for User Post  

g. Send the Feed

    if (!string.IsNullOrEmpty(feedItem))
     // remove the empty/Null feed                 

   {
         if (feedItem.Length > 512)
         {
               feedItem = feedItem.Substring(0, 508) + "...";
// to limit the feed limit
         }
         postOptions.Content = feedItem; 
// content for the feed 

         if ((!(feedItem == null)) && !(feedItem.Equals("")))
        {
            if (true)
            {
                postOptions.TargetActor = targetActor;
// set the target actor for a feed               
                microfeedManager.Post(postOptions); 
//post the feed on each user's newsfeed
                clientContext.ExecuteQuery();
                success = true;
            }
            else
            {
                success = false;
//couldn't push it to target no valid target
            }

        }
   }

}

5. Create another project (console Application) and create new file. then call Push newsfeed method in this class

 NewsFeedPushClass.PushToSharePoint("Testing Feed1", "Sharepoint_Web_application_URL", "domain\\user", "password", "Team Site URL", "Microsoft.SharePoint.Microfeed.UserPost");

6. Run the program and check whether it is working or not.



Sample feed(Defect Information) pushed from external system(Project management system) to Team Site

 
Download the Solution File - MediaFire Link