Exemplo n.º 1
0
        protected SPWeb GetWeb(SPWeb parentWeb, WebDefinition webModel)
        {
            var newWebSiteRelativeUrl = SPUrlUtility.CombineUrl(parentWeb.ServerRelativeUrl, webModel.Url);
            var currentWeb = parentWeb.Site.OpenWeb(newWebSiteRelativeUrl);

            return currentWeb;
        }
Exemplo n.º 2
0
        private void CreateWeb(object modelHost, SPWeb parentWeb, WebDefinition webModel)
        {
            if (string.IsNullOrEmpty(webModel.CustomWebTemplate))
            {
                // TODO
                using (var web = GetOrCreateWeb(parentWeb, webModel, true))
                {
                    web.Title = webModel.Title;
                    web.Description = webModel.Description;

                    web.Locale = new CultureInfo((int)webModel.LCID);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model = null,
                        EventType = ModelEventType.OnProvisioned,
                        Object = web,
                        ObjectType = typeof(SPWeb),
                        ObjectDefinition = webModel,
                        ModelHost = modelHost
                    });

                    web.Update();
                }
            }
            else
            {
                throw new SPMeta2NotImplementedException("Custom web templates is not supported yet");
            }
        }
Exemplo n.º 3
0
        private static void MapProperties(SPWeb web, WebDefinition webModel)
        {
            web.Title = webModel.Title;
            web.Description = string.IsNullOrEmpty(webModel.Description) ? String.Empty : webModel.Description;

            if (webModel.LCID > 0)
                web.Locale = new CultureInfo((int)webModel.LCID);

            if (!string.IsNullOrEmpty(webModel.AlternateCssUrl))
                web.AlternateCssUrl = webModel.AlternateCssUrl;

            if (!string.IsNullOrEmpty(webModel.SiteLogoUrl))
                web.SiteLogoUrl = webModel.SiteLogoUrl;
        }
Exemplo n.º 4
0
        private void CreateWeb(object modelHost, SPWeb parentWeb, WebDefinition webModel)
        {
            using (var web = GetOrCreateWeb(parentWeb, webModel, true))
            {
                MapProperties(web, webModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = web,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = modelHost
                });

                web.Update();
            }
        }
Exemplo n.º 5
0
        private void CreateWeb(object modelHost, SPWeb parentWeb, WebDefinition webModel)
        {
            using (var web = GetOrCreateWeb(parentWeb, webModel, true))
            {
                web.Title = webModel.Title;
                web.Description = webModel.Description;

                web.Locale = new CultureInfo((int)webModel.LCID);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = web,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = modelHost
                });

                web.Update();
            }
        }
Exemplo n.º 6
0
        protected virtual SPWebTemplate LookupCustomWebTemplateFromWeb(SPWeb web, WebDefinition definition)
        {
            // smain lookup by the internal name
            var result = web.GetAvailableWebTemplates(definition.LCID)
                            .OfType<SPWebTemplate>()
                            .FirstOrDefault(tmpl => tmpl.IsCustomTemplate
                                                    && !string.IsNullOrEmpty(tmpl.Name)
                                                    && tmpl.Name.ToUpper() == definition.CustomWebTemplate.ToUpper());

            if (result != null)
                return result;

            // one more try by title
            return web.GetAvailableWebTemplates(definition.LCID)
                      .OfType<SPWebTemplate>()
                      .FirstOrDefault(tmpl => tmpl.IsCustomTemplate
                                            && !string.IsNullOrEmpty(tmpl.Title)
                                            && tmpl.Title.ToUpper() == definition.CustomWebTemplate.ToUpper());
        }
Exemplo n.º 7
0
        protected virtual SPWebTemplate LookupCustomWebTemplate(SPWeb web, WebDefinition definition)
        {
            // lookup on the current web?
            SPWebTemplate result = LookupCustomWebTemplateFromWeb(web, definition);

            // lookup on the site?
            if (result == null)
                result = LookupCustomWebTemplateFromWeb(web.Site.RootWeb, definition);

            return result;
        }
Exemplo n.º 8
0
        private string GetCurrentWebUrl(ClientRuntimeContext context, Web parentWeb, WebDefinition webModel)
        {
            // TOSDO, need to have "safe" url concats here, CSOM is doomed
            // WOOOOOOOOOHOAAAAAAAAA how bad is this?! :)

            var fullUrl = context.Url.ToLower();
            var serverUrl = fullUrl.Replace(parentWeb.ServerRelativeUrl.ToLower(), string.Empty);
            var currentWebUrl = serverUrl + "/" + parentWeb.ServerRelativeUrl + "/" + webModel.Url;

            return currentWebUrl.ToLower();
        }
Exemplo n.º 9
0
        /// <summary>
        /// Creates a new instance of the ModelNode adding web model provided.
        /// If RequireSelfProcessing set as 'true', then web model is going to be processed and pushed by SPMeta2 API.
        /// Use action to get access to the "web model node" and construct model tree.
        /// </summary>
        /// <param name="webDefinition"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static ModelNode NewWebModel(WebDefinition webDefinition, Action<ModelNode> action)
        {
            var newModelNode = new ModelNode { Value = webDefinition ?? new WebDefinition { RequireSelfProcessing = false } };

            if (action != null)
                action(newModelNode);

            return newModelNode;
        }
Exemplo n.º 10
0
        private SPWeb GetOrCreateWeb(SPWeb parentWeb, WebDefinition webModel)
        {
            var webUrl = webModel.Url;
            var webDescription = string.IsNullOrEmpty(webModel.Description) ? String.Empty : webModel.Description;

            var currentWeb = GetWeb(parentWeb, webModel);

            if (!currentWeb.Exists)
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = null,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = webModel
                });

                currentWeb = parentWeb.Webs.Add(webUrl,
                    webModel.Title,
                    webDescription,
                    webModel.LCID,
                    webModel.WebTemplate,
                    webModel.UseUniquePermission,
                    webModel.ConvertIfThere);
            }
            else
            {
                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = currentWeb,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = webModel
                });
            }

            return currentWeb;
        }
Exemplo n.º 11
0
        public void Deploy_CRMCustomerSite()
        {
            var customerName = string.Format("Customer_{0}", Environment.TickCount);
            var newCustomerWeb = new WebDefinition
            {
                Title = customerName,
                Url = customerName,
                WebTemplate = BuiltInWebTemplates.Collaboration.TeamSite
            };

            var model = SPMeta2Model
                            .NewWebModel(newCustomerWeb, web =>
                            {
                                web
                                    .AddList(SampleLists.CustomerSite.CustomerDocs)
                                    .AddList(SampleLists.CustomerSite.CustomerIssues)
                                    .AddList(SampleLists.CustomerSite.CustomerTasks)
                                    .AddList(SampleLists.CustomerSite.KPI)
                                    .AddList(BuiltInListDefinitions.SitePages, pages =>
                                    {
                                        pages
                                            .AddWebPartPage(SamplePages.KPI)
                                            .AddWebPartPage(SamplePages.MyTasks)
                                            .AddWikiPage(SamplePages.About)
                                            .AddWikiPage(SamplePages.FAQ);
                                    });
                            });

            DeployWebModel(model);
        }
Exemplo n.º 12
0
        protected LookupFieldEnvironment GetLookupFieldEnvironment(Action<LookupFieldEnvironment> action,
            WebDefinition destinationWebDefinition)
        {
            var result = new LookupFieldEnvironment();

            var dataList = ModelGeneratorService.GetRandomDefinition<ListDefinition>(def =>
            {
                def.TemplateType = BuiltInListTemplateTypeId.GenericList;
            });

            var masterList = ModelGeneratorService.GetRandomDefinition<ListDefinition>(def =>
            {
                def.TemplateType = BuiltInListTemplateTypeId.GenericList;
            });

            var lookupField = GetSingleSelectLookupDefinition(def =>
            {
                def.Indexed = false;
                //def.LookupListTitle = dataList.Title;
            });

            ModelNode childListNode = null;

            var siteModel = SPMeta2Model.NewSiteModel(site =>
            {
                site.AddField(lookupField);
            });

            var webModel = SPMeta2Model.NewWebModel(web =>
            {
                web.AddField(lookupField);
            });

            var childWebModel = SPMeta2Model.NewWebModel(web =>
            {
                if (destinationWebDefinition != null)
                {
                    web.AddWeb(destinationWebDefinition, subWeb =>
                    {
                        subWeb.AddList(dataList, list =>
                        {
                            childListNode = list;

                            list
                                .AddRandomListItem()
                                .AddRandomListItem()
                                .AddRandomListItem();
                        });
                    });
                }
                else
                {
                    web.AddList(dataList, list =>
                    {
                        childListNode = list;

                        list
                            .AddRandomListItem()
                            .AddRandomListItem()
                            .AddRandomListItem();
                    });
                }
            });

            var masterWebModel = SPMeta2Model.NewWebModel(web =>
            {
                web.AddList(masterList, list =>
                {
                    list.AddListFieldLink(lookupField);
                });
            });

            result.LookupField = lookupField;

            result.ChildList = dataList;
            result.ChildListNode = childListNode;
            result.ChildListModel = childWebModel;


            result.MasterList = masterList;
            result.MasterListModel = masterWebModel;

            result.SiteModel = siteModel;
            result.WebModel = webModel;

            if (action != null)
                action(result);

            return result;
        }
Exemplo n.º 13
0
        protected virtual void ProcessLocalization(SPWeb obj, WebDefinition definition)
        {
            if (definition.TitleResource.Any())
            {
                foreach (var locValue in definition.TitleResource)
                    LocalizationService.ProcessUserResource(obj, obj.TitleResource, locValue);
            }

            if (definition.DescriptionResource.Any())
            {
                foreach (var locValue in definition.DescriptionResource)
                    LocalizationService.ProcessUserResource(obj, obj.DescriptionResource, locValue);
            }
        }
Exemplo n.º 14
0
 protected virtual void ProcessLocalization(Web obj, WebDefinition definition)
 {
     ProcessGenericLocalization(obj, new Dictionary<string, List<ValueForUICulture>>
     {
         { "TitleResource", definition.TitleResource },
         { "DescriptionResource", definition.DescriptionResource },
     });
 }
Exemplo n.º 15
0
        private static void MapProperties(Web web, WebDefinition webModel)
        {
            web.Title = webModel.Title;
            web.Description = webModel.Description ?? string.Empty;

            var supportedRuntime = ReflectionUtils.HasProperty(web, "AlternateCssUrl")
                                 && ReflectionUtils.HasProperty(web, "SiteLogoUrl");


            if (supportedRuntime)
            {
                var context = web.Context;

                if (!string.IsNullOrEmpty(webModel.AlternateCssUrl))
                {
                    context.AddQuery(new ClientActionInvokeMethod(web, "AlternateCssUrl", new object[]
                    {
                        webModel.AlternateCssUrl
                    }));
                }

                if (!string.IsNullOrEmpty(webModel.SiteLogoUrl))
                {
                    context.AddQuery(new ClientActionInvokeMethod(web, "SiteLogoUrl", new object[]
                    {
                        webModel.SiteLogoUrl
                    }));
                }
            }
            else
            {
                TraceService.Critical((int)LogEventId.ModelProvisionCoreCall,
                    "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Update CSOM runtime to a new version. Provision is skipped");
            }
        }
Exemplo n.º 16
0
        private static void MapProperties(Web web, WebDefinition webModel)
        {
            if (!string.IsNullOrEmpty(webModel.Title))
                web.Title = webModel.Title;

            if (!string.IsNullOrEmpty(webModel.Description))
                web.Description = webModel.Description;

            var supportedRuntime = ReflectionUtils.HasProperty(web, "AlternateCssUrl") && ReflectionUtils.HasProperty(web, "SiteLogoUrl");
            if (supportedRuntime)
            {
                var context = web.Context;

                if (!string.IsNullOrEmpty(webModel.AlternateCssUrl))
                {
                    context.AddQuery(new ClientActionInvokeMethod(web, "AlternateCssUrl", new object[]
                    {
                        webModel.AlternateCssUrl
                    }));
                }

                if (!string.IsNullOrEmpty(webModel.SiteLogoUrl))
                {
                    context.AddQuery(new ClientActionInvokeMethod(web, "SiteLogoUrl", new object[]
                    {
                        webModel.SiteLogoUrl
                    }));
                }
            }
            else
            {
                TraceService.Critical((int)LogEventId.ModelProvisionCoreCall,
                    "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Update CSOM runtime to a new version. Provision is skipped");
            }

            #if !NET35
            if (webModel.IndexedPropertyKeys.Any())
            {
                var props = web.AllProperties;

                // may not be there at all
                var indexedPropertyValue = props.FieldValues.Keys.Contains("vti_indexedpropertykeys")
                                            ? ConvertUtils.ToStringAndTrim(props["vti_indexedpropertykeys"])
                                            : string.Empty;

                var currentIndexedProperties = IndexedPropertyUtils.GetDecodeValueForSearchIndexProperty(indexedPropertyValue);

                // setup property bag
                foreach (var indexedProperty in webModel.IndexedPropertyKeys)
                {
                    // indexed prop should exist in the prop bag
                    // otherwise it won't be saved by SharePoint (ILSpy / Refletor to see the logic)
                    // http://rwcchen.blogspot.com.au/2014/06/sharepoint-2013-indexed-property-keys.html

                    var propName = indexedProperty.Name;
                    var propValue = string.IsNullOrEmpty(indexedProperty.Value)
                                            ? string.Empty
                                            : indexedProperty.Value;

                    props[propName] = propValue;
                }

                // merge and setup indexed prop keys, preserve existing props
                foreach (var indexedProperty in webModel.IndexedPropertyKeys)
                {
                    if (!currentIndexedProperties.Contains(indexedProperty.Name))
                        currentIndexedProperties.Add(indexedProperty.Name);
                }

                props["vti_indexedpropertykeys"] = IndexedPropertyUtils.GetEncodedValueForSearchIndexProperty(currentIndexedProperties);
            }
            #endif
        }
Exemplo n.º 17
0
        protected SPWeb GetOrCreateWeb(SPWeb parentWeb, WebDefinition webModel, bool updateProperties)
        {
            var webUrl = webModel.Url;
            var webDescription = string.IsNullOrEmpty(webModel.Description) ? String.Empty : webModel.Description;

            // Enhance web provision - handle '/' slash #620
            // https://github.com/SubPointSolutions/spmeta2/issues/620
            webUrl = UrlUtility.RemoveStartingSlash(webUrl);

            var currentWeb = GetWeb(parentWeb, webModel);

            if (!currentWeb.Exists)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = null,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = webModel
                });

                // custom web template handling
                // based on pull request Implematation for CustomWebTemplate included #612 by @andreasblueher
                if (string.IsNullOrEmpty(webModel.CustomWebTemplate))
                {
                    currentWeb = parentWeb.Webs.Add(webUrl,
                        webModel.Title,
                        webDescription,
                        webModel.LCID,
                        webModel.WebTemplate,
                        webModel.UseUniquePermission,
                        webModel.ConvertIfThere);
                }
                else
                {
                    var customWebTemplate = LookupCustomWebTemplate(parentWeb, webModel);

                    if (customWebTemplate == null)
                        throw new SPMeta2ModelDeploymentException("Couldn't find custom web template: " + webModel.CustomWebTemplate);

                    currentWeb = parentWeb.Webs.Add(webUrl,
                        webModel.Title,
                        webModel.Description,
                        webModel.LCID,
                        customWebTemplate,
                        webModel.UseUniquePermission,
                        webModel.ConvertIfThere);
                }
            }
            else
            {
                if (updateProperties)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject,
                        "Current web is not null. Updating Title/Description.");

                    currentWeb.Title = webModel.Title;
                    currentWeb.Description = webModel.Description ?? string.Empty;

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model = null,
                        EventType = ModelEventType.OnProvisioning,
                        Object = currentWeb,
                        ObjectType = typeof(SPWeb),
                        ObjectDefinition = webModel,
                        ModelHost = webModel
                    });

                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "currentWeb.Update()");
                    currentWeb.Update();
                }
            }

            return currentWeb;
        }
Exemplo n.º 18
0
 public static ModelNode AddHostWeb(this ModelNode model, WebDefinition definition)
 {
     return AddHostWeb(model, definition, null);
 }
        public void Deploy_NewWeb()
        {
            // Step 1, define web
            var customerWeb = new WebDefinition
            {
                Title = "Customers",
                Url = "customers",
                Description = "Web site to store customer information.",
                WebTemplate = BuiltInWebTemplates.Collaboration.TeamSite

            };

            var supportWeb = new WebDefinition
            {
                Title = "Support",
                Url = "support",
                Description = "Feedback and support site.",
                WebTemplate = BuiltInWebTemplates.Collaboration.TeamSite
            };

            // Step 2, define web model and artifact relationships - add web to the web 
            var model = SPMeta2Model
                             .NewWebModel(web =>
                             {
                                 web
                                    .AddWeb(customerWeb)
                                    .AddWeb(supportWeb);
                             });

            // Step 3, deploy model
            DeployWebModel(model);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Creates a new instance of the ModelNode adding "empty web model".
        /// Web model is not going to be pushes by SPMeta2 API, it just required to be there for model tree processing.
        /// Use action to get access to the "site model node" and construct model tree.
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public static ModelNode NewWebModel(Action<ModelNode> action)
        {
            var definition = new WebDefinition { RequireSelfProcessing = false };

            return NewWebModel(definition, action);
        }
Exemplo n.º 21
0
 public static ModelNode AddWeb(this ModelNode model, WebDefinition definition, Action<ModelNode> action)
 {
     return model.AddDefinitionNode(definition, action);
 }
Exemplo n.º 22
0
        private static void MapProperties(SPWeb web, WebDefinition webModel)
        {
            // temporarily switch culture to allow setting of the properties Title and Description for multi-language scenarios
            CultureUtils.WithCulture(web.UICulture, () =>
            {
                if (!string.IsNullOrEmpty(webModel.Title))
                    web.Title = webModel.Title;

                if (!string.IsNullOrEmpty(webModel.Description))
                    web.Description = webModel.Description;
            });

            if (webModel.LCID > 0)
                web.Locale = new CultureInfo((int)webModel.LCID);

            if (!string.IsNullOrEmpty(webModel.AlternateCssUrl))
                web.AlternateCssUrl = webModel.AlternateCssUrl;

            if (!string.IsNullOrEmpty(webModel.SiteLogoUrl))
                web.SiteLogoUrl = webModel.SiteLogoUrl;

            #if !NET35
            if (webModel.IndexedPropertyKeys.Any())
            {
                foreach (var indexedProperty in webModel.IndexedPropertyKeys)
                {
                    // indexed prop should exist in the prop bag
                    // otherwise it won't be saved by SharePoint (ILSpy / Refletor to see the logic)
                    // http://rwcchen.blogspot.com.au/2014/06/sharepoint-2013-indexed-property-keys.html

                    var propName = indexedProperty.Name;
                    var propValue = string.IsNullOrEmpty(indexedProperty.Value)
                                            ? string.Empty
                                            : indexedProperty.Value;

                    if (web.AllProperties.ContainsKey(propName))
                        web.AllProperties[propName] = propValue;
                    else
                        web.AllProperties.Add(propName, propValue);

                    if (!web.IndexedPropertyKeys.Contains(propName))
                        web.IndexedPropertyKeys.Add(propName);
                }
            }
            #endif
        }
Exemplo n.º 23
0
 public static ModelNode AddHostWeb(this ModelNode model, WebDefinition definition, Action<ModelNode> action)
 {
     return model.AddDefinitionNodeWithOptions(definition, action, ModelNodeOptions.New().NoSelfProcessing());
 }
Exemplo n.º 24
0
        protected WebDefinition GetLocalizedWebDefinition(WebDefinition definition)
        {
            var localeIds = Rnd.LocaleIds();

            foreach (var localeId in localeIds)
            {
                definition.TitleResource.Add(new ValueForUICulture
                {
                    CultureId = localeId,
                    Value = string.Format("LocalizedTitle_{0}", localeId)
                });

                definition.DescriptionResource.Add(new ValueForUICulture
                {
                    CultureId = localeId,
                    Value = string.Format("LocalizedDescription_{0}", localeId)
                });
            }

            return definition;
        }
Exemplo n.º 25
0
 /// <summary>
 /// Creates a new instance of the ModelNode adding web model provided.
 /// If RequireSelfProcessing set as 'true', then web model is going to be processed and pushed by SPMeta2 API.
 /// </summary>
 /// <param name="webDefinition"></param>
 /// <returns></returns>
 public static ModelNode NewWebModel(WebDefinition webDefinition)
 {
     return NewWebModel(webDefinition, null);
 }
Exemplo n.º 26
0
        protected SPWeb GetOrCreateWeb(SPWeb parentWeb, WebDefinition webModel, bool updateProperties)
        {
            var webUrl = webModel.Url;
            var webDescription = string.IsNullOrEmpty(webModel.Description) ? String.Empty : webModel.Description;

            var currentWeb = GetWeb(parentWeb, webModel);

            if (!currentWeb.Exists)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioning,
                    Object = null,
                    ObjectType = typeof(SPWeb),
                    ObjectDefinition = webModel,
                    ModelHost = webModel
                });

                currentWeb = parentWeb.Webs.Add(webUrl,
                    webModel.Title,
                    webDescription,
                    webModel.LCID,
                    webModel.WebTemplate,
                    webModel.UseUniquePermission,
                    webModel.ConvertIfThere);
            }
            else
            {
                if (updateProperties)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject,
                        "Current web is not null. Updating Title/Description.");

                    currentWeb.Title = webModel.Title;
                    currentWeb.Description = webModel.Description ?? string.Empty;

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model = null,
                        EventType = ModelEventType.OnProvisioning,
                        Object = currentWeb,
                        ObjectType = typeof(SPWeb),
                        ObjectDefinition = webModel,
                        ModelHost = webModel
                    });

                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "currentWeb.Update()");
                    currentWeb.Update();
                }
            }

            return currentWeb;
        }
Exemplo n.º 27
0
 protected string GetCurrentWebUrl(ClientRuntimeContext context, Web parentWeb, WebDefinition webModel)
 {
     var result = UrlUtility.CombineUrl(parentWeb.ServerRelativeUrl, webModel.Url);
     return result.ToLower();
 }
        public override ModelNode ReverseSingleHost(object reverseHost, ReverseOptions options)
        {
            TraceService.Information((int)ReverseLogEventId.ReverseSingleHostStart, "Processing single web host start");

            var item = (reverseHost as WebReverseHost).HostWeb;

            var def = new WebDefinition();

            if (!item.IsPropertyAvailable("Title"))
            {
                item.Context.Load(item);
                item.Context.ExecuteQueryWithTrace();
            }

            def.Title = item.Title;
            def.Description = item.Description;

            def.WebTemplate = item.WebTemplate;

            if (item.Configuration > -1)
            {
                def.WebTemplate = string.Format("{0}#{1}",
                    item.WebTemplate, item.Configuration);
            }

            // always web relative
            def.Url = item.Url.Split('/').Last();

            TraceService.Information((int)ReverseLogEventId.ReverseSingleHostStart, "Processing single web host end");

            return new WebModelNode
            {
                Options = { RequireSelfProcessing = true },
                Value = def
            };
        }