Sharepoint SPDisposeCheck - PullRequest
       17

Sharepoint SPDisposeCheck

4 голосов
/ 18 июня 2009

Утилита SPDisposeCheck оповестила меня о некорректно настроенном вызове SPWeb.Add . Как вы можете видеть ниже, типичный с использованием (SPWeb NewWeb = webs.add (siteUrl ....) метод не будет работать, поскольку RunWithElevatedPrivileges приведет к возврату 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;
        }
    }   
} 

Ответы [ 3 ]

6 голосов
/ 18 июня 2009

SPDisposeCheck сообщает об этом как об ошибке, потому что он недостаточно умен, чтобы знать, что вы делаете с newWeb, как только вы вернули его этим методом. Пока вы избавляетесь от newWeb после вызова CreateSiteFromSTP (), утечки памяти не будет.

Если вы уверены, что в этом методе нет утечки памяти, вы можете настроить SPDisposeCheck на игнорирование только этого конкретного предупреждения. Просто добавьте следующую декларацию (с правильным номером SPDisposeCheckID, который вы получили) над вашим методом CreateSiteFromSTP:

[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_110, "Caller will dispose")]
1 голос
/ 24 августа 2009

Правильный способ избавиться от вашего нового SPWeb находится в области, где он был создан. Если вам необходимо выполнить дополнительные операции в новой сети, просто передайте делегата для вызова:

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

Затем вы можете просто передать метод (анонимный или именованный), который манипулирует вашим новым 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. Я также предпочитаю, чтобы было совершенно очевидно, где мой код будет работать с разными разрешениями.

1 голос
/ 18 июня 2009

Это в основном вопрос передового опыта по безопасной очистке в этом случае ... было бы лучше, чтобы этот метод возвращал GUID или URL для нового SPWeb, а не фактический SPWeb, который был создан? Таким образом, этот метод может должным образом избавиться от созданного им SPWeb, и у вызывающей стороны все равно будет возможность легко создать еще один SPWeb, срок службы которого менее загадочен. Какова реальная стоимость создания SPWeb по сравнению с риском его обойти и потенциально пренебречь надлежащей очисткой?

...