我使用以下代码来获取 Web 应用程序网站集中的所有“公告”列表。

不幸的是,有时当前用户没有该站点的权限,页面会因异常而失败,即使在 try 块内也是如此。

为所有用户安全地执行以下操作的正确方法是什么,即使是匿名用户也不会得到任何结果?

static public List<SPListMeta> AllSiteAnnouncementsLists()
{
    var returnList = new List<SPListMeta>();
    foreach (SPSite oSiteCollection in SPContext.Current.Web.Site.WebApplication.Sites)
    {
        var collWebs = oSiteCollection.AllWebs;
        try
        {
            foreach (SPWeb oWebsite in collWebs)
            {
                using (oWebsite)
                {
                    var collSiteLists = oWebsite.GetListsOfType(SPBaseType.GenericList);
                    returnList.AddRange(from SPList oList in collSiteLists where oList.Title == "Announcements" select new SPListMeta(oList));
                }
            }
        }
        catch
        {
        }

    }
    return returnList;
}

异常正在触发 foreach (SPWeb oWebsite in collWebs)

有帮助吗?

解决方案

仅检索数据
如果您只查询这些列表中的项目,请考虑以下两种循环遍历所有内容的替代方案:

如果您可以忍受爬行造成的延迟,请使用搜索来收集项目。

如果不是,并且您处于“正常”情况,即如果用户有权访问任何子网站,那么他也至少有权访问网站集根目录,那么您应该更改代码以仅获取 oSiteCollection.RootWeb 内的 oSiteCollection.RootWeb尝试/捕获然后使用 SPS站点数据查询 查询所有子站的公告列表。

其他访问如果您的用户始终有权访问他们有权访问的网站的父网站,那么您可以访问根网站,然后正如 @SPArchaeographer 提到的那样递归地使用 GetSubwebsForCurrentUser 。

如果访问是“随机”的,那么你需要这样的东西:

// Get login of user in some way
var userLogin = SPContect.CurrentWeb.CurrentUser.LoginName;

// Get ids of all site user has access to
var siteIds = new List<Guid>();
SPSecurity.RunWithElevatedPrivileges(() =>
  {
    using (var elevatedSiteCollection = new SPSite(oSiteCollection.ID))
    {
      foreach (SPWeb elevatedSite in elevatedSiteCollection.AllWebs) 
      {
        if(elevatedSite .DoesUserHavePermissions(userLogin, SPBasePermissions.Open))
        {
          siteIds.Add(elevatedSite.ID);
        }    
      }
    }
  });
foreach (var id in SiteIds)
{
  using (SPWeb oWebsite = oSiteCollection.OpenWeb(id))
  { 
    ...
  } 
}

其他提示

在“使用”网络之前检查用户是否有权访问网络, SPWeb.DoesUserHavePermissions 是你想要的方法。例子 -

if(oWebsite.DoesUserHavePermissions(SPBasePermissions.Open))
 using (oWebsite)
 {
    //code
 }

请告诉我是否有效。

从您的评论来看,您的问题似乎在线:

 var collWebs = oSiteCollection.AllWebs; 

该调用要求用户有权访问您正在枚举的 Web 实例 - 一旦您尝试访问用户无权访问的网站,该调用就会失败。尝试使用 SPWeb.DoesUserHavePermission 等解决方法也是无用的,因为即使在调用之前您也会收到访问被拒绝的异常。

您可以执行以下操作:打开一个您确定用户有权访问的网站(也许是根网站?),然后枚举该网站下的所有网站。您可以使用以下代码行来完成此操作。

SPWebCollection websForCurrentUser = theCurrentSite.OpenWeb().GetSubwebsForCurrentUser();

这里的“theCurrentSite.OpenWeb()”是对 SPSite 实例的 OpenWeb() 方法的调用,以获取您将作为搜索基础的 SPWeb - 请注意,您将需要有权访问该“基础”网站。之后,您只需调用 GetSubwebsForCurrentUser 即可。

许可以下: CC-BY-SA归因
scroll top