Wednesday, 4 October 2017

SharePoint OnPremises: Client side file upload control and uploading file in SharePoint using rest API

Hi All,

Background:In one of our SharePoint OnPremises project, we have requirement to upload the user’s photo, his profile image in SharePoint Image library (PublishingImages). So we have implemented this feature using JavaScript and upload image in SharePoint Image library using rest API.

This become generic component and anybody can use this in any SharePoint project. We have used this control in our couple of Visual WebParts.

In this article I’ll share step by step details how we implemented and how this component works.

Environment: SharePoint on premises 2013, didn’t tested for SharePoint online but I believe it should work for SharePoint online as well.

Details: We have OOB FileUpload control available in .NET but which causes page postback so we decided to implement client side control.

Step 1: Using <input> element with type “file”. This let the user to select one or more files. File input renders the button “Choose File”, on click of this button file picker dialog opens and label which shows the file name as

<input type="file" draggable="true" id="fileupload" class="form-control" />

 

Figure 1: File Input element

On click of “Choose File” button file open dialog box opens as and we can select the one or multiple files from it. Here in case we required only one file and so considering each time that only one file will be selected at a time.

Figure 2: Open file dialog box, opens when "Choose File" button is clicked

Step 2: We have added one more button “Upload Profile”, on click of this button we are uploading image in SharePoint Images library as

Figure 3: "Upload Profile" button with File Input control

Step 3: On “Upload Profile” button click we will upload the selected file using rest apis, we are calling JavaScript method “UploadFile” as


<input type="button" value="Upload Profile" id="btnUploadProfile" onclick="UploadFile()" />

Here also showing OOB wait dialog box till the image get uploaded in SharePoint.

Following are the detailed steps to upload file using rest API from JavaScript

1.     Get the file element as
var fileElement = <%=fileupload.ClientID%>;

2.     Check if file is selected or not, if not then showing alert message as

if (fileElement.files.length === 0) {
            alert('No file was selected');
            return;
        }//if (fileElement.files.length === 0)

3.     Since we are using REST API call back happens, we are showing OOB SharePoint wait dialog box till the file is get uploaded in SharePoint Images library as

var waitDialog_FileUpload = SP.UI.ModalDialog.showWaitScreenWithNoClose("Profile Image upload in progress", '', 80, 560);

4.     Get the file name as
var parts = fileElement.value.split("\\");
       var filename = parts[parts.length - 1];

5.     Read the file and once done call the rest api as, we are using FileReader object which let us asynchronously read the content of file. There is a FileReader.readyState property having possible values of the state are

EMPTY             0          No data is loaded yet
LOADING         1          Data is currently being loading
DONE              2          Read request is done

var fileReader = new FileReader();
//File loaded
fileReader.onloadend = function (event) {
           if (event.target.readyState == FileReader.DONE) {
              var filecontent = event.target.result;
            
//Code to upload image in Images Library
         }

6.     Uploading image to Images library using REST APIs
      
 //SharePoint images library path
        var imagelibraryURL = _spPageContextInfo.siteServerRelativeUrl +
          "PublishingImages";
             
        //Complete REST API
 var completeImageLibraryUrl = _spPageContextInfo.webAbsoluteUrl
              + "/_api/web/GetFolderByServerRelativeUrl('" + imagelibraryURL +
"')/Files/add(url='" + filename + "',overwrite=true)";

              
$.ajax({
               url: completeImageLibraryUrl,
               type: "POST",
               data: filecontent,
               async: false,
               processData: false,
               headers: {
                    "accept": "application/json;odata=verbose",
                      "X-RequestDigest": $("#__REQUESTDIGEST").val(),
               },
               complete: function (data) {
                       var clientContext = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
                        var web = clientContext.get_web();
                        var fileurl = imagelibraryURL + "/"+filename;
                        var imagetopublish = web.getFileByServerRelativeUrl(fileurl);

                        imagetopublish.checkIn();
                        imagetopublish.publish();
                        clientContext.executeQueryAsync();
                        //close the wait dialog
                        if (waitDialog_FileUpload != null) {
                            waitDialog_FileUpload.close();
                        }
                        alert("Your profile image uploaded successfully");
                     }, //complete
                     error: function (err) {
                          if (waitDialog_FileUpload != null) {
                              waitDialog_FileUpload.close();
                           }
                           alert(err + err.message + err.stacktrace);
                     }//error
                });//$.ajax

            fileReader.readAsArrayBuffer(fileElement.files[0]);

Complete Code:

HTML:

<input type="file" draggable="true" id="fileupload" class="form-control" />
<input type="button" value="Upload Profile" id="btnUploadProfile" onclick="UploadFile()" />

JavaScript:

function UploadFile() {
        var fileElement = <%=fileupload.ClientID%>;
        if (fileElement.files.length === 0) {
            alert('No file was selected');
            return;
}//if (fileElement.files.length === 0)
       else {
var waitDialog_FileUpload = SP.UI.ModalDialog.showWaitScreenWithNoClose("Profile Image upload in progress", '', 80, 560);
var parts = fileElement.value.split("\\");
       var filename = parts[parts.length - 1];
var fileReader = new FileReader();
//File loaded
fileReader.onloadend = function (event) {
           if (event.target.readyState == FileReader.DONE) {
              var filecontent = event.target.result;
            
//Code to upload image in Images Library
var imagelibraryURL = _spPageContextInfo.siteServerRelativeUrl +
          "PublishingImages";
             
        //Complete REST API
 var completeImageLibraryUrl = _spPageContextInfo.webAbsoluteUrl
              + "/_api/web/GetFolderByServerRelativeUrl('" + imagelibraryURL +
"')/Files/add(url='" + filename + "',overwrite=true)";

              
$.ajax({
               url: completeImageLibraryUrl,
               type: "POST",
               data: filecontent,
               async: false,
               processData: false,
               headers: {
                    "accept": "application/json;odata=verbose",
                      "X-RequestDigest": $("#__REQUESTDIGEST").val(),
               },
               complete: function (data) {
                       var clientContext = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
                        var web = clientContext.get_web();
                        var fileurl = imagelibraryURL + "/"+filename;
                        var imagetopublish = web.getFileByServerRelativeUrl(fileurl);

                        imagetopublish.checkIn();
                        imagetopublish.publish();
                        clientContext.executeQueryAsync();
                        //close the wait dialog
                        if (waitDialog_FileUpload != null) {
                            waitDialog_FileUpload.close();
                        }
                        alert("Your profile image uploaded successfully");
                     }, //complete
                     error: function (err) {
                          if (waitDialog_FileUpload != null) {
                              waitDialog_FileUpload.close();
                           }
                           alert(err + err.message + err.stacktrace);
                     }//error
});//$.ajax
       }// if (event.target.readyState == FileReader.DONE)
            fileReader.readAsArrayBuffer(fileElement.files[0]);
            
  }//else
}//UploadFile

References:
  1.      <input type="file">
  2.      FileReader object
  3.      Rest API to upload the file
  4.      OOB SharePoint Wait dialog box 

Thanks J

Enjoy Reading J

As usual any comment / suggestions / feedback / questions always welcome :)



Monday, 2 October 2017

Office 365 - Executing Exchange Online PowerShell cmdlets through SharePoint Online Management Shell or Windows PowerShell. Creating remote PowerShell session.

Hi All,

Today new topic, new sharing :)

For Office 365 administrator there are list of Exchange Online PowerShell cmdlets are available. We can execute these cmdlets through SharePoint Online Management Shell or Windows PowerShell by creating remote PowerShell session with Exchange Online. In this article I’ll explain how to create remote PowerShell session to Exchange Online and then executing Exchange Online PowerShell cmdlets.

There are list of PowerShell cmdlets available for Exchange Online. Administrator can execute these PowerShell commands from their local computer using Remote PowerShell. Administrator can manage complete Exchange Online from command line. First of all we will create remote PowerShell session and the see how to fetch all list of exchange online commands which administrator can execute.

Here, I will explain for SharePoint Online. So first step is to install SharePoint Online management shell. For installing SharePoint Online management shell please have a look once my old blog “SharePoint Online / Office 365: SharePoint Online Management Shell Installation”.

Once SharePoint Online Management Shell is ready then next step is making SharePoint Online Management Shell ready for connecting Office 365. For connecting to Office 365 first time we need to install following two software’s:


1.     64-bit version of the Microsoft Online Services Sign-in Assistant - Microsoft Online Services Sign-in Assistant for IT Professionals RTW.

2.     64-bit version of the Microsoft Azure Active Directory module for Windows PowerShell



Once required software’s ready we are ready to connect to Exchange Online.

Step 1: Get Credentials using “Get-Credential” cmdlet as

$credential = Get-Credential

Once we execute this cmdlet, “Windows PowerShell credential?” dialog box will appear as

Figure 1: Windows PowerShell credential request? Dialog

Enter your Office 365 account user name and password and press OK. Once we have credentials next step is to create the PowerShell session PSSession using “New-PSSession” as

Step 2: Create the PowerShell session PSSession using “New-PSSession” as

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $ credential -Authentication Basic -AllowRedirection

Once we have session object, next step is to import the session using “Import-PSSession

Step 3: Import the session using “Import-PSSession” as

Import-PSSession $Session

Which imports all exchange online commands such as cmdlets, functions, and aliases from PSSession into the current SharePoint online management session.  Result will look like as

Figure 2: result of Import-PSSession cmdlet

We can just print $Session object and see the details as

Figure 3: Session object details after importing

Since we are ready to execute Exchange Online cmdlets we will see how to get all list of cmdlets, using “Get-Module” and “Get-Command” cmdlets as

$mods=Get-Module | where {$_.Name -like "tmp_*"}; $modName=$mods.Name

Here we are filtering based on module name and contains “tmp_ *. We used “tmp_ *” because if we see the result of Import-PSSession cmdlet we got the module name “{tmp_q34a00sh.o0j}” and then will execute “Get-Command” cmdlet

Get-Command -Module $modName | More

Figure 4: All exchange online command
References:






Thanks!

Enjoy Reading J

As usual any comment / suggestions / feedback / questions always welcome :)