我们要求用户无法访问的Sharepoint列表的项目必须仍然对前端的用户可见,并且选项为" Request Access"如有必要。为此,我们有一个Web服务,它首先从列表中提取所有项目,然后仅提取用户有权访问的项目。
// Get all the items in list
SPUser superUser = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
SPUserToken superToken = superUser.UserToken;
SPList superList;
using (SPSite site = new SPSite(SPContext.Current.Web.Url, superToken))
{
using (SPWeb elevatedWeb = site.OpenWeb())
{
superList = elevatedWeb.Lists.TryGetList(listname);
}
}
SPListItemCollection superListItems = superList.GetItems(camlQuery);
// Get items in list accessible to current user
SPUser regularUser = SPContext.Current.Web.CurrentUser;
SPUserToken regularToken = regularUser.UserToken;
SPList regularList;
using (SPSite site = new SPSite(SPContext.Current.Web.Url, regularToken))
{
using (SPWeb regularWeb = site.OpenWeb())
{
regularList = regularWeb.Lists.TryGetList(listname);
}
}
SPListItemCollection regularListItems = regularList.GetItems(camlQuery);
接下来,需要计算两个list-item-collections之间的差异。如果可能的话,这应该足够简单:
// Now make a list of the items that the current user DOES NOT HAVE ACCESS TO
SPListItemCollection noAccessListItems;
foreach (SPListItem superListItem in superListItems)
{
if(!regularListItems.Contains(superListItem)) // Fails here
{
noAccessListItems.Add(superListItem);
}
}
唯一的问题是SPListItemCollection
不支持.Contains()
方法。
获取两个list-item-collection对象差异的最佳方法是什么?
答案 0 :(得分:1)
您可以使用Cast来使用所有IEnumerable LINQ方法,例如Contains()。 使用try-catch这不是太漂亮的解决方案,imho。 你可以用一个简单的行来完成:
var noAccessListItems = regularListItems.Cast<SPListItem>().Where(x => !superListItems.Cast<SPListItem>().Select(y => y.ID).Contains(x.ID));
或者像这样:
var noAccessListItems = regularListItems.Cast<SPListItem>().Except(superListItems.Cast<SPListItem>());
但在这种情况下,您必须为SPListItem定义比较器。
<强> UPDATE1:强>
要定义比较器,您需要从IEqualityComparer继承的实现类,如下所示:
class SPListItemEqualityComparer : IEqualityComparer<SPListItem>
{
public bool Equals(SPListItem i1, SPListItem i2)
{
return i1.ID == i2.ID;
}
public int GetHashCode(SPListItem item)
{
int hCode = item.ID;
return hCode.GetHashCode();
}
}
然后,您需要在Except
方法中添加此类的实例作为第二个参数:
var noAccessListItems = superListItems.Except(regularListItems, new SPListItemEqualityComparer());
答案 1 :(得分:0)
好。搞定了。这有效:
// Now make a list of the items that the current user DOES NOT HAVE ACCESS TO
SPListItemCollection noAccessListItems;
foreach (SPListItem superListItem in superListItems)
{
try
{
regularListItems.GetItemById(superListItem.ID);
}
catch(ArgumentException ae)
{
noAccessListItems.Add(superListItem);
}
}