using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SharePoint; /// /// This is a dictionary guaranteed to have only one of each value and key. /// It may be searched either by TFirst or by TSecond, giving a unique answer because it is 1 to 1. /// /// The type of the "key" /// The type of the "value" public class BiDictionaryOneToOne { IDictionary firstToSecond = new Dictionary(); IDictionary secondToFirst = new Dictionary(); #region Exception throwing methods /// /// Tries to add the pair to the dictionary. /// Throws an exception if either element is already in the dictionary /// /// /// public void Add(TFirst first, TSecond second) { if (firstToSecond.ContainsKey(first) || secondToFirst.ContainsKey(second)) throw new ArgumentException("Duplicate first or second"); firstToSecond.Add(first, second); secondToFirst.Add(second, first); } /// /// Find the TSecond corresponding to the TFirst first /// Throws an exception if first is not in the dictionary. /// /// the key to search for /// the value corresponding to first public TSecond GetByFirst(TFirst first) { TSecond second; if (!firstToSecond.TryGetValue(first, out second)) throw new ArgumentException("first"); return second; } /// /// Find the TFirst corresponing to the Second second. /// Throws an exception if second is not in the dictionary. /// /// the key to search for /// the value corresponding to second public TFirst GetBySecond(TSecond second) { TFirst first; if (!secondToFirst.TryGetValue(second, out first)) throw new ArgumentException("second"); return first; } /// /// Remove the record containing first. /// If first is not in the dictionary, throws an Exception. /// /// the key of the record to delete public void RemoveByFirst(TFirst first) { TSecond second; if (!firstToSecond.TryGetValue(first, out second)) throw new ArgumentException("first"); firstToSecond.Remove(first); secondToFirst.Remove(second); } /// /// Remove the record containing second. /// If second is not in the dictionary, throws an Exception. /// /// the key of the record to delete public void RemoveBySecond(TSecond second) { TFirst first; if (!secondToFirst.TryGetValue(second, out first)) throw new ArgumentException("second"); secondToFirst.Remove(second); firstToSecond.Remove(first); } #endregion #region Try methods /// /// Tries to add the pair to the dictionary. /// Returns false if either element is already in the dictionary /// /// /// /// true if successfully added, false if either element are already in the dictionary public Boolean TryAdd(TFirst first, TSecond second) { if (firstToSecond.ContainsKey(first) || secondToFirst.ContainsKey(second)) return false; firstToSecond.Add(first, second); secondToFirst.Add(second, first); return true; } /// /// Find the TSecond corresponding to the TFirst first. /// Returns false if first is not in the dictionary. /// /// the key to search for /// the corresponding value /// true if first is in the dictionary, false otherwise public Boolean TryGetByFirst(TFirst first, out TSecond second) { return firstToSecond.TryGetValue(first, out second); } /// /// Find the TFirst corresponding to the TSecond second. /// Returns false if second is not in the dictionary. /// /// the key to search for /// the corresponding value /// true if second is in the dictionary, false otherwise public Boolean TryGetBySecond(TSecond second, out TFirst first) { return secondToFirst.TryGetValue(second, out first); } /// /// Remove the record containing first, if there is one. /// /// /// If first is not in the dictionary, returns false, otherwise true public Boolean TryRemoveByFirst(TFirst first) { TSecond second; if (!firstToSecond.TryGetValue(first, out second)) return false; firstToSecond.Remove(first); secondToFirst.Remove(second); return true; } /// /// Remove the record containing second, if there is one. /// /// /// If second is not in the dictionary, returns false, otherwise true public Boolean TryRemoveBySecond(TSecond second) { TFirst first; if (!secondToFirst.TryGetValue(second, out first)) return false; secondToFirst.Remove(second); firstToSecond.Remove(first); return true; } #endregion /// /// The number of pairs stored in the dictionary /// public Int32 Count { get { return firstToSecond.Count; } } /// /// Removes all items from the dictionary. /// public void Clear() { firstToSecond.Clear(); secondToFirst.Clear(); } } public abstract class SPUtilityBase { protected void PerformActionOnSite(string siteUrl, Action action) { using (SPSite site = new SPSite(siteUrl)) { using (SPWeb web = site.OpenWeb()) { action(site, web); web.Close(); } site.Close(); } } } public enum SPSiteTemplates { TeamSite, BlankSite, DocumentWorkspace, BasicMeetingWorkspace, BlankMeetingWorkspace, DecisionMeetingWorkspace, SocialMeetingWorkspace, MultiPageMeetingWorkspace, Wiki, Blog, /// /// A central document management location for an enterprise /// DocumentCenter, /// /// A central location in which records managers can define routes for incoming files /// RecordsCenter1, RecordsCenter2, PublishingSite, /// /// A site for publishing web pages on a schedule with workflow features enabled /// PublishingSite2, PressReleasesSite, /// /// A publishing site for web pages using approval workflows /// PublishingSiteWithWorkflow, /// /// A site for publishing news and articles /// NewsSite, /// /// A site for creating, managing, and delivering web pages, dashboards, and Key Performance Indicators (KPIs) /// ReportCenter, /// /// A starter hierarchy for an intranet divisional portal /// SPSPortal, /// /// A profile site that includes page layouts with zones /// ProfileSite, /// /// A site collection preconfigured for revision-controlled, secure content creation and publication /// PublishingPortal, /// /// Keep in mind that only one of these can be provisioned per Shared Services Provider /// MySiteHost, /// /// A site designed to deliver the search query and results experience /// SearchCenter, /// /// A superset of the previous; does not appear in navigation bars /// SearchCenter2 } public static class SPSiteTemplateMethodExtension { private const string SP_SITE_TEMPLATE_TEAM_SITE = "STS#0"; private const string SP_SITE_TEMPLATE_BLANK_SITE = "STS#1"; private const string SP_SITE_TEMPLATE_DOCUMENT_WORKSPACE = "STS#2"; private const string SP_SITE_TEMPLATE_BASIC_MEETING_WORKSPACE = "MPS#0"; private const string SP_SITE_TEMPLATE_BLANK_MEETING_WORKSPACE = "MPS#1"; private const string SP_SITE_TEMPLATE_DECISION_MEETING_WORKSPACE = "MPS#2"; private const string SP_SITE_TEMPLATE_SOCIAL_MEETING_WORKSPACE = "MPS#3"; private const string SP_SITE_TEMPLATE_MULTI_PAGE_MEETING_WORKSPACE = "MPS#4"; private const string SP_SITE_TEMPLATE_WIKI = "WIKI#0"; private const string SP_SITE_TEMPLATE_BLOG = "BLOG#0"; private const string SP_SITE_TEMPLATE_DOCUMENT_CENTER = "BDR#0"; private const string SP_SITE_TEMPLATE_RECORDS_CENTER_1 = "OFFILE#0"; private const string SP_SITE_TEMPLATE_RECORDS_CENTER_2 = "OFFILE#1"; private const string SP_SITE_TEMPLATE_PUBLISHING_SITE = "CMSPUBLISHING#0"; private const string SP_SITE_TEMPLATE_PUBLISHING_SITE_2 = "BLANKINTERNET#0"; private const string SP_SITE_TEMPLATE_PRESS_RELEASES_SITE = "BLANKINTERNET#1"; private const string SP_SITE_TEMPLATE_PUBLISHING_SITE_WITH_WORKFLOW = "BLANKINTERNET#2"; private const string SP_SITE_TEMPLATE_NEWS_SITE = "SPSNHOME#0"; private const string SP_SITE_TEMPLATE_REPORT_CENTER = "SPSREPORTCENTER#0"; private const string SP_SITE_TEMPLATE_SPS_PORTAL = "SPSPORTAL#0"; private const string SP_SITE_TEMPLATE_PROFILE_SITE = "PROFILES#0"; private const string SP_SITE_TEMPLATE_PUBLISHING_PORTAL = "BLANKINTERNETCONTAINER#0"; private const string SP_SITE_TEMPLATE_MY_SITE_HOST = "SPSMYSITEHOST#0"; private const string SP_SITE_TEMPLATE_SEARCH_CENTER = "SRCHCENTERLITE#0"; private const string SP_SITE_TEMPLATE_SEARCH_CENTER_2 = "SRCHCENTERLITE#1"; private static BiDictionaryOneToOne _templates; private static BiDictionaryOneToOne Templates { get { if (_templates == null) { _templates = new BiDictionaryOneToOne(); _templates.Add(SPSiteTemplates.BasicMeetingWorkspace, SP_SITE_TEMPLATE_BASIC_MEETING_WORKSPACE); _templates.Add(SPSiteTemplates.BlankMeetingWorkspace, SP_SITE_TEMPLATE_BLANK_MEETING_WORKSPACE); _templates.Add(SPSiteTemplates.BlankSite , SP_SITE_TEMPLATE_BLANK_SITE); _templates.Add(SPSiteTemplates.Blog , SP_SITE_TEMPLATE_BLOG); _templates.Add(SPSiteTemplates.DecisionMeetingWorkspace , SP_SITE_TEMPLATE_DECISION_MEETING_WORKSPACE); _templates.Add(SPSiteTemplates.DocumentCenter , SP_SITE_TEMPLATE_DOCUMENT_CENTER); _templates.Add(SPSiteTemplates.DocumentWorkspace , SP_SITE_TEMPLATE_DOCUMENT_WORKSPACE); _templates.Add(SPSiteTemplates.MultiPageMeetingWorkspace , SP_SITE_TEMPLATE_MULTI_PAGE_MEETING_WORKSPACE); _templates.Add(SPSiteTemplates.MySiteHost , SP_SITE_TEMPLATE_MY_SITE_HOST); _templates.Add(SPSiteTemplates.NewsSite , SP_SITE_TEMPLATE_NEWS_SITE); _templates.Add(SPSiteTemplates.PressReleasesSite , SP_SITE_TEMPLATE_PRESS_RELEASES_SITE); _templates.Add(SPSiteTemplates.ProfileSite , SP_SITE_TEMPLATE_PROFILE_SITE); _templates.Add(SPSiteTemplates.PublishingPortal , SP_SITE_TEMPLATE_PUBLISHING_PORTAL); _templates.Add(SPSiteTemplates.PublishingSite , SP_SITE_TEMPLATE_PUBLISHING_SITE); _templates.Add(SPSiteTemplates.PublishingSite2 , SP_SITE_TEMPLATE_PUBLISHING_SITE_2); _templates.Add(SPSiteTemplates.PublishingSiteWithWorkflow , SP_SITE_TEMPLATE_PUBLISHING_SITE_WITH_WORKFLOW); _templates.Add(SPSiteTemplates.RecordsCenter1 , SP_SITE_TEMPLATE_RECORDS_CENTER_1); _templates.Add(SPSiteTemplates.RecordsCenter2 , SP_SITE_TEMPLATE_RECORDS_CENTER_2); _templates.Add(SPSiteTemplates.ReportCenter , SP_SITE_TEMPLATE_REPORT_CENTER); _templates.Add(SPSiteTemplates.SearchCenter , SP_SITE_TEMPLATE_SEARCH_CENTER); _templates.Add(SPSiteTemplates.SearchCenter2 , SP_SITE_TEMPLATE_SEARCH_CENTER_2); _templates.Add(SPSiteTemplates.SocialMeetingWorkspace , SP_SITE_TEMPLATE_SOCIAL_MEETING_WORKSPACE); _templates.Add(SPSiteTemplates.SPSPortal , SP_SITE_TEMPLATE_SPS_PORTAL); _templates.Add(SPSiteTemplates.TeamSite , SP_SITE_TEMPLATE_TEAM_SITE); _templates.Add(SPSiteTemplates.Wiki , SP_SITE_TEMPLATE_WIKI); } return _templates; } } public static string GetSharePointStringKey(this SPSiteTemplates siteTemplate) { return Templates.GetByFirst(siteTemplate); } } public enum SPLocales: uint { Afrikaans /*af*/ = 1078, Albanian /*sq*/ = 1052, Arabic_UnitedArabEmirates /*ar-ae*/ = 14337, Arabic_Bahrain /*ar-bh*/ = 15361, Arabic_Algeria /*ar-dz*/ = 5121, Arabic_Egypt /*ar-eg*/ = 3073, Arabic_Iraq /*ar-iq*/ = 2049, Arabic_Jordan /*ar-jo*/ = 11265, Arabic_Kuwait /*ar-kw*/ = 13313, Arabic_Lebanon /*ar-lb*/ = 12289, Arabic_Libya /*ar-ly*/ = 4097, Arabic_Morocco /*ar-ma*/ = 6145, Arabic_Oman /*ar-om*/ = 8193, Arabic_Qatar /*ar-qa*/ = 16385, Arabic_SaudiArabia /*ar-sa*/ = 1025, Arabic_Syria /*ar-sy*/ = 10241, Arabic_Tunisia /*ar-tn*/ = 7169, Arabic_Yemen /*ar-ye*/ = 9217, Armenian /*hy*/ = 1067, Azeri_Latin /*az-az*/ = 1068, Azeri_Cyrillic /*az-az*/ = 2092, Basque /*eu*/ = 1069, Belarusian /*be*/ = 1059, Bulgarian /*bg*/ = 1026, Catalan /*ca*/ = 1027, Chinese_China /*zh-cn*/ = 2052, Chinese_HongKongSAR /*zh-hk*/ = 3076, Chinese_MacauSAR /*zh-mo*/ = 5124, Chinese_Singapore /*zh-sg*/ = 4100, Chinese_Taiwan /*zh-tw*/ = 1028, Croatian /*hr*/ = 1050, Czech /*cs*/ = 1029, Danish /*da*/ = 1030, Dutch_TheNetherlands /*nl-nl*/ = 1043, Dutch_Belgium /*nl-be*/ = 2067, English_Australia /*en-au*/ = 3081, English_Belize /*en-bz*/ = 10249, English_Canada /*en-ca*/ = 4105, English_Caribbean /*en-cb*/ = 9225, English_Ireland /*en-ie*/ = 6153, English_Jamaica /*en-jm*/ = 8201, English_NewZealand /*en-nz*/ = 5129, English_Phillippines /*en-ph*/ = 13321, English_SouthAfrica /*en-za*/ = 7177, English_Trinidad /*en-tt*/ = 11273, English_UnitedKingdom /*en-gb*/ = 2057, English_UnitedStates /*en-us*/ = 1033, Estonian /*et*/ = 1061, Farsi /*fa*/ = 1065, Finnish /*fi*/ = 1035, Faroese /*fo*/ = 1080, French_France /*fr-fr*/ = 1036, French_Belgium /*fr-be*/ = 2060, French_Canada /*fr-ca*/ = 3084, French_Luxembourg /*fr-lu*/ = 5132, French_Switzerland /*fr-ch*/ = 4108, Gaelic_Ireland /*gd-ie*/ = 2108, Gaelic_Scotland /*gd*/ = 1084, German_Germany /*de-de*/ = 1031, German_Austria /*de-at*/ = 3079, German_Liechtenstein /*de-li*/ = 5127, German_Luxembourg /*de-lu*/ = 4103, German_Switzerland /*de-ch*/ = 2055, Greek /*el*/ = 1032, Hebrew /*he*/ = 1037, Hindi /*hi*/ = 1081, Hungarian /*hu*/ = 1038, Icelandic /*is*/ = 1039, Indonesian /*id*/ = 1057, Italian_Italy /*it-it*/ = 1040, Italian_Switzerland /*it-ch*/ = 2064, Japanese /*ja*/ = 1041, Korean /*ko*/ = 1042, Latvian /*lv*/ = 1062, Lithuanian /*lt*/ = 1063, FYRO_Macedonian /*mk*/ = 1071, Malay_Malaysia /*ms-my*/ = 1086, Malay_Brunei /*ms-bn*/ = 2110, Maltese /*mt*/ = 1082, Marathi /*mr*/ = 1102, Norwegian_Bokmal /*no-no*/ = 1044, Norwegian_Nynorsk /*no-no*/ = 2068, Polish /*pl*/ = 1045, Portuguese_Portugal /*pt-pt*/ = 2070, Portuguese_Brazil /*pt-br*/ = 1046, Raeto_Romance /*rm*/ = 1047, Romanian_Romania /*ro*/ = 1048, Romanian_RepublicOfMoldova /*ro-mo*/ = 2072, Russian /*ru*/ = 1049, Russian_RepublicOfMoldova /*ru-mo*/ = 2073, Sanskrit /*sa*/ = 1103, Serbian_Cyrillic /*sr-sp*/ = 3098, Serbian_Latin /*sr-sp*/ = 2074, Setsuana /*tn*/ = 1074, Slovenian /*sl*/ = 1060, Slovak /*sk*/ = 1051, Sorbian /*sb*/ = 1070, Spanish_Spain /*es-es*/ = 1034, Spanish_Argentina /*es-ar*/ = 11274, Spanish_Bolivia /*es-bo*/ = 16394, Spanish_Chile /*es-cl*/ = 13322, Spanish_Colombia /*es-co*/ = 9226, Spanish_CostaRica /*es-cr*/ = 5130, Spanish_DominicanRepublic /*es-do*/ = 7178, Spanish_Ecuador /*es-ec*/ = 12298, Spanish_Guatemala /*es-gt*/ = 4106, Spanish_Honduras /*es-hn*/ = 18442, Spanish_Mexico /*es-mx*/ = 2058, Spanish_Nicaragua /*es-ni*/ = 19466, Spanish_Panama /*es-pa*/ = 6154, Spanish_Peru /*es-pe*/ = 10250, Spanish_PuertoRico /*es-pr*/ = 20490, Spanish_Paraguay /*es-py*/ = 15370, Spanish_ElSalvador /*es-sv*/ = 17418, Spanish_Uruguay /*es-uy*/ = 14346, Spanish_Venezuela /*es-ve*/ = 8202, Sutu /*sx*/ = 1072, Swahili /*sw*/ = 1089, Swedish_Sweden /*sv-se*/ = 1053, Swedish_Finland /*sv-fi*/ = 2077, Tamil /*ta*/ = 1097, Tatar /*tt*/ = 1092, Thai /*th*/ = 1054, Turkish /*tr*/ = 1055, Tsonga /*ts*/ = 1073, Ukrainian /*uk*/ = 1058, Urdu /*ur*/ = 1056, Uzbek_Cyrillic /*uz-uz*/ = 2115, Uzbek_Latin /*uz-uz*/ = 1091, Vietnamese /*vi*/ = 1066, Xhosa /*xh*/ = 1076, Yiddish /*yi*/ = 1085, Zulu /*zu*/ = 1077 } public class SPSiteHelper: SPUtilityBase { // based on http://blah.winsmarts.com/2007-5-Programatically_create_a_SharePoint_site_based_on_a_site_definition.aspx public SPWeb CreateSite(string parentSiteURL, string siteURLRequested, string siteTitle, SPSiteTemplates siteTemplate, SPLocales locale, string description) { SPWeb resultWeb = null; PerformActionOnSite(parentSiteURL, (siteCollection, parentWeb) => { SPWebTemplateCollection Templates = siteCollection.GetWebTemplates(Convert.ToUInt32(locale)); SPWebTemplate spTemplate = Templates[siteTemplate.GetSharePointStringKey()]; // http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010programming/thread/a2b19ec3-6380-44a9-a027-37e9dbd84762 var rootUrl = siteCollection.Url; if (siteURLRequested.ToUpper().StartsWith(rootUrl.ToUpper())) { siteURLRequested = siteURLRequested.Remove(0, rootUrl.Length); if (siteURLRequested.StartsWith("/")) siteURLRequested = siteURLRequested.Remove(0, 1); if (siteURLRequested.Length == 0) //they were equal, don't create the root site { resultWeb = parentWeb; } else if (parentWeb.Webs[siteURLRequested].Exists) //it's not the root site, but it exist anyway { resultWeb = parentWeb.Webs[siteURLRequested]; } else { resultWeb = parentWeb.Webs.Add(siteURLRequested, siteTitle, description, Convert.ToUInt32(locale), spTemplate, false, false); } } }); return resultWeb; } }