5

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?

3
  • So does it set the title correctly when logging isn't set to Verbose?
    – James Love
    May 3, 2011 at 13:00
  • Yes, the code works fine if tracing is set to anything but verbose.
    – SHug
    May 3, 2011 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. May 4, 2011 at 12:47

2 Answers 2

2

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.

3
  • 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, 2011 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). May 4, 2011 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, 2011 at 15:39
2

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

1
  • I'm afraid this has made no difference. I'll update the question with some more info
    – SHug
    May 4, 2011 at 9:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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