Creating frontend pages on module installation
Hi,
I'm trying to make some pages in module intsallation method. I click install and it install process doesn't stops. After refreshing module page, there is an error saying: "Object references between two different object scopes are not allowed. The object 'Telerik.Sitefinity.Pages.Model.PageNode' is already managed by 'ObjectScopeImpl 0x4e OpenAccessRuntime.EnlistableObjectScope' and was tried to be managed again by 'ObjectScopeImpl 0x5d OpenAccessRuntime.EnlistableObjectScope'.":
01.
App.WorkWith().Page()
02.
.CreateNewStandardPage(PageManager.GetManager().GetLocationRoot(Telerik.Sitefinity.Fluent.Pages.PageLocation.Frontend),UniquePageGuid)
03.
.Do(p=>
04.
05.
p.Title =
"Test page"
;
06.
p.ShowInNavigation =
false
;
07.
p.UrlName =
"test234"
;
08.
p.NodeType = NodeType.Group;
09.
)
10.
.Done();
Native API works fine:
PageNode rootPage = PageManager.GetManager().CreatePage(Telerik.Sitefinity.Fluent.Pages.PageLocation.Frontend, Uniquepageid, NodeType.Group);
rootPage.Title = "test123";
rootPage.ShowInNavigation = false;
rootPage.UrlName = "test233";
I'm having one more problem. After creating page, I would like to publish that page.
As written in example, i wrote that:
Dictionary<string, string> bag1 = new Dictionary<string, string>();
bag1.Add("ContentType", typeof(PageNode).FullName);
WorkflowManager.MessageWorkflow(newPage.Id, typeof(PageNode), null, "Publish", false, bag1);
But call to "WorkflowManager.MessageWorkflow" throws an exception "HTTP Content-Type header is required for SOAP messaging and none was found."
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Telerik.Sitefinity.ContentWorkflows.IService.SendMessage(String operationName, Boolean isCheckedOut, Guid workflowDefinitionId, Guid contentId, String providerName, Dictionary`2 contextBag)
at Telerik.Sitefinity.ContentWorkflows.ServiceClient.SendMessage(String operationName, Boolean isCheckedOut, Guid workflowDefinitionId, Guid contentId, String providerName, Dictionary`2 contextBag)
at Telerik.Sitefinity.Workflow.WorkflowManager.MessageWorkflow(String wokflowUrl, String operationName, WorkflowDefinition workflowDefinition, Guid contentId, String providerName, Boolean isCheckedOut, Dictionary`2 contextBag)
at Telerik.Sitefinity.Workflow.WorkflowManager.MessageWorkflow(Guid itemId, Type itemType, String providerName, String operationName, Boolean isCheckedOut, Dictionary`2 contextBag)
at TestModule.TestModuleInfo.InstallPages(SiteInitializer initializer) in ****TestModuleInfo.cs:line 300
at Telerik.Sitefinity.Modules.GenericContent.ContentModuleBase.Install(SiteInitializer initializer)
at TestModule.TestModuleInfo.Install(SiteInitializer initializer) in ****TestModuleInfo.cs:line 156
at Telerik.Sitefinity.Services.ModuleBase.Install(SiteInitializer initializer, Version upgradeFrom)
at Telerik.Sitefinity.Services.SystemManager.InitializeModule(ModuleSettings settings, InstallContext installContext, Nullable`1 start, Boolean skipLoading)
When exception occurs bag1 contains:
[ContentType, Telerik.Sitefinity.Pages.Model.PageNode]
[userHostAddress, ::1]
Hello,
Do you experience this problem only when you're publishing a page by code? Please try the following code, since with it I was able to create a new Page in a sample project:
protected
void
Page_Load(
object
sender, EventArgs e)
var page =
"myTestPage"
;
var pageId = Guid.NewGuid();
var parentPageNodeId = Guid.Empty;
CreatePage(pageId, page,
false
, parentPageNodeId);
public
void
CreatePage(Guid pageId,
string
pageName,
bool
isHomePage, Guid parentPageNodeId)
var pageDataId = Guid.NewGuid();
PageManager manager = PageManager.GetManager();
PageData pageData =
null
;
PageNode pageNode =
null
;
// Get the parent node Id
if
(parentPageNodeId == Guid.Empty)
parentPageNodeId = SiteInitializer.FrontendRootNodeId;
PageNode parent = manager.GetPageNode(parentPageNodeId);
// Check whether exists
var initialPageNode = manager.GetPageNodes().Where(n => n.Id == pageId).SingleOrDefault();
if
(initialPageNode !=
null
)
return
;
// Create the page
pageData = manager.CreatePageData(pageDataId);
pageData.HtmlTitle = pageName;
pageData.Title = pageName;
pageData.Description = pageName;
pageData.Culture = Thread.CurrentThread.CurrentCulture.ToString();
pageData.UiCulture = Thread.CurrentThread.CurrentUICulture.ToString();
pageNode = manager.CreatePage(parent, pageId, NodeType.Standard);
pageNode.Page = pageData;
pageNode.Name = pageName;
pageNode.Description = pageName;
pageNode.Title = pageName;
pageNode.UrlName = Regex.Replace(pageName.ToLower(), @
"[^\w\-\!\$\'\(\)\=\@\d_]+"
,
"-"
);
pageNode.ShowInNavigation =
true
;
pageNode.DateCreated = DateTime.UtcNow;
pageNode.LastModified = DateTime.UtcNow;
// Check whether home page
if
(isHomePage)
manager.SetHomePage(pageId);
manager.SaveChanges();
// Publish
var bag =
new
Dictionary<
string
,
string
>();
bag.Add(
"ContentType"
,
typeof
(PageNode).FullName);
WorkflowManager.MessageWorkflow(pageId,
typeof
(PageNode),
null
,
"Publish"
,
false
, bag);
First, thank you for reply.
Second: I'm trying to publish page in context of module instalation, where I can't use SaveChanges():
protected override void InstallPages(Telerik.Sitefinity.Abstractions.SiteInitializer initializer)
PageManager pageManager = initializer.PageManager;
....
Page creation works fine, publishing using WorkflowManager creates problem.
I don't know how, but I found out that pageManager.PublishPageDraft(draftPage); does the job.
What's the difference between those two methods?
I used this guide: www.sitefinity.com/.../adding-and-removing-controls
Edit: I experienced this problem only with code, in cms everything works.
Hello,
The two approaches are different. Calling WorkflowManager.MessageWorkflow you're publishing the page through the Workflow, which changes its ApprovalWorkflowState to Published (this can be seen under the Page title in the SiteMap tree - the "Published" sign comes from the worflow). Messaging the workflow also changes the lifestyle of the page to Live. The other approach you mentioned goes through the life lifecylce only. This means that if you have any workflows set (default or custom) it will publish the page without passing through the workflow. Of course in this case you need to change the ApprovalWorkflowState to published again. Here's a sample code where we're using the lifecycle to publish the page. We practically repeat the procedure - creating a the page node and page data, but then we edit the page, which releases a "temp" version of the page. Then we Checkin the page. This creates a draft of the page. The last thing we do is we pass the draft to the Publish lifecycle method of the page manager and set the ApprovalWorkflowState status to "Published".
var page =
"Test"
;
var pageId = Guid.NewGuid();
var parentPageNodeId = Guid.Empty;
CreatePage(pageId, page,
false
, parentPageNodeId);
public
void
CreatePage(Guid pageId,
string
pageName,
bool
isHomePage, Guid parentPageNodeId)
var pageDataId = Guid.NewGuid();
PageManager manager = PageManager.GetManager();
PageData pageData =
null
;
PageNode pageNode =
null
;
// Get the parent node Id
if
(parentPageNodeId == Guid.Empty)
parentPageNodeId = SiteInitializer.FrontendRootNodeId;
PageNode parent = manager.GetPageNode(parentPageNodeId);
// Check whether exists
var initialPageNode = manager.GetPageNodes().Where(n => n.Id == pageId).SingleOrDefault();
if
(initialPageNode !=
null
)
return
;
// Create the page
pageData = manager.CreatePageData(pageDataId);
pageData.HtmlTitle = pageName;
pageData.Title = pageName;
pageData.Description = pageName;
pageData.Culture = Thread.CurrentThread.CurrentCulture.ToString();
pageData.UiCulture = Thread.CurrentThread.CurrentUICulture.ToString();
pageNode = manager.CreatePage(parent, pageId, NodeType.Standard);
pageNode.Page = pageData;
pageNode.Name = pageName;
pageNode.Description = pageName;
pageNode.Title = pageName;
pageNode.UrlName = Regex.Replace(pageName.ToLower(), @
"[^\w\-\!\$\'\(\)\=\@\d_]+"
,
"-"
);
pageNode.ShowInNavigation =
true
;
pageNode.DateCreated = DateTime.UtcNow;
pageNode.LastModified = DateTime.UtcNow;
// Check whether home page
if
(isHomePage)
manager.SetHomePage(pageId);
manager.SaveChanges();
var temp = manager.EditPage(pageData.Id);
var draft = manager.PagesLifecycle.CheckIn(temp);
// Publish
//var bag = new Dictionary<string, string>();
//bag.Add("ContentType", typeof(PageNode).FullName);
//WorkflowManager.MessageWorkflow(pageId, typeof(PageNode), null, "Publish", false, bag);
manager.PagesLifecycle.Publish(draft);
pageNode.ApprovalWorkflowState =
"Published"
;
manager.SaveChanges();
public
static
bool
CreatePage(Guid pageId,
string
pageName,
bool
isHomePage, Guid parentPageId)
bool
result =
false
;
var pageDataId = Guid.NewGuid();
var parentId = parentPageId;
if
(parentId == Guid.Empty)
parentId = SiteInitializer.FrontendRootNodeId;
var count = 0;
using
(var fluent = App.WorkWith())
var pagesFacade = fluent.Pages();
using
(
new
ElevatedModeRegion(pagesFacade.GetManager()))
pagesFacade.Where(p => p.Id == pageId).Count(
out
count);
if
(count == 0)
var pageFacade = fluent.Page();
pageFacade
.CreateNewStandardPage(parentId, pageId, pageDataId)
.Do(p =>
p.Title = pageName;
p.Name = pageName;
p.Description = pageName;
p.UrlName = Regex.Replace(pageName.ToLower(), UrlNameCharsToReplace, UrlNameReplaceString);
p.ShowInNavigation =
true
;
p.DateCreated = DateTime.UtcNow;
p.LastModified = DateTime.UtcNow;
p.Page.HtmlTitle = pageName;
p.Page.HtmlTitle = pageName;
p.Page.Title = pageName;
p.Page.Description = pageName;
p.Page.Culture = Thread.CurrentThread.CurrentCulture.ToString();
p.Page.UiCulture = Thread.CurrentThread.CurrentUICulture.ToString();
p.ApprovalWorkflowState.Value = SampleUtilities.ApprovalWorkflowStatePublished;
).CheckOut().Publish().SaveChanges();
if
(isHomePage)
SystemManager.CurrentContext.CurrentSite.SetHomePage(pageId);
//var pageIdFacade = fluent.Page(pageId);
//using (new ElevatedModeRegion(pageIdFacade.GetManager()))
//
// pageIdFacade.SetAsHomePage().SaveChanges();
//
result =
true
;
return
result;
Yes, both works fine everywhere except in module instalation method.
Hello,
Can you give us more information about the errors you get when you run the provided code samples?
Regards,Full example:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading;
using
Telerik.Sitefinity.Abstractions;
using
Telerik.Sitefinity.Configuration;
using
Telerik.Sitefinity.Fluent.Pages;
using
Telerik.Sitefinity.Modules.Pages;
using
Telerik.Sitefinity.Pages.Model;
using
Telerik.Sitefinity.Services;
using
Telerik.Sitefinity.Workflow;
namespace
TestModule
public
class
ModuleInfo : ModuleBase
public
override
void
Install(SiteInitializer initializer)
// I can also use PageManager.GetManager(),
// but same exception occurs in the end
PageManager pageManager = initializer.PageManager;
PageNode node = pageManager.CreatePage(PageLocation.Frontend,
Guid.NewGuid(), NodeType.Standard);
// set page properties
node.Title =
"Test page"
;
node.ShowInNavigation =
false
;
node.UrlName =
"test-page"
;
node.DateCreated = DateTime.Now;
node.LastModified = DateTime.Now;
// Create a PageData object to hold the actual page contents
PageData pageData = pageManager.CreatePageData();
pageData.HtmlTitle =
"Test page"
;
pageData.Title =
"Test page"
;
pageData.Visible =
true
;
pageData.IncludeScriptManager =
true
;
pageData.Culture = Thread.CurrentThread.CurrentCulture.ToString();
pageData.UiCulture = Thread.CurrentThread.CurrentUICulture.ToString();
pageData.Template = pageManager.GetTemplates().FirstOrDefault();
// associate the node with the PageData object
node.Page = pageData;
/* can't save here, because I'm using initializer.PageManager
Exception occuring: Cannot use SaveChanges or CancelChanges on
instance manager that was specified to use global or distributed
transaction. Instead, use TransactionManager static methods
CommitTransaction(string transactionName) or
RollbackTransaction(string transactionName). */
// pageManager.SaveChanges();
// Editing page
PageDraft draftPage = pageManager.EditPage(pageData.Id);
draftPage.TemplateId = pageData.Template.Id;
pageManager.PagesLifecycle.CheckIn(draftPage,
Thread.CurrentThread.CurrentUICulture);
// can't save page
// pageManager.SaveChanges();
/* here exception occurs
Text - An HTTP Content-Type header is required for SOAP
messaging and none was found. */
WorkflowManager.MessageWorkflow(node.Id,
typeof
(PageNode),
null
,
"Publish"
,
false
,
new
Dictionary<
string
,
string
>()
"ContentType"
,
typeof
(PageNode).FullName
);
protected
override
ConfigSection GetModuleConfig()
return
null
;
public
override
Guid LandingPageId
get
return
new
Guid(
"a39e0940-477f-4a7c-a6ff-58c00f072d0f"
);
public
override
Type[] Managers
get
return
new
Type[] ;
public
override
void
Upgrade(SiteInitializer initializer,
Version upgradeFrom)
Hello Gooya,
I wasn't able to reproduce the exception with your code. Please try to publish pages with the two codes I sent you. You can find more information about the exception you receive here:
social.msdn.microsoft.com/.../8e4c954e-37f5-4149-b2dd-f6f1f0e2e8ca
I the issue persists, I would suggest you to open a support ticket and provide your module for debugging.