| Herman Nijland 2005-11-30, 7:58 am |
| A while ago I posted a problem on this group concerning CMS struggling when
deleting channels with subchannels. After some support sessions with Microsoft
Europe we were told that a) it is possibly a bug in the API (the bad news) and
b) there is a workaround (the good news).
With consent of Yann-Loïc Orgeval (MS Europe, thanks man!) I quote the answer below:
============ Quote E-mail ========================================
===
Further some research and tests I have more information for you on this issue.
Basically, there is an inconsistency in the parent channel node collection after
we delete it. The inconsistency is that the deleted sub channel is still listed
in its collection, so the CMS API fails with an exception “The request node has
been deleted” and terminates. This does not allow the browsing of the parent
channel until its cached items collection is refreshed, because CMS cannot find
the default posting to serve from this channel.
So while this clearly looks like a bug of our API, I found a workaround. In
order to allow the parent channel node collection to remain updated, I store the
post back url to either the default posting of the parent channel or its first
posting before deleting the current channel. In this case when the postback is
done toward the posting unpublished URL, the issue does not occur.
========== End Quote ========================================
=======
And the code of DeleteCurrentChannel.cs:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.WebAuthor;
using Microsoft.ContentManagement.WebControls;
using Microsoft.ContentManagement.WebControls.ConsoleControls;
namespace McmsWebControlLibrary
{
/// <summary>
/// Summary description for DeleteChannel.
/// </summary>
[ToolboxData("<{0}:DeleteCurrentChannel
runat=server></{0}:NewFromTemplateAction>")]
public class DeleteCurrentChannel: BasePostbackAction
{
private Channel cChannel;
private Channel pChannel;
private bool mSetupDone;
[Bindable(true),
Category("Authoring"),
DefaultValue("")]
public override bool Available
{
get
{
return
WebAuthorContext.Current.Mode==WebAuthorContextMode.PresentationUnpublished
&& SetupParams() && cChannel.CanCreateChannels;
}
}
protected override void OnInit(EventArgs e)
{
this.Text = "Delete Current Channel";
}
private bool SetupParams()
{
if (!mSetupDone)
{
cChannel = (Channel)CmsHttpContext.Current.Channel;
pChannel = (Channel)CmsHttpContext.Current.Channel.Parent;
}
mSetupDone = true;
return (cChannel!=null && pChannel !=null);
}
private bool DeleteChannel(Channel dChannel)
{
if ( dChannel != CmsHttpContext.Current.RootChannel )
{
deleteChannelContent(dChannel);
return true;
}
else return false;
}
private void deleteChannelContent(Channel thisChannel)
{
try
{
foreach (Posting delposting in thisChannel.Postings)
{
delposting.Delete();
CmsHttpContext.Current.CommitAll();
}
foreach (Channel subChannel in thisChannel.Channels)
{
deleteChannelContent(subChannel);
}
CmsHttpContext.Current.CommitAll();
thisChannel.Delete();
CmsHttpContext.Current.CommitAll();
}
catch
{
CmsHttpContext.Current.RollbackAll();
throw;
}
}
protected override void PerformActionBehavior()
{
ChannelItem ret = null;
string PostbackURL;
if ( SetupParams() )
{
if ( pChannel.DefaultPostingName != "" )
ret =
(ChannelItem)CmsHttpContext.Current.Searches.GetByPath(pChannel.Path +
pChannel.DefaultPostingName);
else
{
foreach(Posting pDef in pChannel.Postings)
if ( pDef.Path != "" )
{
ret =
(ChannelItem)CmsHttpContext.Current.Searches.GetByPath(pDef.Path);
break;
}
}
PostbackURL = WebAuthorContext.Current.GetUrlForMode(ret,
WebAuthorContextMode.PresentationUnpublished, false);
if ( PostbackURL != "" )
{
DeleteChannel(cChannel);
GenerateStartupScriptRedirect(PostbackUR
L);
base.PerformActionBehavior();
}
}
}
}
}
|