In my recent post I’ve illustrated how to check from code whether a given mail alias is already reserved. If you need to know details about the list / web the alias is mapped to, you have to work further on the issue.
Note: the code below uses non-public API calls and so it is not a supported approach. Use this sample at you own risk and preferably only in test environments.
First I introduced a few extension methods to make our live (and work with Reflection) a bit easier.
- public static class Extensions
- {
- public static object GetPublicInstanceFieldValue(this Type type, string fieldName, object instance)
- {
- object result = null;
- FieldInfo fi = type.GetField(fieldName);
- if ((fi != null) && (instance != null))
- {
- result = fi.GetValue(instance);
- }
- return result;
- }
- public static void SetPublicInstanceFieldValue(this Type type, string fieldName, object fieldValue, object instance)
- {
- FieldInfo fi = type.GetField(fieldName);
- if ((fi != null) && (instance != null))
- {
- fi.SetValue(instance, fieldValue);
- }
- }
- public static object GetPublicInstancePropertyValue(this Type type, string fieldName, object instance)
- {
- object result = null;
- System.Reflection.PropertyInfo pi = type.GetProperty(fieldName);
- if ((pi != null) && (instance != null))
- {
- result = pi.GetValue(instance, null);
- }
- return result;
- }
- }
Next, I defined the following wrapper struct for the internal EmailAliasRecord struct (Microsoft.SharePoint.Administration namespace, Microsoft.SharePoint assembly):
- public struct EmailAliasRecord
- {
- public string Alias { get; private set; }
- public Guid ListId { get; private set; }
- public Guid WebId { get; private set; }
- public Guid SiteId { get; private set; }
- public bool IsValid { get; private set; }
- private const string _emailAliasRecordTypeName = "Microsoft.SharePoint.Administration.EmailAliasRecord";
- public EmailAliasRecord(object emailAliasRecord) : this()
- {
- InitFields(emailAliasRecord);
- }
- private void InitFields(object emailAliasRecord)
- {
- // hack to get the Microsoft.SharPoint assembly
- Assembly sharePointAssembly = typeof(SPWeb).Assembly;
- // and a reference to the type of the EmailAliasRecord internal struct
- Type emailAliasRecordType = sharePointAssembly.GetType(_emailAliasRecordTypeName);
- this.Alias = emailAliasRecordType.GetPublicInstanceFieldValue("alias", emailAliasRecord) as string;
- this.ListId = (Guid)emailAliasRecordType.GetPublicInstanceFieldValue("listId", emailAliasRecord);
- this.WebId = (Guid)emailAliasRecordType.GetPublicInstanceFieldValue("webId", emailAliasRecord);
- this.SiteId = (Guid)emailAliasRecordType.GetPublicInstanceFieldValue("siteId", emailAliasRecord);
- this.IsValid = (bool)emailAliasRecordType.GetPublicInstancePropertyValue("IsValid", emailAliasRecord);
- }
- public EmailAliasRecord(SqlDataReader reader) : this()
- {
- object emailAliasRecord = null;
- // hack to get the Microsoft.SharPoint assembly
- Assembly sharePointAssembly = typeof(SPWeb).Assembly;
- // and a reference to the type of the EmailAliasRecord internal struct
- Type emailAliasRecordType = sharePointAssembly.GetType(_emailAliasRecordTypeName);
- emailAliasRecord = sharePointAssembly.CreateInstance(_emailAliasRecordTypeName);
- if (emailAliasRecord != null)
- {
- emailAliasRecordType.SetPublicInstanceFieldValue("alias", reader.GetString(0), emailAliasRecord);
- emailAliasRecordType.SetPublicInstanceFieldValue("siteId", reader.GetGuid(1), emailAliasRecord);
- emailAliasRecordType.SetPublicInstanceFieldValue("webId", reader.GetGuid(2), emailAliasRecord);
- emailAliasRecordType.SetPublicInstanceFieldValue("listId", reader.GetGuid(3), emailAliasRecord);
- InitFields(emailAliasRecord);
- }
- }
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- using (SPSite site = new SPSite(this.SiteId))
- {
- using (SPWeb web = site.OpenWeb(this.WebId))
- {
- SPList list = web.Lists[this.ListId];
- sb.AppendFormat("{0} e-mail alias '{1}' found\r\n", this.IsValid ? "Valid" : "Invalid", this.Alias);
- if (this.IsValid)
- {
- sb.Append("Mapped to:'\r\n");
- sb.AppendFormat(" Web title: {0}\r\n", web.Title);
- sb.AppendFormat(" Web URL: {0}\r\n", web.Url);
- sb.AppendFormat(" List title: {0}\r\n", list.Title);
- }
- }
- }
- return sb.ToString();
- }
- }
Using the code above, it is rather straightforward to call the private GetEmailAliasRecordFromDatabase method of the internal SPEmailMap class (namespace and assembly as above):
- private void GetEmailAliasRecordFromDatabase(string mailAlias)
- {
- bool found = false;
- string spEmailMapTypeName = "Microsoft.SharePoint.Administration.SPEmailMap";
- // hack to get the Microsoft.SharPoint assembly
- Assembly sharePointAssembly = typeof(SPWeb).Assembly;
- // and a reference to the type of the SPElementProvider internal class
- Type spEmailMapType = sharePointAssembly.GetType(spEmailMapTypeName);
- // spEmailMap will be of type internal class
- // Microsoft.SharePoint.Administration.SPEmailMap
- // defined in Microsoft.SharePoint assembly
- object spEmailMap = sharePointAssembly.CreateInstance(spEmailMapTypeName, false,
- BindingFlags.Public | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null);
- if (spEmailMap != null)
- {
- // we call
- // internal EmailAliasRecord GetEmailAliasRecordFromDatabase(string alias)
- MethodInfo mi_GetEmailAliasRecordFromDatabase = spEmailMapType.GetMethod("GetEmailAliasRecordFromDatabase",
- BindingFlags.NonPublic | BindingFlags.Instance, null,
- new Type[] { typeof(string) }, null
- );
- if (mi_GetEmailAliasRecordFromDatabase != null)
- {
- object result = mi_GetEmailAliasRecordFromDatabase.Invoke(spEmailMap,
- new Object[] { mailAlias });
- EmailAliasRecord ear = new EmailAliasRecord(result);
- if (ear.IsValid)
- {
- found = true;
- Console.WriteLine(ear.ToString());
- }
- }
- }
- if (!found)
- {
- Console.WriteLine("Found no valid mapping for e-mail alias '{0}'", mailAlias);
- }
- }
This code will output the Title property of the associated SPWeb and SPList objects, as well as the Url property of the SPWeb, thus helping you to find out where you set the specified mail alias.