I have the same problem as in this question SharePoint 2013 - display the detail from a list item in a branded page, NOT the default SharePoint details page
but my question is that i don't understand yet how to use this script ?
and how can I retrieve the ID of the item from the url to retrieve his detail ? and how can I represent that informations in my page
Since this is kind of a broad question, a more general answer
Most common ways to access/display data on SharePoint
asp.net webpart
asp.net page
silverlight webpart
sharepoint app based on javascript
with asp.net you would mostly use the SharePoint Object Model, accessing data with either SandBoxed or Form solution, by querying SPSite -> SPWeb -> SPList -> SPListItem, like
using (SPSite site = new SPSite("Url to SharePoint site"))
{
using (SPWeb web = site.OpenWeb("Url to SharePoint web"))
{
SPList list = web.TryGetList("ListName");
SPListItem item = list.GetItemById(ID);
...
or
...
SPQuery query = new SPQuery();
query.Query = '<Where><Eq><FieldRef Name="ID" /><Value Type="Number">ID</Value>';
SPListItemCollection collection = list.GetItems(query);
foreach (SPListItem item in collection) {
...
}
}
}
Silverlight and Javascript either use the Rest services or the SharePoint Client Side Object Model
with Javascript you could use:
- AJAX calls by using the odata compatible Rest services (which partly allows the usage of managed meta data),
- SharePoint CSOM
- The older SOAP service
- The SPDataQuery
The odata webservice allows you to get data based on the following urls:
lists: http://sharepointsite/web/_api/lists
listdetail: http://sharepointsite/web/_api/lists/getbytitle(%27listName%27)
fields: http://sharepointsite/web/_api/lists/getbytitle(%27listName%27)/Fields
Items: http://sharepointsite/web/_api/lists/getbytitle(%27listName%27)/Items
Specific item: http://sharepointsite/web/_api/lists/getbytitle(%27listName%27)/Items?$filter=(ID eq 1)
The returned data is either xml atom feed or json, based on the request headers
provided you use jquery you could use
<script type="text/javascript">
function getItem(list, id, callback) {
var url = _spPageContextInfo.webAbsoluteUrl;
$.ajax({
url: url + '/_api/lists/getbytitle(%27' + list + '%27)/Items(' + id + ')',
header: {
'accept': 'application/json;odata=verbose'
},
complete: function(data, status) {
if (status === 'error') {
// error occured
callback(false);
return;
}
var results = JSON.parse(data.responseText).d.results, i;
callback(true, results);
}
});
}
getItem('listName', 5, function(success, results) {
if (success) {
// results is an array of objects with data
}
});
</script>
Related
Our company has multiple brands and each brand has its own host name, but they are all part of the same site. We can let customers share baskets and other session information when they switch between brands via a redirect link using URLUtils.sessionRedirect.
But URLUtils is not available in content assets. Is it possible to form a session redirect link in content asset keeping all the session information?
Thanks in advance.
You can include dynamic content in Content Assets with the $include('Controller-Name', 'name1', 'value1', 'name2', 'value2', ...)$ syntax. See the MarkupText Class Documentation for more info on that syntax. The 'name1' and 'value1' parameters are mapped as query string attributes eg: Controller-Name?name1=value1&name2=value2
Create a controller that outputs the session redirect link you need, and call it via that syntax like: $include(Util-RenderSessionLink, 'siteID', 'foo')$
The controller would need to use a response Content-Type header of text/plain or something like that so that nothing is injected into the response. (eg: Storefront toolkit or tracking tags) For example:
response.setContentType('text/plain');
Alternatively, you could process the content asset for some sorts of keys that you perform find & replace operations on. For example, the following code does a find & replace on a Content Asset's body content for the key: '%%SessionLink%%'.
var ContentMgr = require('dw/content/ContentMgr');
var URLUtils = require('dw/web/URLUtils');
if (!empty(content) {
var content = ContentMgr.getContent('my-content-id');
var contentOut = "";
var viewData = {};
contentOut = content.custom.body.getMarkup()
.replace('%%SessionLink%%', URLUtils.sessionRedirect(...));
viewData.content = contentOut;
// then output your `pdict.content` key within a template with the appropriate encoding
}
If anybody else is running into this, we added a bit of client-side javascript that pickups up all outbound links and if it's one of our domains it sends them through a session redirect. This way we don't need content managers to fix very link between domains:
var domains = ["domaina.com", "domainb.com", "domainc.com"]
var sessionRedirectBase = '/s/Our-Site/dw/shared_session_redirect';
$(document).on("click.crossSite", "a", (e) => {
const href = $(e.currentTarget).attr("href");
if (href) { //does the link have a href
if (href.match(/^(http(s)?:)?\/\//)) { //is href an absolute url
const url = new URL(href);
if (url.hostname != window.location.hostname && domains.indexOf(url.hostname) > -1) { //is hostname not the current one and part of the domains array
e.preventDefault();
const sessionRedirect = `${sessionRedirectBase}?url=${encodeURIComponent(href)}`
window.location = sessionRedirect;
}
}
}
});
I have a .net core 2.0 app and am implementing external login providers like google, twitter, and facebook. I have the requirement to get the user's display name and profile picture, and can't find any documentaion of how to achieve this in .net core 2.0.
I add the authentication like this post: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/
Here are my twitter login and callback functions...
[HttpGet]
[Route("/api/security/login/type/socialmedia/twitter")]
public IActionResult GetTwitterLogin(string redirect_uri)
{
ClientCallback = redirect_uri;
string redirectUrl = "/api/security/login/type/socialmedia/twittercallback";
var properties = SignInManager.ConfigureExternalAuthenticationProperties("Twitter", redirectUrl);
return Challenge(properties, "Twitter");
}
[HttpGet]
[Route("/api/security/login/type/socialmedia/twittercallback")]
public async Task<HttpResponseMessage> GetTwitterCallBackAsync()
{
var info = await SignInManager.GetExternalLoginInfoAsync();
var result = await SignInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
}
else
{
}
Response.StatusCode = (int)HttpStatusCode.OK;
return null;
}
It looks like you can get some items from info.Principal.Claims, but nothing for the user's display name or profile picture.
How do you get the display name or profile picture for the various login providers?
I finally figured this out...you need to add claims when you configure the authentication. These claims look at the resulting json response and pulls items from it. The pertinent lines are the ClaimActions items.
services.AddAuthentication()
.AddTwitter(twitterOptions =>
{
twitterOptions.ConsumerKey = cfg.SystemConfig["TwitterConsumerKey"];
twitterOptions.ConsumerSecret = cfg.SystemConfig["TwitterConsumerSecret"];
twitterOptions.SaveTokens = true;
twitterOptions.RetrieveUserDetails = true;
twitterOptions.ClaimActions.MapJsonKey("display-name", "name");
twitterOptions.ClaimActions.MapJsonKey("profile-image-url", "profile_image_url_https");
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = cfg.SystemConfig["FacebookClientId"];
facebookOptions.AppSecret = cfg.SystemConfig["FacebookClientSecret"];
facebookOptions.SaveTokens = true;
facebookOptions.ClaimActions.MapJsonKey("display-name", "name");
})
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = cfg.SystemConfig["GoogleClientId"];
googleOptions.ClientSecret = cfg.SystemConfig["GoogleClientSecret"];
googleOptions.SaveTokens = true;
googleOptions.ClaimActions.MapJsonSubKey("profile-image-url", "image", "url");
googleOptions.ClaimActions.MapJsonKey("display-name", "displayName" );
});
After getting the login information in your callback using
var info = await SignInManager.GetExternalLoginInfoAsync();
If populated successfully you can query the claims and find the values
var profileImageClaim = info.Principal.Claims.Where(x => x.Type == "profile-image-url").FirstOrDefault();
Facebook images are different from google and twitter and can be found using...
var claim = info.Principal.Claims.Where(x => x.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").FirstOrDefault();
var url = "http://graph.facebook.com/" + claim.Value + "/picture";
In ASP.NET Core 2.0, FacebookOptions uses extension methods on ClaimActions to map the profile data returned by UserInformationEndpoint.
ClaimActions.MapJsonKey(ClaimTypes.DateOfBirth, "birthday");
In the mapping above, "birthday" is a top-level property in the Facebook Graph API response that's mapped to the value represented by the claim ClaimTypes.DateOfBirth.
To grab the profile picture you would do the same thing, but since the picture in the Graph API response is a nested JSON object, you would have to use MapCustomJson()
services.AddAuthentication()
.AddFacebook(options =>
{
// ...other options omitted
options.Fields.Add("picture");
options.ClaimActions.MapCustomJson("urn:facebook:picture",
claim => (string)claim.SelectToken("picture.data.url"));
})
Here, claim is a NewtonSoft JObject that uses JPath syntax to select the nested property value and cast it to a string.
The profile picture URL will now appear in your Claims list.
hello I'm trying to consume a REST service in an app for windows 8.1, I'm so gratefull if you can give me more information related about this topic, thanks !!
You could use the XMLHttpRequest object. But, since you are using WinsJS, the WinJS.xhr function would be more convenient.
Here's an example on how to use it:
(function () {
"use strict";
var app = WinJS.Application;
app.onactivated = function (args) {
// Change RSS feed URL as you need to.
var resDiv = document.getElementById("divResult"),
rssURL = "http://blogs.windows.com/windows/b/appbuilder/rss.aspx";
// Call WinJS.xhr to retrieve an XML feed from the Web.
WinJS.xhr({
url: rssURL,
responseType: "document"
}).done(
// When the result has completed, check the status.
function completed(result) {
if (result.status === 200) {
// Get the XML document from the results.
var xmlDocument = result.responseXML,
title = xmlDocument.getElementsByTagName('title')[0];
// Update the HTML in the app.
resDiv.style.backgroundColor = "lightGreen";
resDiv.innerText = "Downloaded RSS feed from the " + title.textContent + " blog.";
}
});
};
app.start();
})();
This is my first question that I have ever posted on here so please be gentle!
I am trying to use a SharePoint 2013 REST service call using JQUERY Ajax to return the total 'likes' the most recent post to a user's SharePoint (MySite) newsfeed has recieved. Basically I have developed a little social webpart for our company intranet that displays the user's portrait and their last post (truncated). I thought it would be cool to also show how many likes that post has recieved but I have not been able to find out how to do so.
Here is a segment of my code which is working but I am only adding it to this question to give some insight to what I am trying to achieve -
$.ajax({
url: "/_api/social.feed/my/feed(MaxThreadCount=1,SortOrder=1)",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
dataType: 'json',
success: function (data) {
if (data.d.SocialFeed.UnreadMentionCount != null)
{document.getElementById("unreadmentions").innerHTML = data.d.SocialFeed.UnreadMentionCount;}
else
document.getElementById("unreadmentions").innerHTML = 0;
html = data.d.SocialFeed.Threads.results[0].Actors.results[0].StatusText;
if (html == null)
{document.getElementById("socialstatus").innerHTML = "No posts available";}
else
{
html = html.substring(0,30) + " ...";
document.getElementById("socialstatus").innerHTML = html;
}
}, error: function (data) {}
For the life of me I can not understand why that particular feed does not also return how many likes that post has recieved. Seems kind of silly that it wouldnt.
Cheers for the help!
I am building a REST API for my project. The API for getting a given user's INFO is:
api.com/users/[USER-ID]
I would like to also allow the client to pass in a list of user IDs. How can I construct the API so that it is RESTful and takes in a list of user ID's?
If you are passing all your parameters on the URL, then probably comma separated values would be the best choice. Then you would have an URL template like the following:
api.com/users?id=id1,id2,id3,id4,id5
api.com/users?id=id1,id2,id3,id4,id5
api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5
IMO, above calls does not looks RESTful, however these are quick and efficient workaround (y). But length of the URL is limited by webserver, eg tomcat.
RESTful attempt:
POST http://example.com/api/batchtask
[
{
method : "GET",
headers : [..],
url : "/users/id1"
},
{
method : "GET",
headers : [..],
url : "/users/id2"
}
]
Server will reply URI of newly created batchtask resource.
201 Created
Location: "http://example.com/api/batchtask/1254"
Now client can fetch batch response or task progress by polling
GET http://example.com/api/batchtask/1254
This is how others attempted to solve this issue:
Google Drive
Facebook
Microsoft
Subbu Allamaraju
I find another way of doing the same thing by using #PathParam. Here is the code sample.
#GET
#Path("data/xml/{Ids}")
#Produces("application/xml")
public Object getData(#PathParam("zrssIds") String Ids)
{
System.out.println("zrssIds = " + Ids);
//Here you need to use String tokenizer to make the array from the string.
}
Call the service by using following url.
http://localhost:8080/MyServices/resources/cm/data/xml/12,13,56,76
where
http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76
As much as I prefer this approach:-
api.com/users?id=id1,id2,id3,id4,id5
The correct way is
api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5
or
api.com/users?ids=id1&ids=id2&ids=id3&ids=id4&ids=id5
This is how rack does it. This is how php does it. This is how node does it as well...
There seems to be a few ways to achieve this. I'd like to offer how I solve it:
GET /users/<id>[,id,...]
It does have limitation on the amount of ids that can be specified because of URI-length limits - which I find a good thing as to avoid abuse of the endpoint.
I prefer to use path parameters for IDs and keep querystring params dedicated to filters. It maintains RESTful-ness by ensuring the document responding at the URI can still be considered a resource and could still be cached (although there are some hoops to jump to cache it effectively).
I'm interested in comments in my hunt for the ideal solution to this form :)
You can build a Rest API or a restful project using ASP.NET MVC and return data as a JSON.
An example controller function would be:
public JsonpResult GetUsers(string userIds)
{
var values = JsonConvert.DeserializeObject<List<int>>(userIds);
var users = _userRepository.GetAllUsersByIds(userIds);
var collection = users.Select(user => new { id = user.Id, fullname = user.FirstName +" "+ user.LastName });
var result = new { users = collection };
return this.Jsonp(result);
}
public IQueryable<User> GetAllUsersByIds(List<int> ids)
{
return _db.Users.Where(c=> ids.Contains(c.Id));
}
Then you just call the GetUsers function via a regular AJAX function supplying the array of Ids(in this case I am using jQuery stringify to send the array as string and dematerialize it back in the controller but you can just send the array of ints and receive it as an array of int's in the controller). I've build an entire Restful API using ASP.NET MVC that returns the data as cross domain json and that can be used from any app. That of course if you can use ASP.NET MVC.
function GetUsers()
{
var link = '<%= ResolveUrl("~")%>users?callback=?';
var userIds = [];
$('#multiselect :selected').each(function (i, selected) {
userIds[i] = $(selected).val();
});
$.ajax({
url: link,
traditional: true,
data: { 'userIds': JSON.stringify(userIds) },
dataType: "jsonp",
jsonpCallback: "refreshUsers"
});
}