问题
We're using the Sharepoint 2013 REST API to get all news items from the Sharepoint. We made a custom ContentType 'Newsitem' with several properties including a Publishing Image Field.
var contentTypeId = "0x01100018B03AC7E8312648AEA00851DEDBCAF802";
var standardUri = "https://examplesite.com/blog/_api/lists/getbytitle('Messages')/items?$top=7&$filter=startswith(ContentTypeId,'" + contentTypeId + "')";
var selectiveUri = "https://examplesite.com/blog/_api/lists/getbytitle('Messages')/items?$top=7&$filter=startswith(ContentTypeId,'" + contentTypeId + "')&$Select=Title,Teaser,Body,ShowAt,TeaserImg";
Using standardUri for my REST call, I retrieve all properties but no TeaserImg. Explicitly selecting TeaserImg makes the call fail of course.
Why can't I find the TeaserImg, isn't this possible with Sharepoint 2013 REST Api and should I use CSOM instead?
回答1:
It does not seem possible to retrieve Publishing Image
fields using List Item Collection endpoint.
There is a workaround, publishing fields could be retrieved using ListItem.FieldValuesAsHtml
property via SharePoint REST endpoint as demonstrated below
Limitation: it requires to perform two requests.
How to retrieve Publishing fields using SharePoint 2013 REST
function getJson(endpointUri, success, error)
{
$.ajax({
url: endpointUri,
type: "GET",
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose"
},
success: success,
error: error
});
}
function getPublishingPage(webUrl,listName,listItemId,publishingProperties, success, failure)
{
var itemUri = webUrl + "/_api/web/lists/getbytitle('" + listName + "')/items(" + listItemId + ")";
getJson(itemUri,
function(data){
var pageItem = data.d;
var selectProperties = [];
for(var idx in publishingProperties){
if(!pageItem.hasOwnProperty(publishingProperties[idx])){
selectProperties.push(publishingProperties[idx]);
}
}
if(selectProperties.length > 0) {
//construct an additional query
var query = '/FieldValuesAsHtml?$select=' + selectProperties.join(',');
var endpointUri = pageItem['__metadata'].uri + query;
getJson(endpointUri,
function(data){
for(var property in data.d){
if(property == "__metadata") continue;
pageItem[property] = data.d[property];
}
success(pageItem);
},
failure);
}
else {
success(pageItem);
}
},
failure);
}
Usage
The following example demonstrates how to retrieve page fields including publishing fields, such as PublishingRollupImage
:
getPublishingPage(_spPageContextInfo.webAbsoluteUrl,'Pages',3,['PublishingRollupImage','PublishingPageImage'],printPageDetails,logError);
function printPageDetails(pageItem)
{
console.log('Page Content: ' + pageItem.PublishingPageContent);
console.log('Page Title: ' + pageItem.Title);
console.log('Page Rollup Image ' + pageItem.PublishingRollupImage);
}
function logError(error){
console.log(JSON.stringify(error));
}
Probably the best solution here would be to utilize CSOM
function getListItems(listTitle,success,error)
{
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(listTitle);
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
ctx.load(items);
ctx.executeQueryAsync(function() {
success(items);
},error);
}
getListItems('Pages',printPageItemsDetails,logError);
function printPageItemsDetails(pageItems)
{
for(var i = 0; i < pageItems.get_count();i++) {
var pageItem = pageItems.getItemAtIndex(i);
console.log(pageItem.get_fieldValues()['PublishingPageContent']);
console.log(pageItem.get_fieldValues()['PublishingRollupImage']);
}
}
回答2:
Unfortunately, the Publishing Image field is not technically returnable via REST (at least, according to this article).
However I found (using the Advanced REST client) that you can actually retrieve the html for the Publishing Image field by making two requests. One to retrieve the list item for which you are attempting to get the Publishing Image, and another to retrieve the Publishing Image html via the FieldValuesAsHtml
property of the returned results.
getPublishingImage(listname, id){
var publishingImage = '';
$.ajax({
url: _spPageContextInfowebroot.webAbsoluteUrl + '/_api/web/lists/getbytitle(\'' + listname + '\')/items(' + id + ')',
method: 'GET',
headers: {
Accept: 'application/json; odata=verbose'
},
success: function(data, request){
// List item retrieved. Fetch the Publishing Image.
var publishingImageUri = data.d.0.FieldValuesAsHtml.__deferred.uri;
// Query SharePoint
$.ajax({
url: publishingImageUri,
method: 'GET',
headers: {
Accept: 'application/json; odata=verbose'
},
success: function(data, request){
publishingImage = data.d.Image;
}
});
}
});
// Return the Publishing Image html
return publishingImage;
};
While not ideal, at least with the html you can use jQuery or another method to extract the image uri from the html element. Or you can simply insert the element as is into the DOM.
Hope this helps!
回答3:
function LoadArticle(item) {
return GetPublishingPageImage(item, ["DCCAIContentImage"]).then(function(
pub
) {
for (var property in pub.d) {
if (property == "__metadata") continue;
item.DCCAIContentImage(pub.d[property]);
}
});
}
function GetPublishingPageImage(curItem, publishingProperties) {
var query = "/FieldValuesAsHtml?$select=" + publishingProperties;
//debugger;
var endpointUri = curItem["__metadata"].uri + query;
// var endpointUri = curItem.__metadata().uri + query;
return $.ajax({
url: endpointUri,
type: "GET",
processData: false,
contentType: "application/json;odata=verbose",
headers: {
Accept: "application/json;odata=verbose"
}
}).then(function(response) {
return response;
});
}
回答4:
I found a way to get all data in a single call: use the RenderListDataAsStream POST REST call:
this._webAbsoluteUrl +
"/_api/web/GetList(@listUrl)/RenderListDataAsStream?
@listUrl=%27%2Fsites%2F<scName>%2Flists%2F<listUrlName>%27";
It gives all simple text field data, can be used for more complex fields such as managed metadata & lookup fields, but more importantly in this case, it gives you the url of the image that was used for the Publishing Image column.
You do need to parse it from this structure:
"<div dir="" class="ms-rtestate-field"><img alt="" src="/sites/<scName>/SiteAssets/<myImageOnSharepoint>.jpg" style="BORDER:0px solid;" /></div>"
Code sample (SPFx with TypeScript):
const requestHeaders: Headers = new Headers();
requestHeaders.append("Content-type", "application/json");
requestHeaders.append("Accept", "application/json");
var body =
{ parameters:
{
DatesInUtc: "true"
}
};
const httpClientOptions: IHttpClientOptions = {
body: JSON.stringify(body),
headers: requestHeaders
};
const queryUrlGetAllItems: string =
this._webAbsoluteUrl +
`/_api/web/GetList(@listUrl)/RenderListDataAsStream?@listUrl=%27%2Fsites%2F<scName>%2Flists%2F<listUrlName>%27`;
return this._webPartContext.spHttpClient
.post(queryUrlGetAllItems, SPHttpClient.configurations.v1, httpClientOptions)
.then((response: any) => {
if (response.status >= 200 && response.status < 300) {
return response.json();
} else {
return Promise.reject(new Error(JSON.stringify(response)));
}
})
.then((data: any) => {
if (data) {
for (let i = 0; i < data.Row.length; i++) {
let item = data.Row[i];
// ... process data
}
}
// ... return value
});
来源:https://stackoverflow.com/questions/25852997/retrieve-publishing-image-field-with-sharepoint-2013-rest-api-csom