Sunday, 17 November 2013

SharePoint 2013:Programatically generate EmbedCode for uploaded Video

In this post I will post a code example to generate a SharePoint embedCode for the uploaded videos , In SharePoint you can add three different types of video files 
  1. Upload video 
  2. Provide link to the video
  3. Using EmbedCode

if you use the third option the field VideoSetEmbedCode will contain the embed iframe of the video  but if you use the first option the Field VideoSetEmbedCode will remain empty , although you can get the embed code any time manually as you play the video.

The question is how to get the EmbedCode Programatically ? let us first check the format of the automatically generated embed code by SharePoint
it's simply Iframe with Src attribute with different set of parameters
  1. Player Url            "/_layouts/15/videoembedplayer.aspx"
  2. Some Parameter like:
    1. Site  : Site ID
    2. Web :Web ID
    3. Folder :Actually this is the current video Item ID not the parent Folder ID (Don't know why it's named as Folder)
    4. img: Thumbnail image of the Video
    5. lowner: if it equals 1 the owner name will be displayed 
    6. lTitle: if it equals  1 the title will be displayed
The question is how to construct this from the VideoItem  the code below do the trick



it first check if the VideoSetEmbedCode is not empty then if it's empty it constructs the EmbedCode in the same manner SharePoint does 

Monday, 11 November 2013

SharePoint Apps Pricing models

The new SharePoint App store got three different Pricing models , when you submit or update you app you can change the pricing model at the last step of the submission , the available pricing models are

  • Free 
I think this model does not require any explanation you post your app for free no revenuee unless some hits to your website (if you are using a provider hosting app model)
  • One Time purchase 
The buyer will pay once and will use the application unlimited in this option you can set trail version support for number of days  and users 

  • Sold as subscription
The user can download and use the app, in perpetuity or until they cancel their subscription, for a recurring monthly fee.



Sunday, 10 November 2013

Retrieve VideoSetEmbedCode using Search API

I've created new asset library in SharePoint , when I upload a new video I have the option to select an embed video , when I try to query the video Item using Search RESTful API The VideoSetEmbedCode is not appearing , below is the troubleshooting steps i did to overcome the problem

  1. Open the Central administration
  2. Click on Manage service Application
  3. Manage Search service Application
  4. Click on Search Schema
  5. Try To search for managed property (no luck)
  6. Try to search for crawled property (no luck)
  7. using the powershell I retrieved the Video Item and it got he property ows_VideoSetEmbedCode so why this crawled property is not appearing in the search schema 
  8. I find out that the Field is hidden so I tried to unhide it using powershell and failed
  9. it turns out that CanToggleHidden is set to false so I used the below code to make it unhidden
  10.  using (SPSite  site=new SPSite("http://sp:2020"))
                {
    
    
                    SPList list = site.RootWeb.Lists["MediaLibrary"];
                    SPField videoField = list.Fields.GetFieldByInternalName("VideoSetEmbedCode");
    
                    Type type = videoField.GetType();
                    MethodInfo mi = type.GetMethod("SetFieldBoolValue", BindingFlags.NonPublic | BindingFlags.Instance);
                    mi.Invoke(videoField, new object[] { "CanToggleHidden", true });
                    videoField.Hidden = false;
                    videoField.Update();
    
                   
               
                }
    
    
    I performed full crawling and now it works I can retrieve the VideoSetEmbedCode using Search API (Restful /KeywordQuery)


Wednesday, 23 October 2013

AD Synchronization to SharePoint user profile

In this post I will list the steps needed to synchronize active directory users to SharePoint user profile service

  1. Go to Central administration 
  2. Click on Mange Services on server

  3. Click start for the user profile synchronization service
  4. Enter the credentials for the account will run the service  
  5. Make sure that the service is Started 
  6. Go to Manage service application and click on the user profile service

  7. Go to synchronization section and click on configure synchronization connection
  8. Enter name of the connection and user credentials to connect to the AD 

  9. Test the connection by clicking on populate data 
  10. Save and back to the user profile service application page you can execute a full synchronization 
  11. To check the number of object synchronized go to the server running the user profile synch service and navigate to the path  "C:\Program Files\Microsoft Office Servers\15.0\Synchronization Service\UIShell"  
  12. Run the miisclient.exe and see the synchronization status 

Saturday, 19 October 2013

HTML5 code is not working in SharePoint 2010

I've seen this question over and over , to make the HTML5 code working in SharePoint 2010 simple modifications to the OOTB master page is needed

  1. replace the first line <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">   with <!DOCTYPE HTML">
  2. Change the compitability to IE=9 instead of 8  by replacing <meta http-equiv="X-UA-Compatible" content="IE=8"/>   with <meta http-equiv="X-UA-Compatible" content="IE=9"/>


Upload local Files to remote SharePoint site

This post is to answer a question how to upload files to a remote SharePoint installation , for remote SharePoint installation we have different options

  • Using RESTful api which is in the new SharePoint 2013 is a very powerful API , using RESTful api can be via Javascript ajax calls (GET/POST) or using a Console Application
  • The other option is to use the Client Object model 
In this post we will elaborate how to use the client object model to upload files to a remote Document Library

  1. Create new Console Application 
  2. Add the SharePoint Client dlls to the project references
  3. Write the below code :


Provider Hosted Application Token not sent along with the standard tokens

I've recently updated one of my SharePoint 2013 apps , after deploying the new version to the test environment I keep getting weird errors , when I viewed the URL I noticed that there is no token passed by to the provider hosted application:

I checked the updated Web.config and I discovered that the Client Id and client secret are both empty 
<appsettings><add key="ClientId" value="">
    <add key="ClientSecret" value="">
  </add></add></appsettings>

to make sure that the client context will be successfully retrieved via the method
 public static string GetContextTokenFromRequest(HttpRequest request){
            string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" };
            foreach (string paramName in paramNames)
            {
                if (!string.IsNullOrEmpty(request.Form[paramName])) return request.Form[paramName];
                if (!string.IsNullOrEmpty(request.QueryString[paramName])) return request.QueryString[paramName];
            }
            return null;
        }

make sure that the deployed application contains the correct client id and secret you created via Seller dashboard

how to create new client id please review the previous post


Tuesday, 24 September 2013

Provisioning MutliUser SiteColumn SharePoint 2013

Have you ever tried to create a site column using a feature , how many times you searched for the correct  format and syntax , I've tried to add multiple Person column to a custom content type
and instead of googling and copy and paste the code I came up with another way to get the Field Schema without google help !

I created a dummy custom list

  • Add an App

  • Choose custom List


  • Type the list name in my case I Typed "TestList"


  • Check if the list has been created



  •  Go to List ->List Settings


  • Add New Column , Type PeopleMulti , Choose Person or Group



  • Choose allow multiple values, People Only



Using Power Shell type the below 2 lines to export the field schema to XML file 




here is the UserMulti field , don't forget to change the Field ID 

<Field Type="UserMulti"
      DisplayName="PeopleMulti" 
      List="UserInfo"
      Required="FALSE"
      EnforceUniqueValues="FALSE"
      ShowField="ImnName"
      UserSelectionMode="PeopleOnly"
      UserSelectionScope="0" 
      Mult="TRUE"
      Sortable="FALSE"
      ID="{87C0735C-394D-4783-BDAD-1C997EF2B9AF}"
      StaticName="PeopleMulti" Name="PeopleMulti"
       />

Note remove the source ID from the generated XML , you can use the same method to get any Field Schema to help you create Custom Content Type using Visual studio





Wednesday, 20 March 2013

SharePoint 2013 App Google Drive Import Walk-through Part III


More innovated Version
The beta version was meant to test the potential of the SharePoint hosted apps, which is great potential but because of the first version require the user to setup his own Google Drive API using API Console, I decided to move to the Provider Hosted application.

Deploying the same solution as a windows azure website will remove the headache required to set up the app for single deployment.
Adding the ribbon button & Utilize the provider hosted application
The new version of the application also enables the user to import Google drive files to any document library by adding new ribbon button called “Google Drive Import” under the files ribbon group.

when the user clicks the import from Google Drive button a SharePoint dialog will open and Import.aspx page will be opened with the appropriate parameters needed like 


Steps
   1.Follow the same steps to create the initial version of the application mentioned in my previous blog post , just select the Provider hosted type instead of the SharePoint hosted app



2.After selecting the provider hosted option two different projects will be added to your solution , one of them is the SharePoint app project and the other is Web Application

3.Utilizing the same code in the first version in Import.aspx
    
    4.Adding Server Side Static method to do the import using the SharePoint client context



Simply this Static method will be called from JavaScript action on the Import.aspx page once the user clicks import




The AddFileToLibrary function is an asynchronous function you need to add call back functions as well



When the User clicks the close button the dialog will be closed and the parent page will be refreshed to display the newly added document a single line of JavaScript code is used to facilitate this behavior 


 5.     To create the ribbon button simply right click the SharePoint app project and click add new item Select the ribbon custom action and name it “GoogleDriveImportRibbon”

The elements.xml file of the custom action will be as below, note that I add listId to the standard token to be able to upload the selected files to the appropriate document library



Also you need to specify the ribbon button image which points somewhere in the ~remoteAppUrl which represents the remote Windows Azure website URL


6.In order to publish your app you need to create Client ID go to http://sellerdashboard.microsoft.com

after successful login click on client ids and select add new oauth client id 

Clicking add new oauth client id opens  the form below




 Just add friendly name and app domain and redirect URL then press generate, for the googledriveImport the Client ID is as below


In order to publish your application you need to keep
·        Client id
·        Client secret 
7.Create publishing profile for the Google Drive Import website , the easiest way to publish the site is to use Windows azure website
a.      Register for a free 3 month trail azure evaluation plan.
b.     Create your new website and select your domain name in my case it was
googledriveimport.azurewebsites.net




c.      After creating the website on windows azure platform , download the publishing profile.



d.      Use the downloaded publishing profile to publish your application by importing the profile as below 


e.      Right click the SharePoint 2013 application project and select publish  select the publishing profile you just imported 



f.      Enter the website URL and the client ID and client secret from the seller dashboard step.


follow the wizard and set back for couple of minutes your azure website and SharePoint application will be published 

Test your application by uploading it to your developer site then publish it to the app store 




























SharePoint 2013 App Google Drive Import Walk-through Part II

This blog entry is second part in series of blog post to walk-through the creation of Google drive import  application


What you’ve already got so far
You will find that some logic been already added but it’s very simple to just display the logged in user name using the JavaScript client object model
var context;
var web;
var user;

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model

$(document).ready(function () {
    context = SP.ClientContext.get_current();
    web = context.get_web();
    getUserName();
});
// This function prepares,loads, and then executes a SharePoint query to get the current users information
function getUserName() {
    user = web.get_currentUser();
    context.load(user);
    context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
}
// This function is execute if the above OM call is successful
// It replaces the contents of the 'helloString' element with the user name
function onGetUserNameSuccess() {
    $('#message').text('Hello ' + user.get_title());
}
// This function is executed
if the above call fails
function onGetUserNameFail(sender, args) {
    alert('Failed to get user name. Error:' + args.get_message());
}
What to Add

now let's try the specific items related to the application itself , let's start with the needed style sheets and javascript files used in this early version of the application
  • Style and JavaScript references

Because I’m using the JQuery datatables plugin I needed to add references to the DataTables scripts also adding metro style JQueryUI
  • CSS added to the Content Folder like below


  • Reference Scripts added to the script Folder



  • Application Pages
the application consists of two different aspx pages the first one is the setting page in which the user set his google drive api key and client ID
    • Settings page :Settings.aspx
<h1>App Settings</h1>
    <br />
    <br />
    <table>
        <tr>
            <td><span>Google Drive API Key:</span> </td>
            <td><textarea  id="txtAPI_KEY"  cols="50"></textarea></td>
        </tr>
        <tr>
            <td><span>Google Drive Client ID:</span> </td>            
            <td><textarea  id="txtCLIENT_ID" cols="50"></textarea></td>
        </tr>
        <tr>
           
            <td colspan="2" align="center"> 
                <div>
                    <a href="#" onclick="saveSettings();" id="btnSave">Save</a>
                    <a href="default.aspx" id="btnCancel">Cancel</a>
                </div>
            </td>
        </tr>
     </table>



 The setting page is used to set the Google Drive API application key and Client ID, it simply store the value within the website properties , and by website I mean the SharePoint application itself as it will be deployed as an isolated website.


   

The settings.aspx webpage calls saveSettings() function which stored the data within the website properties.

Settings.js
The Javascript file contains the code utilized in the Settings.aspx webpage

$(document).ready(function () {
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', readApplicationSettings); 
});
function readApplicationSettings()
{
       var context = new SP.ClientContext.get_current();
    var web = context.get_web();
       this.props =  web.get_allProperties();  
       context.load(this.props);
    context.executeQueryAsync(Function.createDelegate(this, gotProperty), Function.createDelegate(this, failedGettingProperty));
}

function gotProperty() {
      
       $("#txtCLIENT_ID").val(this.props.get_item("CLIENT_ID"));
       $("#txtAPI_KEY").val(this.props.get_item("API_KEY"));
      
}
function failedGettingProperty() {
    alert("Can't get the web properties");
}
function saveSettings()
{
       var context = new SP.ClientContext.get_current();
    var web = context.get_web();
       this.props=web.get_allProperties();     
       this.props.set_item("API_KEY", $("#txtAPI_KEY").val());
       this.props.set_item("CLIENT_ID", $("#txtCLIENT_ID").val());
       web.update();
       context.executeQueryAsync(Function.createDelegate(this, onSettingsSaveSuccess), Function.createDelegate(this, onSettingsSaveFailure));
      
}
      
function onSettingsSaveSuccess()
{
       alert("Application Setting Saved");
       window.location="default.aspx";
}

function onSettingsSaveFailure()
{
       alert("Error Saving the settings..!");
}

$(function () {
    $("#btnSave").button();
    $("#btnCancel").button();
});

Deault.aspx

This is the application main page which contains the datatable displays your Google drive and each item has dropdown list for each file to select the export format from Google drive to SharePoint Library.
  <div>
        <p id="message">
            <!-- The following content will be replaced with the user name when you run the app - see App.js -->
            initializing...
        </p>
        <div style="float:right;">
                     <a href="settings.aspx" id="btnSettings">Change Settings</a>
                <a href="../Lists/MyDocuments" id="btnViewDocs">View Documents</a>           
        </div>
    </div>
    <br />
       <div id="container">
        <div>             
             <table cellpadding="0" cellspacing="0" border="0" class="display" id="DocsDataTable">
                   <thead id="thead" style="display:none;">
                          <tr>
                                 <th width="20%">Title</th>
                                 <th width="13%">Create Date</th>
                                 <th width="13%">Modified Date</th>
                                 <th width="13%">Modified By Me Date</th>
                                 <th width="13%">Viewed By Me Date</th>
                        <th width="13%">Last Modified User</th>
                        <th width="10%">View</th>
                        <th width="5%">Select Export Format</th>
                          </tr>
                   </thead>
                   <tbody> 
                                  <tr>
                                         <td colspan="8" id="tdMessage"></td>
                                  </tr> 
                   </tbody>
            </table>
        </div>
        <div class="spacer"></div>
    </div>
    <br />
    <div id="divImport" style="display:none;"> 
        <div>
            <input type="checkbox" id="chkOverwrite" name="overwrite" >Overwrite Existing Files?</input>
        </div>
        <div>       
            <a id="btnImport" href="#" onclick="importSelectedRows();" >import</a>      
        </div>
    </div>  
    <div id="pop-up" style="display:none;">
        <!-- gif represents the import loading -->
        <img src="../Images/ajax-loader.gif" id="imgLoading"/>
        <!-- the below text will be updated upon each file import -->
        <p id="importText"></p>       
        <a href="#" onclick='$("#pop-up").dialog("close");' id="btnClose" style="display:none;">Close</a>          
    </div>
Apps.js

 This file contains almost all the logic the application used
·        Load the Google Drive API
gapi.client.load('drive', 'v2', handleClientLoad);
·        Definition of the Google Drive API related variables

var CLIENT_ID = '597646573398.apps.googleusercontent.com'; //Google drive API client id
var API_KEY = "AIzaSyA9Es1Ej7H8BCYPYkSjhbkNNTdrd-cmS_o"; //api key
var SCOPES = [                   
         'https://www.googleapis.com/auth/drive.readonly.metadata',
        'https://www.googleapis.com/auth/drive.readonly',
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/drive.file',
        'https://www.googleapis.com/auth/drive.metadata.readonly'
        // Add other scopes needed by your application.
        ];
var File_List_URL = "https://www.googleapis.com/drive/v2/files"; //url to get the google drive user files
·        Authenticate the request
function checkAuth() {
       try
       {
        //wait until the gapi is fully loaded
           if (typeof (gapi.auth) == 'undefined') {
               displayMessage('error', 'gapi is not loaded!', true);        
           } 
           else {
               gapi.auth.authorize(
            { 'client_id': CLIENT_ID, 'scope': SCOPES.join(' '), 'immediate': true },
            handleAuthResult);
           }
          
       }
       catch(e)
       {            
              displayMessage('error',e,true);
       }
}

· How to handle the authentication Result
function handleAuthResult(authResult) {
       try
       {       
           if (authResult && !authResult.error) {                   
               GetFiles();
           } else {
               // No access token could be retrieved, force the authorization flow.                   
               displayMessage('error', "can't  authenticate app for Google drive API check App Settings and Ensure you authorize the api to access your files then refersh the page", true);
               gapi.auth.authorize(

             { 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false },
             handleAuthResult);
              }
       }
       catch(e)
       {
              displayMessage('error',e,true);
       }
}


·        Get the Actual File List as JSON object
function GetFiles() {
       try
       {
        //beging loading data
           $("#tdMessage").html("Loading data ....");
           var accessToken = gapi.auth.getToken().access_token;
           var xhr = getXMLHttpRequest();
           xhr.open('GET',File_List_URL+'?key='+API_KEY);
           xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
           xhr.onload = function () {
               renderFiles(xhr.responseText);
           };
           xhr.onerror = function () {
               displayMessage('error','Error Listing Your Google Drive Files');
           };
           xhr.send();
       }
       catch(e){           
              displayMessage('error',e,true);
       }
}

After the files been retrieved the user can select the appropriate format to export these files from Google Drive then press the Import button

In the Third part of this series we will discuss more innovated approach









SharePoint 2013 App:Google Drive Import Walk-through Part 1


Today I will start explaining in details the SharePoint 2013 application I built  I will start with my first published application ever which is Google Drive Import Beta

The Idea

I came up with the idea when I started to use SharePoint 2013 for the very first time and new about the newly introduced app platform, I was facing too much trouble using excel files I hosted over Google Drive, so It just hits me everyone should be able to migrate his office documents from Google Drive to SharePoint platform to enjoy the amazing experience of the Office Web Apps


First Version “SharePoint Hosted"

The first version supposed to be a beta version of the application to test drive the SharePoint hosted application, it was a pure JavaScript

 Prerequisites

  • Installation of the VS2012 is recommended , you can use the web-based application builder NAPA, but it's highly recommended to download and install VS2012 
  • Installation of the Microsoft Office Developer Tool for VS2012 can be easily obtained by Microsoft Web Platform Installer.
  • If you are using Windows 7 it has to be SP1


Steps

1.     Create new project

  


2.     Select  Office/SharePoint from the side navigation and then select App for SharePoint template



3.     Name your solution and your project also set the physical  Location for the solution and project.
4.     Point to the URL of the development environment you set up either locally or as in my case your SharePoint online developer website
Also select from the dropdown list the type of the SharePoint App which in our case in this beta version I used the  SharePoint-hosted application type 



The visual studio will try to connect to the site you already provided so it will prompt you for the credentials
5.     Press finish and wait for the visual studio to create the SharePoint App project
6.     This is what you will get after Visual Studio finish creating  your project



The files been created for you are the
·        Default.aspx
·        Elements.xml
·        Script Folder
o   _references.js
o   App.js
o   Elements.xml
o   jquery-1.7.1.intellisense.js
o   jquery-1.7.1.js
o   jquery-1.7.1.min.js
·        AppManifest.xml
·        packages.config

7.     Start Customizing the App properties
Open the AppManifest.xml it will open in the designer view like below



1.     Edit the application Title
2.     Edit the application Name
3.     Set the version Numberà this is very important as it must match the application details you are going to enter while submitting this application to the Office Store.
4.     Application Icon
5.     Start Page , So far we have only single ASPX webpage which is Default.aspx
6.     Query String it’s the parameters needed to be passed to this page , this will come in handy when walking through the Provider Hosted Application Type
Note: the application page you have is only ASPX page with no code behind.
8.     Start Adding the Logic

In Part II we will continue walking through the whole application implementation