How do you instantiate a SPWeb Object from a console app? - sharepoint

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);

Related

what is difference between spweb and spcontext in sharepoint?

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.

SPSite site = new SPSite(SPContext.Current.Web.Url) vs SPContext.Current.Web.Site

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
}
}
});

How to get Site name dynamically

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...!!!

Should I dispose of this SPWeb?

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.

SharePoint Development Permissions

Hi I am using the SharePoint namespace to pull items from various lists throughout the site. My web part works, but only on my account. When I try it on another account it gives me "Error: Access Denied" for the page. I have taken all web parts out and have only this web part on the page. When I remove the following lines the page loads for everyone, when I add it back in however it does not work. I am guessing this is some permission problem. I was wondering is there away to programatically query different lists on SharePoint by assigning a user id to use? Thank you for any help
...
SPSite site = new SPSite(_SPSite);
SPWeb eachWeb = site.AllWebs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
...
You're correct, the access denied error is occurring when you're using an account which does not have access to the "Listings" list in the current website.
The easiest way around the issue is to use a SPSecurity.RunWithElevatedPrivleges call:
SPSecurity.RunWithElevatedPrivleges(delegate()
{
//Your code here
});
which will run whatever code is contained in the anonymous method using the SharePoint/System account, granting complete control. Be careful when using this technique though, as it equivalent to running code at full trust with a super user account. There are other caveats to be aware of as well.
Try:
SPWeb eachWeb = SPContext.Current.Site.RootWeb.Webs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
Remember that SPWeb should be used in a using block, or disposed of explicitly after use.
As regards the first caveat from EvilGoatBob, I quote:
"If you're manipulating any Object Model elements within your elevated method, you need to get a fresh SPSite reference inside this call. For example
SPSecurity.RunWithElevatedPrivileges(delegate(){
SPSite mySite = new SPSite(http://sharepoint/);
SPWeb myWeb = SPSite.OpenWeb();
// further implementation omitted
});"
Notice that the site parameter is hard-coded - this is because of a bug. If you instead had tried:
using (SPSite site = new SPSite("http://" + System.Environment.MachineName)) {}
You would get the rather generic "No SharePoint Site exists at the specified URL..." error. This caused me no end of grief. Bottom line is that you have to hard-code the server name (unless anyone has an alternative). You can also get a similar error message when debugging Web Parts for the first time with VSeWSS 1.3.
You do not need to hardcode the server name in this case because your requirement is to retrieve items from list inside the same site as your webpart. You are correct, if you do not have enough privileges with your account, then you get the Access Denied. The solution is to create a new SPSite object within a different security context, and do your work:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.OpenWeb())
{
//the web object was retrieved with elevated privileges under the system account.
//do your work here:
SPListItemCollection myItemCollection = web.Lists["Listings"].Items;
//...
}
}
}
);
With the code above, your webpart is portable because there's no hardcoding, and runs in the correct security context while disposing of all unmanaged SPRequest objects created by the SPSite and SPWeb constructors.

Resources