I came across a weird problem in MOSS. The code is rather simple. Consider the following:
string login = "someuser";
using (SPSite site = new SPSite(somesiteid))
{
ServerContext serverContext = ServerContext.GetContext(site);
UserProfileManager manager = new UserProfileManager(serverContext);
if (manager.UserExists(login))
{
// do stuff
}
}
The code is executed from a web service, as this web service has the responsibility to update the properties for some user profiles. The web service is run as a user account, which is an administrator account in MOSS. The underlying application pool is run as the same account. In the web.config for the web service, impersonation is set to ‘false’. There’s no problem in calling the web service, as the above code is executed (by the web service).
When the manager is obtained, I get a COM interop exception stating that I should quote “Try again”. A really informative exception! But well – aren’t we all used to nice error messages in MOSS?!
I found some information about the error, where someone had tried the same code with elevated permissions. At first I didn’t think it would help me here, as elevated permissions runs the code as the application pool (right?)
But anyway, I tried wrapping the above code with SPSecurity.RunWithElevatedPermissions. I still don’t understand why, but now the UserProfileManager was obtained. But the next line throws and exception:
“Operation is not valid due to the current state of the object”
Stack Trace:
at Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context)
at Microsoft.SharePoint.WebControls.SPControl.GetContextWeb(HttpContext context)
at Microsoft.Office.Server.UserProfiles.UserProfileGlobal.GetCurrentUserName()
at Microsoft.Office.Server.UserProfiles.UserProfileManager.get_strCurrentAccountName()
at Microsoft.Office.Server.UserProfiles.UserProfileManager.UserExists(String strAccountName)
at Updater.Update() in c:\Projects\WebService\WebService.cs:line 73
at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)
at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
Googling the problem still suggested that something must be wrong with permissions. But I run with elevated permissions (and everything used in the rather simple code is obtained with elevated permissions). And other methods and properties of the UserProfileManager is executing without any problems.
What does work:
1. Calling the exact same code from “inside” MOSS, i.e. from a web part.
2. Calling the exact same code from a console C# application.
But the web service cannot execute the code. What I should mention here is that I tried putting all involved assemblies in the GAC to achieve full trust.
So there must be something about the permissions of the web service that are not right. But I can’t figure out which!
In the end I found a workaround for the problem. Using Lutz Roeder’s absolutely brilliant program Reflector I managed to get the code working by calling the following code prior to calling manager.UserExists:
if (HttpContext.Current != null)
{
if (HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
HttpContext.Current.Items["HttpHandlerSPWeb"] = site.RootWeb;
if (HttpContext.Current.Items["Microsoft.Office.ServerContext"] == null)
HttpContext.Current.Items["Microsoft.Office.ServerContext"] = serverContext;
}
It seems that some of the properties of HttpContext used by MOSS in static classes (i.e. ServerContext) are not initialised properly. The code makes it possible for MOSS to retrieve “current web” (SPContext.Current.Web) and “current servercontext”.
Since this is quite a hack my concerns are of course:
1. Does this hack break some security aspects?
2. Does it work under all circumstances? It shouldn’t affect environments other than those having incorrect properties in HttpConext (the null-checks take care of this), but I’m not sure if all methods/properties of UserProfileManager works.
3. The most important: Is there really not a better way to do this?!?!?! Is there something something wrong with the permission settings in my web service or similar.
Any comments are highly appreciated!
[...] ozo.dk Velkommen til Kristians blog « UserProfileManager and alternative servercontext [...]
Hi Velkommen! This i need was a helpful post. I have struggling to get my webpart working with User Profiles but it throws exception everytime UserExists webservice was being called.
Finally its been fixed because of this useful post.
Nafees
Hey,
This is an important post.I was struggling as my office server dll’s were causing lots of issues.
I realized after reading this post that it is not a dll issue, but a server context one.
Thanks a lot indeed
Sri
thank you, thank you, THANK YOU!!!!
[...] found excellent hack written by Kristian Kjær. As it turns out this problem raises when some items are missing from current HTTP context. This [...]
This is HUGE! There is very little information abo9ut this out there anywhere. I, like the rest of these poor souls, have been searching high and low for a solution to this. Thank you very very much!
Very useful post!!! Thanks!!!!
[...] Further research showed that other people have seem the same strange behaviour. Repeatedly. And the issue may be related to how the ServerContext is initialised. [...]