RunAs method for running code in specific user SPServiceContext
You may have the need to run some code in a SPServiceContext of a specific user. e.g. when dealing with user profiles or activities.
This can be achieved by using a combination of the SPUser, WindowsIdentity, GenericPrincipal and the GetContext method of SPServiceContext.
From these we can set the HttpContext.Current.User property to the specified user.
Don’t forget to set the context back after the code has executed!
Below is a helper method that makes this very easy.
I haven’t done any solid testing on performance etc. so the usual caveats apply.
// Example calling code
RunAs("http://asharepointsite", "THEDOMAIN\THEUSER", c =>
{
// The code to execute. e.g. get a the UserProfileManager as the passed in user
var upm = new UserProfileManager(c, true);
// Do some stuff to the UPM as the passed in user
});
// Helper method
private static void RunAs(string siteUrl, string userName, Action<SPServiceContext> contextToUse)
{
try
{
var currentSetting = false;
var currentHttpContext = HttpContext.Current;
SPUser currentUser = null;
if (SPContext.Current != null)
{
if (SPContext.Current.Web != null)
{
currentUser = SPContext.Current.Web.CurrentUser;
}
}
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (var site = new SPSite(siteUrl))
{
using (var web = site.OpenWeb())
{
try
{
var user = web.EnsureUser(userName);
currentSetting = web.AllowUnsafeUpdates;
web.AllowUnsafeUpdates = true;
var request = new HttpRequest("", web.Url, "");
HttpContext.Current = new HttpContext(request,
new HttpResponse(
new StringWriter(CultureInfo.CurrentCulture)));
HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
var wi = WindowsIdentity.GetCurrent();
var newfield = typeof (WindowsIdentity).GetField("m_name",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (newfield != null) newfield.SetValue(wi, user.LoginName);
if (wi != null) HttpContext.Current.User = new GenericPrincipal(wi, new string[0]);
var elevatedContext = SPServiceContext.GetContext(HttpContext.Current);
contextToUse(elevatedContext);
//Set the HTTPContext back to "normal"
HttpContext.Current = currentHttpContext;
if (currentUser != null)
{
var winId = WindowsIdentity.GetCurrent();
var oldField = typeof (WindowsIdentity).GetField("m_name",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (oldField != null) oldField.SetValue(winId, currentUser.LoginName);
if (winId != null)
HttpContext.Current.User = new GenericPrincipal(winId, new string[0]);
}
}
catch (Exception ex)
{
// Log or whatever
}
finally
{
web.AllowUnsafeUpdates = currentSetting;
}
}
}
});
}
catch (Exception exO)
{
// Log or whatever
}
}
Fun and games with the ActivityEvent
I haven’t seen a massive amount of documentation on MSDN or other posts about this, so I thought I would write a small note.
This details a way of extracting the info you see in the news feed on your ‘My Site’
First of all you need to get the the format used by the ActivityEvent, this done using ActivityType and ActivityTemplate.
ActivityType type = activityMan.ActivityTypes[activity.ActivityEventId];
ActivityTemplate template = type.ActivityTemplates[ActivityTemplatesCollection.CreateKey(false)];
string format = GetResourceString(template.TitleFormatLocStringResourceFile, template.TitleFormatLocStringName, (uint)CultureInfo.CurrentUICulture.LCID);
The format variable will now contain something along the lines of “{Pubisher} has posted a note {Link} on {PublishDate}”
Now you could at this point take the corresponding Properties in the ActivityEvent, but there is a whole load of formatting that needs to be done. The Publisher Tag needs to be turned into a link to the users profile page and display their name, etc, etc.
There is an easier way, you can use the static methods of the ActivityTemplateVariable.
ActivityTemplateVariable.DateOnlyToString(tag, variable, ContentType.Html, CultureInfo.CurrentCulture);
The problem here is that you have to pass in an ActivityTemplateVariable as one of the parameter and there is no obvious way of doing this.
There are no properties or methods in the ActivityEvent that give you an ActivityTemplateVariable or is there?
After further investigation of the TemplateVariable string property, you can see that this actually returns an XML string. This XML string is a de-serialised ActivityTemplateVariable object.
var variable = (ActivityTemplateVariable)FromXml(item.TemplateVariable, typeof(ActivityTemplateVariable));
You can now use this object to pass to the static method of ActivityTemplateVariable to return the full HTML representation of the tag.
If you then combine that with SimpleTemplateFormat you can then loop round all the tags and replace them.
var items = SimpleTemplateFormat.SimpleParse(formatToUse);
I’ll try and upload a code sample soon.
Add you support for a SharePoint Overflow Q&A site
Please follow this link and show your commitment to a new SharePoint Overflow Q&A site.
http://area51.stackexchange.com/proposals/28921/sharepoint-overflow?referrer=1TGRHFSrtrcnXLaDPCj7kA2
Finding the SMTP server address through code in SharePoint 2010
If anyone knows a better way then let me know.
string smtp = string.Empty;
SPFarm.Local.Servers.ForEach(s => s.ServiceInstances.ForEach(i =>
{
if (i is SPOutboundMailServiceInstance)
{
smtp = s.Address;
}
}));
return smtp;
I use a ForEach extension which I’ve included below
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (T item in enumerable)
{
action(item);
}
}
Dilbert on SharePoint (via SharePoint Tech Blog)
Very true
The hidden User Information List and the Email field
More of a reminder to myself.
The internal name for Email in the hidden User Information list is EMail and not Email.
I came across this when doing a SiteDataQuery on this list and using rather than
The email was never returned in the DataTable.
SPServiceContext or SPContext in SharePoint 2010
After attending the SharePoint Conference 2009, I’m just trying to get clarification on the use of SPServiceContext and SPContext.
In a couple of the developer sessions, the speakers suggested we should use SPServiceContext now instead of SPContext.
Is there an instance where we should use one over the other or should it now always be SPServiceContext?
Any feedback would be greatly appreciated.
SharePoint Conference 2009 – Day Two
I’ve now managed to get my head around most of the new and enhanced features of SharePoint 2010.
My main focus has been around enterprise search and social computing. Two areas I believe are going to massive, when SharePoint 2010 gets released.
I managed to attend the following sessions;
- SharePoint 2010 Search: Capabilities Deep Dive
- Adoption Strategies for Social Computing
- Microsoft Unified Communications and Collaboration in Action
- Deep Dive into SharePoint 2010 My Sites and Social Networking Architecture
- Search Relevance and Relevance tuning
There has been a large investment in the new and enhanced features. My Sites have become the hub for interacting with people through My Sites, User Profiles, Status Updates, Activity Feeds and Knowledge Mining.
SharePoint Conference 2009 – Day One
Well I made it. After travelling for about 12 hours from London to San Fransico to Las Vegas and managed to get over the jet lag (nothing to do with Vegas!)
Today was about getting to know the new version of SharePoint 2010.
We were given an introduction to the product by Steve Ballmer (Microsoft CEO) and Jeff Tepper (Corporate Vice President). There were some nice little sneak peaks and I was surprised that the first demo was a code demo!
My first break session was the “SharePoint 2010 Overview and What’s New” and this gave me a good overview of all the exciting new features available in SharePoint 2010.
Here is a break down (In no particular order) of some of the most exciting
- PowerPivot (Project ‘Gemini’)
- Taxonomy management including tagging and ratings,
- Business Connectivity Services and External Content Types
- Visual Studio 2010 Tools for SharePoint
- Excel, Access and Visio Services and the Office Web Apps
- Sandboxed Solutions
There is a shed load of more features and I’ll blog on them, when I know more.
I then made it along to the ‘Introduction to SharePoint Designer 2010′ and ‘Overview of Social Computing in SharePoint 2010′. The Social Computing of SharePoint 2010 has been greatly improved and their definitely seems to be a nod to Facebook there (The status update and note board).








