I'm hoping someone can help me out. I need to get the root web of the current site from the SPContext. It's easily done with the following
SPContext.Current.Site.RootWeb
I'm comfortable with the idea that the SPSite object here at SPContext.Current.Site.RootWeb shouldn't be disposed of, but what about the SPWeb object I'm getting from the SPSite. Will, when the SPSite get's disposed, the rootweb SPWeb get disposed to? Or do I need to dispose of it myself?
Calls to SPSite.RootWeb should not be disposed. Disposing the SPSite will also dispose the RootWeb.
There is a bug in SPDisposeCheck where it flags if you do dispose it, and if you don't (damned either way!) I detailed how I solved this in this blog post, as you can't use an SPDisposeCheckIgnore attribute in elevated privileges blocks.
No you should not. You should only dispose objects you are in control of. Because the context is something created by SharePoint you do not dispose of this as other objects may be dependent upon this.
If you were to create your own instance of an SPWeb from this objects properties than it would need to be disposed. I.e..
using (SPSite site = new SPSite(SPContext.Current.Site.RootWeb.Url))
using (SPWeb web = site.OpenWeb()) {
// do something
}
Here is an article on the best practices of disposing SharePoint objects.
http://msdn.microsoft.com/en-us/library/aa973248(v=office.12).aspx
You should normally use SPSite and SPWeb in a using clause.
using (SPSite site = new SPSite("http://mysite.sharepoint.com"))
{
using (SPWeb web = site.OpenWeb())
{
// TODO: code for using SPWeb object
}
}
This automatically will correctly release the SPWeb object after you are done with it.
Related
what is the difference spweb and spcontext when we need to use webcontext
Plese anyone can answer me.
spweb web =spcontext.current.web;
and
using(spsite site= new spsite(""))
{
using(spweb web=site.openweb(""))
{
}
}
In it's simplistic terms
using(spsite site= new spsite(""))
{
using(spweb web=site.openweb(""))
{
}
}
The above is pretty much the same as
spweb web =spcontext.current.web;
However the top code snippet you need to justify a URL to get your site object and by using the
using(){
}
You are automatically disposing of the objects site and web object.
The
spweb web =spcontext.current.web;
Get the context of the current web that the code is running in. It is essential that you do NOT dispose of this object.
It all depends if your code is running in the context of the site that you need a web or site object of.
this is my code:
SPWeb oWeb = SPContext.Current.Web;
SPUserToken token = oWeb.AllUsers[#"SHAREPOINTSYSTEM"].UserToken;
using (SPSite elevatedSite = new SPSite(oWeb.Site.ID, token))
{
using (SPWeb elevatedweb = site.OpenWeb())
{
}
}
i run this success. But i see in ULS log of sharepoint, have exceptions as: "Don't dispose object web". I think when i use "using" for proccess, SPSite and SPWeb auto release memory.
Please help me in this problem
According to SPDisposeCheck rule 120, SPSite.OpenWeb should be disposed, so I don't think your error is related to elevatedweb. You might want to check other areas of your code. Definitely make sure that oWeb isn't being disposed.
Use SPDisposeCheck tool to identify if you have memory leaks in this piece of code.
http://archive.msdn.microsoft.com/SPDisposeCheck
Can you please paste the ULS log entry and how you identified it's definitely related to your code?
Your code: is it
using (SPWeb elevatedweb = site.OpenWeb()) OR
using (SPWeb elevatedweb = elevatedSite.OpenWeb()) ?
Can you please paste the complete piece of code?
Why do some SharePoint examples use
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
...
}
and not just simply?
SPSite site = SPContext.Current.Web.Site;
...
Update
I think I have narrowed the question down to the following:
It seems that I should not use SPContent.Current directly, unless I am certain, that my code runs inside SharePoint. But when would that not be true?
Take a look at the best practices documentation on disposing objects in SharePoint 2010 from Microsoft, however there are opposing views.
There are a few key takeaways for SharePoint projects:
Always dispose your SPWeb / SPSite objects --> memory leaks
Make use of SPContext.Current... when you are sure your code is running in a SharePoint context
Unit Tests mean no Sharepoint context
External utilities mean no Sharepoint context
Powershell means no SharePoint context (e.g. activating a feature with feature receiver might fail)
Do not dispose SPContext.Current... but create your own object (again using)
You might have problems with consistency with your multiple SP.. objects.
In the end SPSite site = SPContext.Current.Web.Site; is fine in some instances, but you do not have control over this site object - that might be the problem. If you go for new SPSite(...) you will always have your SPSite and not something SharePoint created and managed for you.
Personally I almost always go for the using structure so all objects are disposed properly afterwards. Alternatively I use SPContext.Current.Web without disposing.
It depends on the context in which your code runs. For instance, you need to create a new SPSite instance if you are running within a RunWithElevatedPrivileges block.
Dennis G is correct. Disposing the SPSite/SPWeb/etc is important but make sure you do not dispose the objects that are provided to you by the API directly. It's subtle but critical otherwise your response will never get generated or cause even thread abort situations.
In my experience, if I need quick information on the SPSite or SPWeb property that I am sure available to the user context (either a content manager authorized user or anonymous), then using SPContext.Current.* object is great. Otherwise, use the RunWithElevatedPriveleges method to wrap your code and inside that lambda has the following pattern:
SPSecurity.RunWithElevatedPrivileges(() =>
{
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
{
// stuff goes here elevated
}
}
});
I want to Change Title and No of Links in Recent Changes of Sharepoint 2010's Wiki page library.
I made one custom user control for that. It work fine but there is one problem that I am unable to pass the url of site in
using (SPSite site = new SPSite(SiteCollection))
I have to pass SiteCollection Statically. I want to make it dynamic. Mine site is a sub site. Is it possible to get Site link to open the Web..
Thanks
just use:
SPSite site = SPContext.Current.Site
the same goes for using a subsite:
SPWeb web = SPContext.Current.Web
No need for using statements if you use the context, you dont need to dispose it :)
Try using this : SPContext.Current.Web.Site.Url.
Nipesh,
You can getting all Webs using below code
SPSite rootSite = SPContext.Current.Site;
foreach (SPWeb oWeb in rootSite.AllWebs)
{
//This Using for SPSite is optional
using (SPSite site = new SPSite(oWeb.Url))
{
//This Using for SPWeb is optional
using (SPWeb web = site.OpenWeb())
{
//You can get all web in this object & perform operation
}
}
oWeb.Dispose();
}
Above both Using for SPSite & SPWeb are optional you can direct access SPWeb object from oWeb object.
Happy Coding...!!!
I am trying to write a console app that simply lists the number of lists at the sharepoint root.
I tried doing it by using the following code, but the object SPContext.Current is null. Any ideas of how to get the web object?
SPWeb web = SPContext.Current.Site.OpenWeb("http://localhost") ;
Just adding a little thing to Nat's post:
Even if it's not a important as in a SharePoint WebApp, it's still recommenced to dispose all SPWeb and SPSite objets.
So do keep good habits:
using (SPSite site = new SPSite(weburl))
{
using (SPWeb web = site.OpenWeb())
{
// bla bla
}
}
Note: you can directly pass the weburl to SPSite constructor, so OpenWeb will open the given web.
SPSite spSite = new SPSite("http://myurl");
SPWeb spMySite = spSite.Allwebs["mysite"];
SPWeb spRootsite = spsite.RootWeb;
The console app will only run on the server as usual.
Also, the url used http://myurl can be a url to a page and an SPSite object will be created. E.g. http://myurl/mysite/pages/default.aspx will get a valid SPSite object.
There are a couple of other ways you can use SPSite.OpenWeb() as well...
If you keep track of the SPWeb object's GUID:
site.OpenWeb(webUid);
Using a web's server or site relative URL or title, see MSDN SPSite.OpenWeb(string) for more details:
site.OpenWeb(relativeUrl);
site.OpenWeb(title);
Using the precise relative URL and avoiding any clever stuff that SPSite.OpenWeb(string) uses:
site.OpenWeb(relativeUrl, true);