使用Sharepoint 2013 REST Api / CSOM检索发布图像字段

10
我们正在使用Sharepoint 2013 REST API从Sharepoint获取所有新闻项目。我们创建了一个自定义ContentType 'Newsitem',其中包括多个属性,包括发布图片字段。
  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";

使用标准的Uri进行REST调用,我检索到了所有属性,但没有 TeaserImg。 显式地选择 TeaserImg 当然会导致调用失败。

为什么我找不到 TeaserImg,在Sharepoint 2013 REST Api 中这不可能吗?我应该使用CSOM吗?


有没有人想过一种方法来添加一个计算字段,用于计算发布图像的字符串URL?然后将该计算字段暴露给REST API? - jmbmage
4个回答

14

似乎无法通过列表项集合端点检索Publishing Image字段。

有一个解决方法,可以通过SharePoint REST端点使用ListItem.FieldValuesAsHtml属性来检索发布字段,如下所示:

限制:需要执行两个请求。

如何使用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);
}

用法

以下示例演示如何检索页面字段,包括发布字段,例如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));
}

在这里最好的解决方案可能是利用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']);
    }
}

1
我认为这是最接近的答案。很遗憾在Sharepoint REST Api中存在这些限制。 - Gigi2m02
事实上,微软为什么决定不通过REST接口公开某些发布字段仍然不清楚,至少它们可以作为延迟公开。 - Vadim Gremyachev
2
我们现在改变了计划,并在Sharepoint服务器上包含了自己的WCF REST服务来读取服务器端数据。我们喜欢它的简洁... - Gigi2m02
1
有没有使用搜索 API 获取它的方法? - Vignesh Subramanian
我不确定这是否是一个新功能,但你可以扩展FieldValuesAsHtml,这样你就可以做..$select=foo,bar,FieldValuesAsHtml/MyField&$expand=FieldValuesAsHtml - Nils

6
很遗憾,根据这篇文章,发布图像字段不能通过REST技术进行返回。
但是,使用高级REST客户端,我发现您可以通过两个请求来检索发布图像字段的HTML。第一个请求获取您尝试获取发布图像的列表项,第二个请求通过返回结果的FieldValuesAsHtml属性获取发布图像的HTML。
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;
};

虽然不是最理想的方法,但至少有了HTML标签,您可以使用jQuery或其他方法从HTML元素中提取图像URI。或者,您可以将该元素直接插入DOM中。
希望这能帮到您!

这是一个不错的解决方案,但我认为对于10个新闻项目列表进行11次调用有点奇怪。希望我能找到一种可以“懒加载”的解决方案。 - Gigi2m02
我同意,并且使用它感觉很不舒服。这就是为什么我正在研究使用内容搜索 Web 部件/显示模板。如果它运行良好,我可能会发布另一个答案。 - scullytr

0
我找到了一种通过单个调用获取所有数据的方法:使用RenderListDataAsStream POST REST调用
this._webAbsoluteUrl +
"/_api/web/GetList(@listUrl)/RenderListDataAsStream?
@listUrl=%27%2Fsites%2F<scName>%2Flists%2F<listUrlName>%27";

它提供了所有简单文本字段数据,可用于更复杂的字段,如托管元数据和查找字段,但在这种情况下更重要的是,它为发布图像列使用的图像提供了URL。

您需要从此结构中解析它:

"<div dir="" class="ms-rtestate-field"><img alt="" src="/sites/<scName>/SiteAssets/<myImageOnSharepoint>.jpg" style="BORDER&#58;0px solid;" /></div>"

代码示例(使用TypeScript的SPFx):

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
  });

0
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;
  });
}

1
有任何细节吗? - Irf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接