Saturday, 31 October 2020

Calling SharePoint Search Using REST From JavaScript

 Introduction

SharePoint 2013 provides a very powerful endpoint, which you can use to retrieve search result and query suggestion.

The first thing which we have seen is the available search endpoints

Endpoint
http://[host]/[site]/_api/search/query
http://[host]/[site]/_api/search/postquery
http://[host]/[site]/_api/search/suggest

 The simplest way to run a query against REST API is to pass a keyword query. There are two basic ways to run searches, where one is by sending the search parameters through the RESTful URL and the other by sending them through the query or suggest endpoints. The querytext can be any legal keyword query language construction, including managed properties and operators. So far we’ve just looked at executing a basic query, where the query text is specified. Here are a couple of other common operations, which you might want to do.

OperationSample REST URL
Specify the maximum number of record to return/_api/search/query?querytext='search term'&rowlimit=100
Specify a start row (i.e. in paging)/_api/search/query?querytext='search term'&startrow=11
Specify a number of results to return/_api/search/query?querytext='search term'&startrow=11&rowlimit=10 (but note 10 is the default)
Specifies the list of properties to sort the search results by./_api/search/query?querytext=’terms’&sortlist= ‘Title:ascending’
Specify particular (managed) properties to return/_api/search/query?querytext='search term'&selectproperties='Author,Path,Title'
Use a search Result Source (i.e. a scope)/_api/search/query?querytext='search term'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31' (this ex. is to search the ‘People’ result source)

Below specifies the unique key identifier of the Result Source to use for executing the search queries,
    Result SourceID
    Documentse7ec8cee-ded8-43c9-beb5-436b54b31e84
    Items matching a content type5dc9f503-801e-4ced-8a2c-5d1237132419
    Items matching a tage1327b9c-2b8c-4b23-99c9-3730cb29c3f7
    Items related to current user48fec42e-4a92-48ce-8363-c2703a40e67d
    Items with same keyword as this item5c069288-1d17-454a-8ac6-9c642a065f48
    Local People Resultsb09a7990-05ea-4af9-81ef-edfab16c4e31
    Local Reports And Data Results203fba36-2763-4060-9931-911ac8c0583b
    Local SharePoint Results8413cd39-2156-4e00-b54d-11efd9abdb89
    Local Video Results78b793ce-7956-4669-aa3b-451fc5defebf
    Pages5e34578e-4d08-4edc-8bf3-002acf3cdbcc
    Pictures38403c8c-3975-41a8-826e-717f2d41568a
    Popular97c71db1-58ce-4891-8b64-585bc2326c12
    Recently changed itemsba63bbae-fa9c-42c0-b027-9a878f16557c
    Recommended Itemsec675252-14fa-4fbe-84dd-8d098ed74181
    Wiki9479bf85-e257-4318-b5a8-81a180f5faa1

    Example

    I wanted to search for the people, the key learning here is that you specify the content sources via its GUID.


    Use the procedure given below to create a sample.

    Step 1

    Navigate to your SharePoint 2013 site.

    Step 2

    From this page, select Site Actions | Edit Page.

    Edit the page, go to the Insert tab in the Ribbon and click Web Part option. In Web Parts picker area, go to the Media and Content category, select the Script Editor Web Part and press the Add button.

    Step 3

    Once the Web Part is inserted into the page, you will see an "EDIT SNIPPET" link; click it. You can insert HTML and/or JavaScript, as shown below.

    1. <script src="/Scripts/jquery-1.10.1.min.js" type="text/javascript"></script>  
    2. <script type="text/javascript">  
    3.     $(document).ready(function() {  
    4.         $("#SearchQuery").click(function() {  
    5.             $.ajax({  
    6.                 url: window.location.protocol + "//" + window.location.host + "/_api/search/query?querytext='" + $("#search-input").val() + "*'&sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'&rowlimit='100'&selectproperties='PictureURL, PreferredName, Country'",  
    7.                 headers: {  
    8.                     "Accept""application/json; odata=verbose"  
    9.                 },  
    10.                 contentType: "application/json; odata=verbose",  
    11.                 success: function(data) {  
    12.                     var results;  
    13.                     var divHTML = '';  
    14.                     var Picurl;  
    15.                     if (data.d) {  
    16.                         if (data.d.query) var users = newArray();  
    17.                         results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;  
    18.                         for (i = 0; i < results.length; i++) {  
    19.                             var item = results[i];  
    20.                             var itemCell = item.Cells;  
    21.                             var itemResults = itemCell.results;  
    22.                             //Get Values for User  
    23.                             var userPic = getValueByKey("PictureURL", itemResults);  
    24.                             var fullname = getValueByKey("PreferredName", itemResults);  
    25.                             var CountryName = getValueByKey("Country", itemResults);  
    26.                             if (userPic != null) {  
    27.                                 Picurl = userPic;  
    28.                             } else {  
    29.                                 Picurl = '/Style Library/styles/images/tempPic.png';  
    30.                             }  
    31.                             // alert(PicId);  
    32.                             divHTML += '<div class="item">' + '<div class="id">' + '<div class="ms-tableCell ms-verticalAlignTop">' + '<div class="ms-peopleux-userImgDiv">' + '<div class="ms-imnSpan">' + '<div style="width: 36px; height: 30px;" id="ImgPicSpan1" class="ms-peopleux-userImgWrapper ms-subtleLink ms-peopleux-imgUserLink">' + '<img style="cliptop: 0px; clipright: 36px; clipbottom: 36px; clipleft: 0px; min-height: 30px; max-height:30px; min-width: 30px; max-width: 30px;" id="PictureDiv1" class="ms-peopleux-userImg" src="' + Picurl + '"/>' + '</div>' + '</div>' + '</div>' + '</div>' + '<div id="PersonNameDiv" class="ms-tableCell ms-verticalAlignTop" >' + '<div> ' + fullname + ' </div>' + '<div class="place">' + CountryName + ' </div>' + '</div>' + '</div>' + '</div>' + '</div>' + '</div>' + '</div>'  
    33.                         }  
    34.                         $("#Result").html(divHTML);  
    35.                     }  
    36.                     elseif(data.d.postquery)  
    37.                     results = data.d.postquery.PrimaryQueryResult.RelevantResults.Table.Rows.results;  
    38.                     else throw "Results not found";  
    39.                 }  
    40.             });  
    41.         });  
    42.   
    43.         function getValueByKey(key, results) {  
    44.             var postItem = $.grep(results, function(e) {  
    45.                 if (e.Key === key) returne;  
    46.             })[0].Value;  
    47.             returnpostItem;  
    48.         }  
    49.     });  
    50. </script> <input type="text" id="search-input"> <input type="button" id="SearchQuery" value="Search">  
    51. <div id="Result"></div>  

    Final Output


    For a more comprehensive reference, the best source which I can find is SharePoint 2013 Search REST API on MSDN.

    Calling Rest API From A SharePoint Designer Workflow

     Introduction

    In this article, we will implement an approach of calling a REST API in SharePoint Designer Workflow.

    Scenario

    Create a custom list, “IT,” and let’s say that we want to create a Workflow which returns the first one by using REST API, which is based on Dept. Filter, which shows Title Name.


    Objective

    Start SharePoint Designer 2013 and add a list Workflow on this IT list; make sure Workflow is a SharePoint 2013 Workflow.


    In the screenshot given below, we need to look back at the XML generated in the Browser. Looking at the JSON output given below from our .getJSON() call, we find the values to show and highlight/copy XML name as we’ll need the exact value since jQuery is case sensitive.

    https://serversitename/_api/web/lists/getbytitle('IT')/items?$filter=Dept eq 'RnD'

    You should get something, as shown below.


    Since the $json option is not supported in SharePoint 2013 REST API, to get the the response in a JSON format, you will have to update the Accept and Content-Type http headers of your Rest http call to be more specific.


    • Accept : application/json;odata=verbose
    • Content-Type : application/json;odata=verbose

    Now, let’s get back to our Workflow in SharePoint Designer 2013.

    Steps 1

    We need to create the Request header and this is possible by using a Dictionary ->.

    In the existing stage, type Build -> rename the variable dictionary as RequestHeader.


    Steps 2

    Click this and click Build your dictionary; add the Accept and the Content-Type headers.


    Steps 2

    Go to Action ->Core Action->Call HTTP Web Service option. Now, let’s focus on the Http request by adding a Call action.


    Step 3

    Click this and paste your http request.


    Steps 4

    Choose the Advanced Properties icon. In the Call HTTP Web Service Parameters dialog, click RequestHeaders dropdown, choose RequestHeader variable and click OK.


    Step 5

    In the Call action, click Response and associate the response to a new variable: JSonResult (of type Dictionary) and a new variable: ShowTitle(of type String).

    After the Call action, add a new Get action.


    Steps 6

    Add a log activity and display the ShowTitle variable in the log.


    Steps 6

    The final stage should look as shown below. Publish and run the Workflow.


    Steps 7

    In the Workflow history, you should find Filter Title, which is shown below.

    SharePoint 2013 - Scope, Requesting And Granting App Permissions

     Introduction

    In this article, we will explore SharePoint 2013 apps security - Managing app permissions functionality to a SharePoint site.

    Scope

      If you have started creating a new SharePoint app in SharePoint 2013 which requires permissions to write into one or many lists of the host-web, you instantly realize that it is not possible to specify which Lists/Libraries should be given permissions to write.

      That is because the Security model (controllable via the AppManifest.xml) does not work like that, but rather uses “Scope” as follows.

      Steps

      Open the Manifest Designer view (double-click the AppManifest.xml file). On the General tab, the Title text box should show the app name that you typed in "New app"  text box. Choose the Permissions tab to add the following permission requests for the app (see Figure ).

      • In the first row of the Permission requests list, in the Scope column, choose Statusing in the drop-down list. In the Permission column, choose SubmitStatus.




      • Requesting and granting app permissions

        The Permissions tab of the app manifest designer supplied by Microsoft Visual Studio makes it easy to add and configure permission requests without having to work with the XML elements directly. The screenshot in Figure shows what the Permissions tab looks like when you are configuring permission requests. You are not required to make direct edits to the AppManifest.xml file to add permission requests.


      There are several different types of permissions that an app can request in SharePoint 2013. The below table provides a listing of more common ones that can be used in app development in SharePoint 2013.

      Table - Permission types in SharePoint 2013

      Object typeScope URIRights
      Tenancyhttp://sharepoint/content/tenantRead, Write, Manage, FullControl
      Site collectionhttp://sharepoint/content/sitecollectionRead, Write, Manage, FullControl
      Host webhttp://sharepoint/content/sitecollection/webRead, Write, Manage, FullControl
      Listshttp://sharepoint/content/sitecollection/web/listRead, Write, Manage, FullControl
      Searchhttp://sharepoint/searchQueryAsUserIgnoreAppPrincipal
      BCShttp://sharepoint/bcs/connectionRead
      Managed metadatahttp://sharepoint/taxonomyRead, Write
      Social corehttp://sharepoint/social/coreRead, Write, Manage, FullControl
      Social tenancyhttp://sharepoint/social/tenantRead, Write, Manage, FullControl
      Microsofeedhttp://sharepoint/social/microfeedRead, Write, Manage, FullControl


      Note

      It is worth noting that running with app-only permissions is only possible when using external authentication. Executing calls from an app with app-only permissions is not possible when using internal authentication. Therefore, running with app-only permissions is not possible from SharePoint-hosted apps. Calls from a SharePoint-hosted app always require that app permissions and user permissions succeed.

      SharePoint 2013 - App Authentication Using S2S High Trust

       WHAT IS A SERVER-To-SERVER (S2S) TRUST

      • A trusted connection between client app and SharePoint Web server
      • Eliminates the need of involving ACS when running apps within private networks
      • Trust between Servers is configured using one or more SSL certificate
      • App Server code requires access to public/private key pair of SSL certificate
      • Requires creating S2S Security Token Service on SharePoint Web server(s)

      On- premises App Authentication is used for setting up High Trust apps that use the server-to-server (S2S) protocol. This is a Provider Hosted app deployed in a private network which eliminates the need to involve ACS for creating authentication tokens. In essence, an S2S Trust represents a trusted connection between a client app running on a local app server and the web servers in the SharePoint farm.

      S2S (High Trust) - App Only Context

      An S2S accesses the token by calling the GetS2SAccessTokenWithWindowsIdentity method of the TokenHelper class. Use the TokenHelper::GetS2SAccessTokenWithWindowsIdentity method, passing a null for the WindowsIdentity parameter.


      Let’s see how we can actually utilize the "App Only" policy to elevate user permissions. I have written the following code in the code behind of the TestPage.aspx of S2S Provider Hosted App.

      Code

      1. Uri _hostWeb = newUri(Request.QueryString["SPHostUrl"]);  
      2. stringappOnlyAccessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(_hostWeb, null);  
      3. using(ClientContext clientContext = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(_hostWeb.ToString(), appOnlyAccessToken)) {  
      4.     List Testlist = clientContext.Web.Lists.GetByTitle("TestList");  
      5.     ListItemCreationInformation info = new ListItemCreationInformation();  
      6.     SharePoint.Client.ListItem item = Testlist.AddItem(info);  
      7.     item["Title"] = "Created S2SApp";  
      8.     item["Body"] = "Created from S2S” + DateTime.Now.ToLongTimeString();  
      9.     Update();  
      10.     Load(item);  
      11.     ExecuteQuery();  
      12. }  

      Deploy the app and then log on as a user who only has read permission to the list. Execute the code and a new item is created even though the user does not have permission to create items in the list. The "Created By" and "Modified By" fields in the list will reflect that it was the SHAREPOINT\App account that was used to create the item.

      In a previous article, I had explored S2S (High Trust) app example.

      Note 

      This capability is only available to provider-hosted apps, not to SharePoint-hosted apps. In a SharePoint-hosted app, there is Full trust code that is not limited by permissions – it can do anything it wants. 

      SharePoint 2013 - Uploading Multiple Attachments To The New Item On List Using JSOM And REST API

        Introduction In this article, we will explore how we can attach multiple attachments to the new item on list using JSOM and REST API. Ther...