Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

We have a custom WCF based service for automating some common tasks within our SharePoint 2007 environment. There is an issue with a piece of code that modifies the title of a SharePoint web. The code is very simple and works fine from a console app:

public void ChangeTitle(SPWeb web, string title)
{
    web.Title = title;
    web.Description = “Description for “ + title;
    web.Update();
}

When the diagnostic logging for the SharePoint farm has the trace log settings set to “verbose”, the call to the web.Update() method throws a NullReferenceException.

Using .NET Reflector, I have tracked this down to the SPUtility.StackTraceString() method, which is only called if the trace logging is set to verbose. This method builds up a call stack string which is then written to the ULS logs. It only succeeds in building some of the string as it seems to expect more method calls in the stack than there actually are. Once it gets to the method exposed as the WCF operation, there are no methods left in the stack and so the null reference exception is thrown.

The stack trace of the error finishes as follows...

System.NullReferenceException was caught Message="Object reference not set to an instance of an object." Source="Microsoft.SharePoint" StackTrace: at Microsoft.SharePoint.Utilities.SPUtility.StackTraceString(Int32 numLevelsToSkip) at Microsoft.SharePoint.SPWeb.TraceWebOperation(String operation, Boolean recordStack) at Microsoft.SharePoint.SPWeb.Update() ...

The StackTraceString method that throws the exception looks like this:

enter image description here

The exception is thrown when trying to access "DeclaringType" after a few iterations (once the WCF boundary has been reached).

The error disappears when trace logging is set to something other than verbose as the code that throws the exception is contained within an "if(verbose){}" style block within the SPWeb.TraceWebOperation() call.

Aside from never setting verbose tracing (as we won't be able to control this in production), is there something else that we can try to get this to work?

share|improve this question
    
So does it set the title correctly when logging isn't set to Verbose? –  James Love May 3 '11 at 13:00
    
Yes, the code works fine if tracing is set to anything but verbose. –  SHug May 3 '11 at 13:20
    
Could you post the code for how you are getting the SPWeb object, as this bug is particular to the way that SPWeb is created/retrieved. –  Tim Ebenezer May 4 '11 at 12:47

2 Answers 2

up vote 2 down vote accepted

Ok, firstly, this is a bug in the implementation of SPUtility.StackTraceString; since StackFrame::GetMethod() CAN return null, but this is not checked.

The solution, therefore is either to ensure that in the instantiation of the StackFrame collection there are no null methods created. Essentially this means that somewhere in the call stack for this thread there has been a method with a null handle. If you can pinpoint that and possibly eliminate it - that would be the best. However, this may have something to do with the fact that it is being called inside a WCF service; which is introducing a stack frame with a null method pointer in it.

Sorry this can't be of more help, but if you could turn verbose logging off programmatically before the call to update, and then reset the state after, that might be the best solution.

share|improve this answer
    
OK, I took the code from StackTraceString(), inserted it in my code and did some debugging. It turns out that the prior to my WCF operation being called, System.ServiceModel.Dispatcher.SyncMethodInvoker calls another method "SyncInvokeRenameSite" (RenameSite is my operation name), which does not appear to have a DeclaringType associated with it. It's this method that breaks the call stack and causes the exception. –  SHug May 4 '11 at 15:22
    
Ok, since it's trying to call a member method on it there's little we can do (unless we could programmatically alter the StackFrame, which seems dangerous - and probably is unsupported). –  Tim Ebenezer May 4 '11 at 15:27
    
I'll probably go with altering the logging, or at least checking that the logging is not verbose before starting my code. Thanks –  SHug May 4 '11 at 15:39

Have you tried setting AllowUnsafeUpdates to True at the beginning of your method and then to False after the Update?

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsite.allowunsafeupdates.aspx

share|improve this answer
    
I'm afraid this has made no difference. I'll update the question with some more info –  SHug May 4 '11 at 9:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.