Get SharePoint search results using REST ajax call from Html


Hi,

We all aware the SharePoint exposed REST Api in order to perform various action at client side. There are some other ways also which a developer can adopt instead of REST(like CSOM) but that requires again client context. So it is recommenced that if we are using SharePoint Apps then use CSOM to get and update the data. Where as REST can be used in apps as well as some external applications.

This blog is intended to show how user can utilize the REST api and get the SharePoint Search results. There are few pre-requisites or conditions which must be fulfilled before proceeding further.

  • The machine where this code will be executed must have access to sharepoint site which means machine must be either in same domain or cross domain accessibility is there.
  • Search must be configured at SharePoint server.
  • Data must be properly crawled and you must get some results when searched for some keyword.

Steps:

1) Open the Explorer or any desired location and create a text file with ant desired name.

2) Now open this txt file in Notepad and click on “Save as..” option. Here select the “Save as type” as “All” and save the file in “.html” format as shown below:

1

3) Now open this file in any desired text editor(I love to use Notepad++ for same) and paste the following code:

<script src=”http://code.jquery.com/jquery-2.1.4.js&#8221; type=”text/javascript”></script>
<script type=”text/javascript”>
$(document).ready(function () {
$(“#SearchQuery”).click(function() {
$.ajax({
url: “http://<server URL>/_api/search/query?querytext='”+$(“#search-input”).val()+”‘&sourceid=%27b09a7990-05ea-4af9-81ef-edfab16c4e31%27″,
headers: { Accept: “application/json;odata=verbose” },
success: function (data) {

console.log(data.d);

},
error: function (jQxhr, errorCode, errorThrown) {
console.log(errorThrown);
}
});
});

});</script>
<input type=”text” id=”search-input”>
<input type=”button” id=”SearchQuery” value=”Search”>
<div id=”resultsDiv”></div>

Issues faced:

1) minFreeMemoryPercentageToActivateService memory issue:

2

Resolution: Open the web config of the web application and find out the entry with

<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” />

to

<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” minFreeMemoryPercentageToActivateService=”1″/>

Happy SharePointing 🙂

 

 

 

Advertisements

Create Sub Site in SharePoint using REST and c# console application


Hi,

Recently, I got an requirement to create a SharePoint sub site from the some .Net application which is hosted somewhere hosted outside the SharePoint environment. It is provided that the .Net application can be added in same domain. So if I brief about requirement here:

  • Need to create a sub site in SharePoint site collection based on some default template(later on custom template)
  • Use REST(not even CSOM) will be used in order to create.
  • API call will be send from some other machine(not SharePoint machine) which is in same domain and can access the SharePoint site.

There are few challenges which I faces if we try to work with such kind of requirements. The authentication tokens and RequestDigest data are the crucial things to retrieve.

I have explored some way to execute REST API and create a sub site without navigating to SharePoint site. Follow the given steps to achieve the same:

1) Create a simple console application with c# selected language.

1

2) Next is to install the Newtonsoft.Json. Navigate to Visual studio menu: “View” > “Other Windows” > “Package Manager Console” and Then type the following: “Install-Package Newtonsoft.Json”

2

 

3) Now install RestSharp using the package manager. Type the following: “Install-Package RestSharp”

3

4) Now open the Program.cs file of console application and paste the code below:

RestClient RC = new RestClient(“http:/SharepointSiteUrl/_api”);
NetworkCredential NCredential = System.Net.CredentialCache.DefaultNetworkCredentials;//new NetworkCredential(“mohitvashishtha”, “******”, “mydomain”);
RC.Authenticator = new NtlmAuthenticator(NCredential);

Console.WriteLine(“Creating Rest Request”);

RestRequest Request = new RestRequest(“contextinfo?$select=FormDigestValue”, Method.POST);
Request.AddHeader(“Accept”, “application/json;odata=verbose”);
Request.AddHeader(“Body”, “”);

string ReturnedStr = RC.Execute(Request).Content;
int StartPos = ReturnedStr.IndexOf(“FormDigestValue”) + 18;
int length = ReturnedStr.IndexOf(@”””,”, StartPos) – StartPos;
string FormDigestValue = ReturnedStr.Substring(StartPos, length);

Console.WriteLine(“Creating Site……”);

var Data = string.Concat(
“{‘parameters’:{‘__metadata’:{‘type’:’SP.WebCreationInformation’},”,
“‘Title’:’Team projects 3′,’Url’:’TeamProjects3′,’WebTemplate’:’STS’,”,
“‘UseSamePermissionsAsParentSite’: true}}”);

Request = new RestRequest(“web/webs/add”, Method.POST);
Request.RequestFormat = DataFormat.Json;
Request.AddHeader(“Accept”, “application/json;odata=verbose”);
Request.AddHeader(“X-RequestDigest”, FormDigestValue);
Request.AddParameter(“application/json;odata=verbose”, Data, ParameterType.RequestBody);

Console.WriteLine(RC.Execute(Request).Content);
Console.WriteLine(“SharePoint Site is successfully created.”);
Console.ReadLine();

5) Now application is ready to run. Make sure that all the namespace issues are resolved.

6) It will take some time to create site but output window will display the details it got from the Request.

In case of already existing site:

4

 

Just a little explanation about the above code, this code is actually getting the request digest first and then in second REST request it will pass the same reader digest. There are few chances that this code will throw 401 unauthorized error if user does not have permission on sharepoint site. But there are option to hardcode the credential too using NetworkCredentials object commented in above code.

Hope this information is helpful to you. Thanks for time.

Happy SharePointing 🙂

 

 

 

Enable SP.JS in publishing sites for SP 2013


Hi,

In my previous post, I have explained the way to add CSOM on master page of any kind of site. But later on when testing same code with publishing site, I realized that sp.js is not loaded on publishing site by default.

So in this post I will discuss how to enable sp.js in Publishing Pages in SharePoint 2013. As the SharePoint uses minimal download strategy it prevents the page to have sp.js when published but the point to note is when you open your ribbon bar (edit or unpublished state) sp.js  script gets loaded in your page .

Note : SharePoint loads scripts on Demand
So to solve this we can do like this: Add a script editor webpart in your page and in script tags just add the following code snippet:
SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’, alert(‘I have loaded the sp.js script.’));
Where instead of alert method you can use any JS method and will be executed after sp.js is loaded.
Happy SharePointing :).

SharePoint CSOM for beginners: Get Current User details


Hi Guys,

This blog is targeted to developers who are novice to the client side object model in SharePoint. SharePoint apps by default provides a basic stub for getting user details inside app. But sometimes it is required to add client side code in simple script file to get user information. I hope this information will also be helpful starters of client side object model.

Pre-requisites:

1) Any version of SharePoint installed: SP 2013, SP 2010 or SP Online

2) A web application and a root site collection inside it. It does not matter whether site is team site or any other type of site.(Note: In case of publishing site you need to enable sp.js file loading).

3) SharePoint Designer installed.

Step I: Create a custom script file

A script file is required in order to place CSOM code to be executed. Well, here depending upon usability user can chooses any one of these two locations to create this file:

List or Style library: It will be hard to update script file if it is placed under style library. Every time one have to update the file in SP Designer in order to make any changes or one have to upload the latest file each time in case of any update.

15 hive folder: This is my favorite place in order to do such kind of research. Create a dummy folder under “15/Template/layouts/dummy”.

I am referring second approach as it is very comfortable to update the files in 15 hive. Now open the dummy folder and create a JS file there with any name say, CSOMDemo.js. Let this file blank as of now.

Step II: Refer a custom script file

Once custom JS file is created, now next is to refer this file to master page so that it will be utilized by SharePoint. There are also many option to refer the file: Master page, Page layout(in case of publishing site), using content editor web part etc.

For this blog I am referring the script file to master page. In order to do same, Open the site using SP Designer and click on All Files > _catalogs >  masterpage > seattle.master(for team site). Then right click on the file and select the option “Edit File in Advanced Mode”.

Capture1                        Capture2

Now find out the head section add following lines:

<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js “></script>
<script type=”text/javascript” src=”/_layouts/15/dummy/Script/CSOMDemo.js”></script>

 

Names can vary according to your naming conventions. But one these lines are placed in master page, all site pages will be registered and enabled with jQuery and custom scripts.

Step III: Write CSOM Code

Open the custom script file and paste the following code in side it.

var currentUser;
$( document ).ready(function() {
console.log(‘ready’);
url = window.document.location.href;

// In case of Publishing site please use following code line

// SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’, init);

ExecuteOrDelayUntilScriptLoaded(init,’sp.js’);

function init(){
var context = new SP.ClientContext.get_current();
var web = context.get_web();
currentUser = web.get_currentUser();
currentUser.retrieve();
context.load(web);
context.executeQueryAsync(
function(){
//On success function
console.log(‘init succeeded..’);
console.log(currentUser.get_loginName());
console.log(currentUser.get_id());
console.log( currentUser.get_title());
console.log(currentUser.get_email());
},
function(){ //On fail function
alert(‘Error: ‘ + args.get_message() + ‘\n’ + args.get_stackTrace());
}
);
}
});

That all. Here is the result:

Capture3

 

Hope that code will be helpful for you.

Happy SharePointing 🙂

SharePoint get followed sites using REST Api


Recently I was tasked with a project requirement that the user should be able to see list of content he/she followed. To me this sounds much like using the following feature of SharePoint 2013 which allows you to follow documents, sites, people and tags. Also, we don’t want the user to navigate to his/her mySite and have a look on to the content followed.

We can use the SharePoint 2013 Representational State Transfer (REST) service to do the same tasks you can do when you use the .NetCSOM, JSOM.

Here I explain how to retrieve the site name and URL followed by the current user in SharePoint 2013 using a client object model (REST API and JavaScript) and displaying it in the SharePoint page.

1. Create a new page and a Content Editor Webpart (CEWP).

Create a New page

2. Edit the web part that was added to the page.

Edit the web part

3. Upload your text file script into the site assests and copy the path of the text file and paste it into the Content link in CEWP.

4. Output

Output

Code

The following example shows how to retrieve all of the following sites:

<html>
<head>
<script type=”text/javascript” src=”//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js”></script>

<script type=”text/javascript”>
var followingManagerEndpoint;
var followedCount;

var followingEndpoint;
var URL;
var website;
var clientContext;

SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’, loadWebsite);
function loadWebsite() {
clientContext = SP.ClientContext.get_current();
website = clientContext.get_web();
clientContext.load(website);
clientContext.executeQueryAsync(onRequestSucceeded, onRequestFailed);
}

function onRequestSucceeded() {

URL = website.get_url();
followingManagerEndpoint = decodeURIComponent(URL) + “/_api/social.following”;

getMyFollowedContent();
}

function onRequestFailed(sender, args) {
alert(‘Error: ‘ + args.get_message());
}

// Get the content that the current user is following.
// The “types=14” parameter specifies all content types
// (documents = 2 + sites = 4 + tags = 8).
function getMyFollowedContent() {

$.ajax( {
url: followingManagerEndpoint + “/my/followed(types=14)”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: followedContentRetrieved,
error: requestFailed
});
}

// Parse the JSON data and iterate through the collection.

function followedContentRetrieved(data) {
var stringData = JSON.stringify(data);
var jsonObject = JSON.parse(stringData);
var types = {
1: “document”,
2: “site”,
3: “tag”
};

var followedActors = jsonObject.d.Followed.results;
var followedList = “You’re following items:”;

for (var i = 0; i < followedActors.length; i++) {
var actor = followedActors[i];
followedList += “<p>The ” + types[actor.ActorType] + “: \”” +actor.Name + “\”</p>”+”<p>Site URL ” + “: \”” +
actor.Uri+ “\”</p>”;;
}
$(“#Follow”).html(followedList);
}

function requestFailed(xhr, ajaxOptions, thrownError) {
alert(‘Error:\n’ + xhr.status + ‘\n’ + thrownError + ‘\n’ + xhr.responseText);
}

</script>
</head>
<body>
<div id=”Follow”></div>
</body>
</html>

Happy SharePointing 🙂

Send message to client app part using a “PostMessage Shim”


In this post, I’ll walk through how to use the postMessage api to enable cross-frame communication between your Client App Parts and the hosting SharePoint page, to make your SharePoint App Parts more dynamic and responsive to changes in the parent page.

Overview

In the SharePoint 2013 App Model, Client App Parts are implemented as iframes into pages hosted in App Webs or Provider Hosted web applications. Because SharePoint apps are hosted on different domains, the iframes can’t use javascript to access the parent window and get information from the hosting page. This is a good thing. You wouldn’t want a Client App Part that you installed from the marketplace to be able to see the list of customers on that List View web part that sits right next to it on the page. But it does make it very hard as a developer to give Client App Parts more dynamic page information to work with. The only contextual info a Client App Part can get is through Client App Part properties.

Normal SharePoint Web Parts have a number of ways of getting initialization data from the hosting page when they first load up:

  1. Web Part Properties (Tool Pane)
  2. Web Part Connections (Passing info from Web Part to Web Part)
  3. Host Page QueryString
  4. Reading Hidden Fields or other form elements on the page
  5. Built-in SharePoint objects like _spPageContextInfo
  6. Reading the metadata of the host page

Unfortunately, SharePoint Client App Parts can only get information from the first option, through Client App Part Properties. When you build your Client App Part with custom properties, they appear in the App Part’s tool pane when you edit the App Part, similar to normal Web Part toolpane properties. Client App Part properties are a little different though – setting these actually appends a querystring parameter to the App Part’s iframe src attribute, which your App Part page can then read when it starts up. That’s good for setting a one-time configuration of your App Part, but you can’t change any of those properties dynamically in response to changes in the host page.

In this post, I’ll show you how to pass additional data from the host page to your Client App Parts via the postMessage api, effectively opening the door to leveraging 2-6 above. The example I’ll show will be an App Part placed on the MySite Host’s About Me page. The App Part will read the host page’s accountname querystring parameter to determine which user profile is being viewed, and will display some basic profile information about that user.

The postMessage API

The postMessage API was designed to enable safe, cross-domain communication between windows or iframes. Essentially each window needs to opt-in to accepting communications from other cross-origin/cross-domain windows. Any window or iframe can send messages to another window or iframe just by calling the postMessage method. If the target window hasn’t opted-in to listen for these messages, the messages are just silently ignored.

Requesting Information from the Host Page

The first step in getting this to work is to configure your Client App Part page to send a request to the host page, and to configure a listener for the host page’s response.

To start this out, using Visual Studio 2013, I created a new SharePoint App project called PostMessageApp, added a Client Web Part (Host Web) called PostMessageAppPart, and created a new page for the App Part called PostMessageAppPartPage.aspx. I gave the App Part the Read permissions to the User Profile (Social) permission set.

The basic solution structure.

In the App Part page, I added some basic HTML markup:

1
2
3
4
5
6
7
8
9
<body>
    <div>
        Host page's full url:<br />
        <textarea id="hostpageurl" readonly="readonly" style="width:100%;height:75px;overflow:scroll;" ></textarea><br /><br />
        First name: <span id="firstname"></span><br />
        Last name: <span id="lastname"></span><br />
        Department: <span id="department"></span><br />
    </div>
</body>

Here is what the app part looks like empty:

Empty App Part

In the newly created App Part page, I added a javascript function to the page head called getQueryStringParameter which is needed to extract querystring information. You’ve probably seen a similar function in many of the SharePoint Hosted App code samples on the internet. This version below includes an overload to get a querystring value from a passed-in url (rather than the current document’s url), which will be used later:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function getQueryStringParameter(key, urlToParse) {
    /// <signature>
    /// <summary>Gets a querystring parameter, case sensitive.</summary>
    /// <param name="key" type="String">The querystring key (case sensitive).</param>
    /// <param name="urlToParse" type="String">A url to parse.</param>
    /// </signature>
    /// <signature>
    /// <summary>Gets a querystring parameter from the document's URL, case sensitive.</summary>
    /// <param name="key" type="String">The querystring key (case sensitive).</param>
    /// </signature>
    if (!urlToParse || urlToParse.length === 0) {
        urlToParse = document.URL;
    }
    if (urlToParse.indexOf("?") === -1) {
        return "";
    }
    var params = urlToParse.split('?')[1].split('&');
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split('=');
        if (singleParam[0] === key) {
            return decodeURIComponent(singleParam[1]);
        }
    }
    return "";
}

After including the querystring function, I added the following script underneath it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(function () {
    var getHostPageInfoListener = function (e) {
        /// <summary>Callback function for getting the host page's info via postMessage api.</summary>
        console.log("postMessage response received: " + e.data);
        var messageData;
        try {
            messageData = JSON.parse(e.data);
        }
        catch (error) {
            console.log("Unable to parse the response from the host page.");
            return;
        }
    }
    // Register the listener
    if (typeof window.addEventListener !== 'undefined') {
        window.addEventListener('message', getHostPageInfoListener, false);
    }
    else if (typeof window.attachEvent !== 'undefined') {
        window.attachEvent('onmessage', getHostPageInfoListener);
    }
    // Send the host page a message
    var hostPageMessage = {};
    hostPageMessage.message = "getHostPageInfo";
    var hostPageMessageString = JSON.stringify(hostPageMessage);
    window.parent.postMessage(hostPageMessageString, document.referrer);
    console.log("Sent host page a message: " + hostPageMessageString);
})();

This script accomplishes two things: 1) it sends a message to the host page requesting information, and 2) it registers a listener (callback) for the response from the host page. Notice that I’m sending a stringified JSON object to the host page, which I will reconstitute later. When you send messages between windows, you are just sending one string of data. You can choose to send XML, plain text, or even stringified JSON.

At this point I can send a message to the host page, but since the host page isn’t listening for it yet, the message will just silently get ignored.

Sending Information Back to the Client App Part Page

The next step in getting this to work is to configure the host page to listen and respond to the request for more information. For this, some javascript must be placed on the host page to opt-in to receiving messages from other windows. You can add javascript to a SharePoint page in a variety of ways, through a Content Editor or Script Editor web part, by editing the page or page layout in SharePoint Designer, or by adding the script directly to a masterpage.

For this example, I am going to edit the About Me page in a MySite Host site collection (“Person.aspx”) with SharePoint Designer to add the following script. I am going to add the script to the PlaceHolderAdditionalPageHead area:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<asp:Content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
<SPSWC:ActivityFeedLink Consolidated="false" runat="server"/> 
<SPSWC:MySiteHideDiv HideRibbonRow="true" runat="server"/>
<script type="text/javascript">
(function() {
    var sendHostPageInfoListener = function (e) {
        var messageData;
        try
        {
            messageData = JSON.parse(e.data);
        }
        catch (error)
        {
            console.log("Could not parse the message response.");
            return;
        }
        // Construct the return data to send to the app part
        var returnData = {};
        returnData._spPageContextInfo = _spPageContextInfo;
        returnData.hostPageURL = document.URL;
        var returnDataString = JSON.stringify(returnData);
        e.source.postMessage(returnDataString, e.origin);
        console.log("Sent app part iframe message: " + returnDataString);
    };
    // Register the listener
    if (typeof window.addEventListener !== 'undefined') {
        window.addEventListener('message', sendHostPageInfoListener, false);
    }
    else if (typeof window.attachEvent !== 'undefined') {
        window.attachEvent('onmessage', sendHostPageInfoListener);
    }
})();
</script
</asp:Content>

The code above does two things: 1) Opts-in to listen for messages from other windows, and 2) Sends JSON data about the current page to the window that sent the request. I’ve chosen here to send a couple of pieces of information. First, I sent the full url of the host page, including any querystring parameters, by passing the document.URL. Second, I’ve also chosen to send the _spPageContextInfo object of the host page, which contains some rich data about the host page. This is just to demonstrate that you aren’t limited to sending plain text, you can serialize javascript objects from the host page as well.

With the App Part and the script above on the page, I can now see the communication back and forth between the windows in the console, and can view the returned data in a watch window. Notice the host page’s _spPageContextInfo is fully deserialized and expanded into a javascript object for use in the App Part.

The returned data

Securing the Requests

By putting these scripts in place, I have allowed my host page to give information to any window or iframe that sends a request message. It’s a good idea to make this more secure, and only give host page information out to windows that you trust. You can get as restrictive or permissive as you want/need with this validation.

For home-grown side-loaded SharePoint apps, this could be as simple as passing a shared key around, and checking on both sides. To demonstrate this basic validation, I’ll add a couple of lines to the code in the Client App Part page to store and send the secret key and to parse and read it from the host page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var secretKey = "mysecretkeyxyz";
(function () { 
    var getHostPageInfoListener = function (e) {
        /// <summary>Callback function for getting the host page's info via postMessage api.</summary>
        console.log("postMessage response received: " + e.data);
        var messageData;
        try {
            messageData = JSON.parse(e.data);
        }
        catch (error) {
            console.log("Unable to parse the response from the host page.");
            return;
        }
        if (!messageData || !messageData.secretKey || messageData.secretKey !== secretKey) {
            console.log("Could not validate the message.");
            return;
        }
    };
    // Register the listener
    if (typeof window.addEventListener !== 'undefined') {
        window.addEventListener('message', getHostPageInfoListener, false);
    }
    else if (typeof window.attachEvent !== 'undefined') {
        window.attachEvent('onmessage', getHostPageInfoListener);
    }
    // Send the host page a message
    var hostPageMessage = {};
    hostPageMessage.secretKey = secretKey;
    hostPageMessage.message = "getHostPageInfo";
    var hostPageMessageString = JSON.stringify(hostPageMessage);
    window.parent.postMessage(hostPageMessageString, document.referrer);
    console.log("Sent host page a message: " + hostPageMessageString);
})();

On the host page, I’ve also added some validation code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(function() {
    var sendHostPageInfoListener = function (e) {
        var secretkey = "mysecretkeyxyz";  
        var messageData;
        try {
            messageData = JSON.parse(e.data);
        }
        catch (error)
        {
            console.log("Could not parse the message response.");
            return;
        }
        if (!messageData || !messageData.secretKey || messageData.secretKey !== secretKey) {
            console.log("Could not validate message.");
            return;
        }
        // Validate that it contains the expected instruction
        if (messageData.message !== "getHostPageInfo") {
            return;
        }
        // Construct the return data to send to the app part
        var returnData = {};
        returnData.secretKey = secretKey;
        returnData._spPageContextInfo = _spPageContextInfo;
        returnData.hostPageUrl = document.URL;
        var returnDataString = JSON.stringify(returnData);
        e.source.postMessage(returnDataString, e.origin);
        console.log("Sent app part iframe message: " + returnDataString);
    };
    // Register the listener
    if (typeof window.addEventListener !== 'undefined') {
        window.addEventListener('message', sendHostPageInfoListener, false);
    }
    else if (typeof window.attachEvent !== 'undefined') {
        window.attachEvent('onmessage', sendHostPageInfoListener);
    }
})();

For the purposes of this example, this basic validation will suffice to demonstrate the point, but I would recommend beefing this up in your own implementations.

Now, on to the last part, consuming the information.

Consuming the Data

Once you’ve got these hooked up, you can work with the data. In the App Part Page, I modified the getHostPageInfoListener function with some code to get the accountname querystring parameter from the data the host page returned, and to query the User Profile REST api to get data about that user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
var getHostPageInfoListener = function (e) {
    /// <summary>Callback function for getting the host page's info via postMessage api.</summary>
    console.log("postMessage response received: " + e.data);
    var messageData;
    try {
        messageData = JSON.parse(e.data);
    }
    catch (error) {
        console.log("Unable to parse the response from the host page.");
        return;
    }
    if (!messageData || !messageData.secretKey || messageData.secretKey !== secretKey) {
        console.log("Could not validate the message.");
        return;           
    }
    var appWebUrl = getQueryStringParameter("SPAppWebUrl");
    var requestUrl = "";
    var requestData = {};
    var accountName = getQueryStringParameter("accountname", messageData.hostPageURL);
    if (!accountName || accountName.length === 0) {
        console.log("Could not find an accountname querystring parameter, using the current user.");
        // Use the current user instead.
        requestUrl = appWebUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
    }
    else {
        requestUrl = appWebUrl + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)";
        requestData["@v"] = "'" + accountName + "'";
    }
    jQuery("#hostpageurl").html(messageData.hostPageURL);
    jQuery.ajax({
        url: requestUrl,
        type: "GET",
        data: requestData,
        headers:{ Accept:"application/json;odata=verbose" },
        success: function (data) {
            var properties = data.d.UserProfileProperties.results;
            for (var i = 0; i < properties.length; i++) {
                if (properties[i].Key === "FirstName") {
                    jQuery("#firstname").html(properties[i].Value);
                }
                else if (properties[i].Key === "LastName") {
                    jQuery("#lastname").html(properties[i].Value);
                }
                else if (properties[i].Key === "Department") {
                    jQuery("#department").html(properties[i].Value);
                }
            }
        },
        error: function (jqxr, errorCode, errorThrown) {
            console.log(jqxr.responseText);
        }
    });
};

You can see the result below, where I am logged in as Adam Toth, but am viewing Harry Tuttle’s profile:

App Part displaying another user's profile information.

Conclusion

With a simple javascript shim in place on a host page, I’ve shown how much richer contextual data can be passed to a Client App Part. Until Microsoft implements an alternative method, the postMessage api remains a safe and viable option for tackling scenarios that sandbox or full-trust web parts have been able to do for some time.

SharePoint 2013: The search service is not able to connect to the machine that hosts the administration component.Verify that the administration component.


Hi,

Issue:

The search service is not able to connect to the machine that hosts the administration component. Verify that the administration component ‘GUID’ in search application ‘Search Service Application’ is in a good state and try again. In Farm Search Administration page when click on “Modify Topology” get error “An unhandled exception occurred in the user interface.Exception Information: Exception has been thrown by the target of an”

Cause: Search is not able to connect is because of name reasons, in this article I am explaining various the solution of this issue.

Solutions: Please find the below solutions, That one of it can resolve the issue.

Solution 1:

In the end it turns out to be that the application pool that hosts the search service application somehow doesn’t have the correct access.
You can simply change the application pool to use SharePoint Web Services System for search service applications and check.
1. Click on Start > Run > Type Inetmgr > Click OK

0094

 

 

 

 

 

 

 

 

 

 

 

2.  In IIS > Expand server > Expand sites > Expand “SharePoint Web Services”
0096

3. Now check all the GUID 1 by 1 in content view unless you find searchadmin.svc and searchservice.svc

0095

4. Right click GUID go to advance settings

0097

5. Change the application to “SharePoint Web Services” > Click OK
0098

Solution 2: Enable the timer job and do IIS reset

1. Run below PS command to know the status of timer job
Get-SPTimerJob job-application-server-admin-service
Result ==> Is Disabled: True

  1. Run below PS command to enable the service.
    Enable-SPTimerJob job-application-server-admin-service
    Result ==> IsDisabled: False
  2. Do Net Stop sptimerv4
  3. Do Net start sptimerv4
  4. DO iisreset

Solution 3:Ensure the account has full control permissions on the Search service application and IIS account used by this service application
Follow below steps
1. Open Central Admin  > Select Security > Select “Configure service accounts”
0092

2. Select the search service application

0093

3.   For “select account for this component” Select a account which has full permission

Hope that helps. Happy SharePointing 🙂