Вопрос

In the code below, within using directive, for rootweb, Dispose(); method will be called implicitly, is that correct? Or should I need a using directive for this: SPWeb rootweb = site.RootWeb since I am not using new keyword?

The reason I am asking because SPDisposeCheck gives following comments:

Dispose should not be called on this object.

Initial Assignment: rootweb := site.

{Microsoft.SharePoint.SPSite}get_RootWeb()

public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            var site = properties.Feature.Parent as SPSite;
            if (site != null)
            {
                
                AddTaxonomyField(site);
            }
        }

private void AddTaxonomyField(SPSite site)
{
    SPContextManager.Current.LogManager.LogInformationToDevelopers(String.Format("Adding {0} to {1}.", CorCatColumn, site.Url));
    try
    {
        using (SPWeb rootweb = site.RootWeb) // At this line
        {
            if (!rootweb.Fields.ContainsField(CorCatColumn))
            {
                TaxonomySession session = new TaxonomySession(site);
                TermStore ts = session.DefaultSiteCollectionTermStore;
                if (session.TermStores.Count != 0)
                {
                   string taxonomyField = "SomeField";
                   string noteField = "SomeField";
                   rootweb.Fields.AddFieldAsXml(noteField);
                   rootweb.Update();
                   rootweb.Fields.AddFieldAsXml(taxonomyField);
                   rootweb.Update();
                }
            }
        }
    }
    catch (Exception ex)
    {
        SPContextManager.Current.LogManager.LogErrorToDevelopers(ex);
    }
}
Это было полезно?

Решение

Do not explicitly (or via using) call Dispose() on the SPSite.RootWeb property. The dispose cleanup will be handled automatically by the SharePoint and the .NET framework.

For existing SharePoint customizations removal of explicit RootWeb Dispose is recommended to avoid an edge case condition where the SPContext.Current.Web has equality to the SPSite.RootWeb.

Problems can occur when disposing RootWeb when obtained from any variation of SPContext (e.g., SPContext.Site.RootWeb, SPContext.Current.Site.RootWeb and GetContextSite(Context).RootWeb). Note the owning SPSite object must be properly disposed (or not disposed in the case of SPContext).

So in you case, just do like this:

private void AddTaxonomyField(SPSite site)
{
    SPContextManager.Current.LogManager.LogInformationToDevelopers(String.Format("Adding {0} to {1}.", CorCatColumn, site.Url));
    try
    {
        SPWeb rootweb = site.RootWeb
        //...

But make sure you dispose the SPSite you pass into the AddTaxonomyField in the function that calls AddTaxonomyField UNLESS you take it from SPContext. As you get it from properties.Feature.Parent, you should not Dispose it, so I'd just do the above mentioned change.

Source and Source

Другие советы

The code is wrong. You need to use using directive only with objects that you created yourself. The code would be correct in this case:

private void AddTaxonomyField(SPSite site)
{
    using (SPWeb web = site.OpenWeb()) //need "using" because you opened the SPWeb yourself
    {

    }
}

This code would dispose of the web object at the end of using statement. This would be correct as well:

private void AddTaxonomyField(SPSite site)
{
    var rootWeb = site.RootWeb; // no need for "using" since the object is managed by SPSite.
}

In your example, you haven't opened a new web but instead you used SPSite.RootWeb object (and SPSite will take care of that for you). Since the SPSite.RootWeb wasn't opened (or created in simple terms) by you - therefor there is no need to use using or call .Dispose().

I believe this is your third similar question in a row :) Just note the following guidelines and it might help:

  1. using = automatic dispose;
  2. You don't dispose of something you don't own (create);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top