Warning: I'm an asp.net developer taking my first steps in SharePoint.
So, i'm writing a console application that connects to a SharePoint Server 2007 site on the same machine, but it seems that something goes wrong during the call to SPSite() constructor. Here's the simplified code:
using (SPSite siteCollection = new SPSite("http://server/AwesomeSite"))
{
//when i set a breakpoint on this line and inspect the siteCollection object,
//most of it's properties (for example siteCollection.AllWebs.Names) throw an
//exception, which leads me to the conclusion that something went wrong during
//the constructor above.
SPWebCollection site = siteCollection.AllWebs;
SPWeb web = site[""];
SPList list = web.Lists["AwesomeList"]; //exception occurs here
}
The SPException text:
Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))
I followed the advice of Sharepoint SPSite and checked that:
The user is a server farm administrator.
The user has Read and Write permissions on the content database.
The user is a site collection administrator.
The user has permissions to access the Windows SharePoint Services site or the SharePoint Server 2007 site through which the code iterates.
And they are all correct. What else could be causing this to happen?
In my experience, the SPSite() constructor is highly dependent on the Alternate Access Mappings configuration of your site. Make sure that the URL you are using in the constructor appears in the list of mappings (e.g., http vs. https, machine vs. FQDN).
You need to get more debug information.
Using Visual Studio
Try setting the debugger to break on all exceptions. Go to Debug, Exceptions and tick Common Language Runtime Exceptions. Then go to Tools, Options, Debugging and untick Enable Just My Code. Finally attach to w3wp.exe. Try running your console application now and you should find that it triggers an exception in w3wp.exe. Check the stack trace and see if that gives you more information.
Using dump files
You could also try working from a crash dump. This is admittedly significantly more hard-core but should give you the detail you are otherwise lacking. The tool ProcDump will can be attached to w3wp.exe (provided the -s switch isn't used) and will create a dump if an unhandled exception occurs. If you have trouble with ProcDump, try ADPlus which does something similar.
From the created dump file, use this KB article to set up WinDbg and get started. There is an example case of how to use WinDbg on Tess Ferrandez's blog (Strategy #2).
Have you tried to run the code with elevated privileges?
Does the IIs have some kind of funky settings regarding authentication? (Try Windows auth. only)
Unfortunately, there are hundreds of ways to generate this error. Just ask Google.
You might consider using SPTraceView to get a better description of the error. Here's a description of the tool and an example working an issue with it.
Good luck!
I have similar (not equals) problem. I've solved it with this piece of code:
using( SPSite site = ConnectToSharepointAsSystem() ) {
// now should be all ok
}
// somewhere in helper class ->
public static SPUserToken GetSystemToken(SPSite site) {
SPUserToken token = null;
bool tempCADE = site.CatchAccessDeniedException;
try {
site.CatchAccessDeniedException = false;
token = site.SystemAccount.UserToken;
}
catch (UnauthorizedAccessException) {
SPSecurity.RunWithElevatedPrivileges(() => {
using (SPSite elevSite = new SPSite(site.ID))
token = elevSite.SystemAccount.UserToken;
});
}
finally {
site.CatchAccessDeniedException = tempCADE;
}
return token;
}
public static Microsoft.SharePoint.SPSite ConnectToSharepoint() {
string urlSharepointSite;
var ret = ConnectToSharepoint(out urlSharepointSite);
return ret;
}
public static Microsoft.SharePoint.SPSite ConnectToSharepoint(out string urlSharepointSite) {
urlSharepointSite = "http://www.domain.org";
var site = new Microsoft.SharePoint.SPSite( urlSharepointSite );
return site;
}
public static Microsoft.SharePoint.SPSite ConnectToSharepointAsSystem() {
string urlSharepointSite;
Microsoft.SharePoint.SPUserToken userToken = null;
using (var tmpSite = CSharepointNastroje.PripojitNaSharepoint( out urlSharepointSite )) {
userToken = GetSystemToken(tmpSite);
}
var site = new Microsoft.SharePoint.SPSite(urlSharepointSite, userToken);
return site;
}
Related
I am using taxonomy for building left navigation in the sharepoint site.
I am using below method for accessing the nodes.
NavigationTermSet navTermSet = TaxonomyNavigation.GetTermSetForWeb(SPContext.Current.Site.RootWeb, StandardNavigationProviderNames.CurrentNavigationTaxonomyProvider, true);
but its returning only two terms and not returning all the child terms under these 2 terms.
But if i logging to the site as admin i am able to get the all the child terms as well.
I tried with console appilcation and its working fine and its problem only with Annonymous user accessing the page.
I have given the Full Access to app pool account also.
Not sure what i am missing here, any lead will be really helpful.
Regards
CR
Try to use RunWithElevatedPrivileges to run with elevated rights.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Site.ID))
{
// implementation details omitted
}
});
I trying to debug EventReceiver is not working. It use to work properly. Only thing I changed is added Intraner AAM.
http:// spfoundation/dept/it/Lists/App%20Change%20Request/AllItems.aspx
Above url is the default AAM and list url.
<Receivers ListUrl="Lists/App%20Change%20Request">
<Receiver>
<Name>AppChangeEventReceiverItemAdded</Name>
<Type>ItemAdded</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>AppChangeRequest.AppChangeEventReceiver.AppChangeEventReceiver</Class>
<SequenceNumber>10000</SequenceNumber>
</Receiver>
public class AppChangeEventReceiver : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
// base.ItemAdded(properties);
using (SPWeb web = properties.OpenWeb())
{
try
{
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Project/Task Status Details"];
......
......
web.AllowUnsafeUpdates = false;
}
catch (Exception ex)
{
throw ex;
}
}
}
In visual studio 2012, I was able to debug properly. Now I am not. Anything wrong I did here? Breakpoint not reaching even first line of it. "No symbols have been loaded..."
There are a few things you can try
1- Delete the dll of your project in GAC (C:\Windows\Microsoft.NET\assembly\GAC_MSIL)
2- Deploy project again
3- Control the dll if its the last deployed one.(control the date)
4- From the vs2012
-debug and attach to process (w3wp.exe and OWSTIMER.exe)
if this does not work, restart vs2012 and try steps again.
I hope it will help you!!
It may be a late answer but still. I killed half of a day figuring out very similar issue in my environment. It is really possible that if AAM is set up incorrectly, event receivers won't be fired (although the site is loaded and everithing works well... well, almost everything). In that case you'll probably find an error like this in the event log:
Event receiver threw an exception: System.IO.FileNotFoundException: The Web application at http://xxx.yyy.zzz/sites/aaa could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
After googling for many hours for a solution for the above Sharepoint exception, I have come to SO for help on this one...
I believe the cause of me getting the above exception is because of the following code:
try
{
using (SPSite site = new SPSite(siteId, spUserToken))
{
using (SPWeb web = site.OpenWeb(webId))
{
createNewSite(web);
}
}
}
createNewSite(web) changes the name and URL of "web" using AllowUnsafeUpdates, so when it comes out of the method it has been changed. My few months worth of Sharepoint developing experience suggest that that is the cause of the exception. "web" is no longer used anymore so I can comfortably null it myself. The problem here is... it didnt work:
try
{
using (SPSite site = new SPSite(siteId, spUserToken))
{
SPWeb web = null;
using (web = site.OpenWeb(webId))
{
createNewSite(web);
if (web != null)
{
web = null;
}
}
}
}
I believe that the original developer used the using declaration to avoid SPWeb objects from leaking. Asides that I think it is okay for me to break this pattern solely for the purpose of getting rid of that dreaded exception.
So the question: what can I do to the above code to potentially fix this exception?
Thanks.
Having a method called createNewSite that changes an existing site is a bad sign - you should post the code for that also.
There is however no need to set web to null - it doesn't have any effect as it is about to go out of scope anyway.
A more likely cause is something wrong in the custom method you are calling or an issue with the validity of the ids used.
This is a question for a WSS/SharePoint guru.
Consider this scenario: I have an ASP.Net web service which links our corporate CRM system and WSS-based intranet together. What I am trying to do is provision a new WSS site collection whenever a new client is added to the CRM system. In order to make this work, I need to programmatically add the managed path to the new site collection. I know that this is possible via the Object Model, but when I try it in my own web service, it fails. Sample code extract below:
Dim _ClientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using _RootWeb As SPSite = New SPSite("http://myintranet")
Dim _ManagedPaths As SPPrefixCollection = _RootWeb.WebApplication.Prefixes
If Not (_ManagedPaths.Contains(_ClientSiteUrl)) Then
_ManagedPaths.Add(_ClientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This code fails with a NullReferenceException on SPUtility.ValidateFormDigest(). Research suggested that this may be due to insufficient privileges, I tried running the code within an elevated privileges block using SPSecurity.RunWithElevatedPrivileges(AddressOf AddManagedPath), where AddManagedPath is a Sub procedure containing the above code sample.
This then fails with an InvalidOperationException, "Operation is not valid due to the current state of the object."
Where am I going wrong?
One workaround I have managed to do is to call out to STSADM.EXE via Process.Start(), supplying the requisite parameters, and this works.
Update: whilst developing the web service, I am running it using the built-in Visual Studio 2005 web server - what security context will this be running under? Can I change the security context by putting entries in web.config?
Update: I think the problem is definitely to do with not running the web service within the correct SharePoint security context. I decided to go with the workaround I suggested and shell out to STSADM, although to do this, the application pool identity that the web service runs under must be a member of the SharePoint administrators.
Update
I think you have proved that the issue is not with the code.
SPSecurity.RunWithElevatedPrivileges: Normally the code in the SharePoint web application executes with the privileges of the user taking the action. The RunWithElevatedPrivileges runs the code in the context of the SharePoint web application pools account (i think)
The description on MSDN could go into the details a tiny bit more.
The issue with the call may be that the web service is not actually running the code within a SharePoint process, so explaining why it cannot elevate (wild guess alert).
Have a crack at changing the user of your web services application pool and see if that gives any joy.
It is likely to be a permissions issue.
Maybe try:
Dim clientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using SPSite = new SPSite(clientSiteUrl)
webApp As SPWebApplication = SPWebApplication.Lookup(new Uri(clientSiteUrl));
If Not (webApp.Prefixes.Contains(clientSiteUrl)) Then
webApp.Prefixes.Add(clientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This is not exact code.
Since the above code is not the exact code, here is the exact working code for a Web Application scopped feature in the Feature Activated event:
On feature activation at the Mange web application features page, activate feature will create a new Explicit managed path in the specified web application (I want to replace the hard coding, maybe with Properties.Feature.Parent, or something similar.)
using (SPSite site = new SPSite("http://dev-moss07-eric/PathHere")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("PathHere"))
{
//
}
else
{
webApp.Prefixes.Add("PathHere", SPPrefixType.ExplicitInclusion);
}
}
Code can probably be improved, but its my attempt at converting the above code.
If you want to create a managed path (explicit) and a site collection at that path, do the following:
using (SPSite site = new SPSite("http://dev-moss07-eric")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("ManagedPathHere"))
{
//
}
else
{
webApp.Prefixes.Add("ManagedPathHere", SPPrefixType.ExplicitInclusion);
}
using (SPWeb web = site.OpenWeb())
{
SPWebApplication webApplication = web.Site.WebApplication;
try
{
webApplication.Sites.Add("ManagedPathHere","Site Title Here","This site is used for hosting styling assets.", 1033, "STS#1", "6scdev\\eric.schrader", "Eric Schrader", "eric.schrader#6sc.com");
}
catch (Exception ex)
{
//ex.ToString;
}
}
}
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.