Sharepoint SPDisposeCheck

Sharepoint SPDisposeCheck,sharepoint,dispose,Sharepoint,Dispose,SPDisposeCheck实用程序提醒我有一个SPWeb.Add调用。正如您在下面所看到的,典型的使用(SPWeb NewWeb=webs.add(siteUrl…)方法将不起作用,因为运行WithLevelatedPrivileges将使返回NewWeb脱离上下文 通过查看下面的newWeb=webs.Add()行,有人能建议一种正确处理新SPWeb对象的方法吗?提前感谢 public partial class SiteHelper {

SPDisposeCheck实用程序提醒我有一个SPWeb.Add调用。正如您在下面所看到的,典型的使用(SPWeb NewWeb=webs.add(siteUrl…)方法将不起作用,因为运行WithLevelatedPrivileges将使返回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;
        }
    }   
} 

SPDisposeCheck将此报告为错误,因为从该方法返回newWeb后,它不够聪明,无法知道您正在对其执行什么操作。只要在调用CreateSiteFromSTP()后处置newWeb,就不会发生内存泄漏

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

[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_110, "Caller will dispose")]

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

处理新的
SPWeb
的正确方法在创建它的范围内。如果您需要在新web上执行其他操作,只需传递一个要呼叫的代表:

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

这还有一个额外的好处,就是将您的提升关注点与创建
SPWeb
的逻辑分离。我还更喜欢让我的代码在不同权限下运行的位置变得非常明显。

+1-如果您返回SPWeb对象,则由函数调用方正确处理它。SPDisposeChe的源代码ckIgnore位于SPDisposeCheck工具附带的SPDISPOSEExampleSource.zip文件中。此外,如果您将SPDisposeCheckIgnore复制到自己的程序集中,则必须保留命名空间。SPDisposeCheck.exe将检查类型为.FullName=“SPDisposeCheck.SPDisposeCheckIgnoreAttribute”的属性请阅读关于如何利用SPDisposeCheckIgnore属性的文章。它归结为添加SPDisposeCheckIgnoreAttribute.cs类,该类位于SPDisposeCheck文件夹(默认情况下为C:\Program Files(x86)\Microsoft\SharePoint Dispose Check)中的SpdisposeExampleSource.zip中。我认为最好还是返回GUID,因为您正在从RunWithElevatedPrivileges作用域泄漏SPWeb,这令人困惑,因为不清楚返回的SPWeb是否具有提升的上下文。
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;
    }
}