4

SPDisposeCheck 实用程序提醒我有一个未正确处理的SPWeb.Add调用。正如您在下面看到的,典型的using(SPWeb NewWeb = webs.add(siteUrl ....)方法将不起作用,因为RunWithElevatedPrivileges会使return newWeb脱离上下文。

通过查看下面的newWeb = webs.Add()行,任何人都可以建议一种正确处理新 SPWeb 对象的方法吗?提前致谢。

public partial class SiteHelper                         
{                               
    public static SPWeb CreateSiteFromSTP(SPWeb parentWeb, string newSiteSTP, int teamId)   
    {                               
        try                     
        {                       
            SPWeb newWeb = null;        
            SPSecurity.RunWithElevatedPrivileges(delegate()    
            {                   
                string siteUrl = teamId.ToString();         
                SPWebCollection webs = parentWeb.Webs;      
                newWeb = webs.Add(siteUrl,.,.,.,);
                TraceProvider.WriteLine("Activating Feature : MembersFeature ");        
                newWeb.Features.Add(new Guid(TeamSiteAttributes.MembersFeature), true);     
                TraceProvider.WriteLine("Activating Feature : BadgeAwardsFeature ");        
                newWeb.Features.Add(new Guid(TeamSiteAttributes.BadgeAwardsFeature), true);     
                TraceProvider.WriteLine("Activating Feature : ProjectBenefitsFeature ");    
                newWeb.Features.Add(new Guid(TeamSiteAttributes.ProjectBenefitsFeature), true);     
                TraceProvider.WriteLine("Activating Feature : TeamScoreFeature ");          
                newWeb.Features.Add(new Guid(TeamSiteAttributes.TeamScoreFeature), true);   
                newWeb.Update();            
                parentWeb.Update();             
            });                     
            return newWeb;              
        }   
        catch (Exception ex)        
        {                       
            TraceProvider.WriteLine("Error", ex);           
            throw;
        }
    }   
} 
4

3 回答 3

6

SPDisposeCheck 将此报告为错误,因为一旦您从该方法返回它,它就不够聪明,无法知道您在用 newWeb 做什么。只要在调用 CreateSiteFromSTP() 之后处理 newWeb,就不会发生内存泄漏。

如果您确信在此方法中没有内存泄漏,您可以设置 SPDisposeCheck 以忽略此特定警告。只需在您的 CreateSiteFromSTP 方法上方添加以下声明(使用您收到的正确 SPDisposeCheckID 编号):

[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_110, "Caller will dispose")]
于 2009-06-18T15:55:02.300 回答
1

处理你的新的正确方法SPWeb是在它被创建的范围内。如果你需要在你的新网站上执行额外的操作,只需传入一个委托来调用:

public static void CreateSiteFromSTP(SPWeb parentWeb, string newSiteSTP, int teamId, Action<SPWeb> actionOnCreate)       
{                                                           
    // ...
    using(var newWeb = webs.Add(...))
    {
        // ...
        newWeb.Update();
        actionOnCreate(newWeb);
    }
}

然后你可以传入一个方法(匿名或命名)来操纵你的 new SPWeb,而无需负责传递处置。这种方法还有一个好处,就是不需要您返回SPWeb高架块的外部,这是不受支持且不可靠的。

事实上,我会惊讶地发现您的代码实际上按您的意图工作:现有的 SharePoint 对象(特别是parentWeb)在创建时设置了它们的权限,也不应该传递到提升的上下文中。在 SharePoint 中提升权限的更好方法是使用 SPSite 模拟。使用此处RunAsSystem定义的方法,我将重构您的代码,如下所示:

public static void ElevateToCreateSiteFromSTP(SPWeb parentWeb, string newSiteSTP, int teamId, Action<SPWeb> actionOnCreate)
{
    parentWeb.RunAsSystem(elevWeb =>
        CreateSiteFromSTP(elevWeb, newSiteSTP, teamId, actionOnCreate));
}

private static void CreateSiteFromSTP(SPWeb parentWeb, string newSiteSTP, int teamId, Action<SPWeb> actionOnCreate)
{                                                           
    try                                     
    {
        string siteUrl = teamId.ToString();             
        SPWebCollection webs = parentWeb.Webs;          
        using(var newWeb = webs.Add(siteUrl, ...))
        {
            var newWebFeatures = newWeb.Features;

            TraceProvider.WriteLine("Activating Feature : MembersFeature ");           
            newWebFeatures.Add(new Guid(TeamSiteAttributes.MembersFeature), true);         
            TraceProvider.WriteLine("Activating Feature : BadgeAwardsFeature ");            
            newWebFeatures.Add(new Guid(TeamSiteAttributes.BadgeAwardsFeature), true);     
            TraceProvider.WriteLine("Activating Feature : ProjectBenefitsFeature ");        
            newWebFeatures.Add(new Guid(TeamSiteAttributes.ProjectBenefitsFeature), true);
            TraceProvider.WriteLine("Activating Feature : TeamScoreFeature ");              
            newWebFeatures.Add(new Guid(TeamSiteAttributes.TeamScoreFeature), true);       

            newWeb.Update();                        
            parentWeb.Update();                     

            if(actionOnCreate != null)
                actionOnCreate(newWeb);
        }
    }       
    catch (Exception ex)
    {                                               
            TraceProvider.WriteLine("Error", ex);                   
            throw;
    }
}

这具有将您的高程问题与创建SPWeb. 我也更愿意让我的代码在不同权限下运行的位置非常明显。

于 2009-08-24T13:14:27.827 回答
1

在这种情况下,这主要是安全清理的最佳实践问题......这种方法返回 GUID 或新 SPWeb 的 url 而不是创建的实际 SPWeb 会更好吗?这样,此方法可以正确处理它创建的 SPWeb,调用者仍然有机会轻松创建另一个生命周期不那么神秘的 SPWeb。与传递一个并可能忽略适当清理的风险相比,创建一个 SPWeb 的实际成本是多少?

于 2009-06-18T19:06:48.707 回答