Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Server

Microsoft Content Management Server : The ASP.NET Stager Application (part 1) - The DotNetSiteStager Project, Recording Messages to a Log File

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
11/30/2012 6:20:06 PM
In the previous section, we have seen how Site Stager works. It is a good tool for creating static snapshots of ASP-based sites. Obviously, we don’t want to take a huge step back and convert all our templates from ASP.NET to ASP. How, then, shall we stage sites that make use of the newer and improved ASP.NET? To get around this limitation of Site Stager, we will build our very own version of the staging tool. The good news is that we won’t start entirely from scratch: we will borrow some of the concepts and ideas behind Site Stager.

Let’s build a console application that mimics what Site Stager does for MCMS 2001 or ASP-based templates in MCMS 2002. Note that the application uses the MCMS PAPI and will need to be executed on a server that has MCMS installed.

Here’s what the application will do:

  • Walk through the entire channel structure, starting from a specified start channel. For each posting and channel cover page found, a static HTML file is generated.

  • Scan through each channel cover page and posting for attachments and stage them.

  • Provide settings for administrators to change the behavior of the stager. For example, administrators can specify the start channel, whether or not hidden postings will be staged, and so on.

We will make the assumption that the staged pages will be placed in the same folder structure as found in Site Manager. For relative links within pages to remain unbroken, the pages should not be nested within sub folders. For example, http://tropicalgreen1 can be staged to http://tropicalgreen2 but not to http://servername/tropicalgreen3/.

The DotNetSiteStager Project

Let’s start by creating a Visual C# Console Application project named DotNetSiteStager. Rename Class1.cs to Stager.cs.

Add the following references to the project:

  • Microsoft.ContentManagement.Publishing.dll (located in the <install directory>/Microsoft Content Management Server/Server/bin/ directory)

  • System.Web

The following namespaces are also required by the solution. Add them above the namespace declaration:

using System;
using System.IO;
						using System.Net;
						using System.Web;
						using System.Text;
						using System.Collections;
						using System.Text.RegularExpressions;
						using Microsoft.ContentManagement.Publishing;
						namespace DotNetSiteStager
{
  . . . code continues . . .
}

Configuring Stager Settings

The .NET stager will provide several configurable settings as shown in the following table. Notice that some settings are equivalent to fields available in Site Stager. We did say that we were going to borrow some of Site Stager’s ideas!

SettingDescriptionValue for Example
m_DestinationDirectorySpecifies the folder where we will create all staged folders and files. This could be a location on the source server itself, or a directory on a remote server in the network. Equivalent to the Destination Directory field of Site Stager.C:\StagedSite\
m_StartChannelThe channel that the stager will begin staging from. You can change the start channel to point to any channel within the hierarchy, allowing you to increase or reduce the scope of the stager accordingly./Channels/www.tropicalgreen.net/
m_LogFileThe path of the file that the stager will use to write all warnings and error messages to.C:\StagedSite\logs\
m_SourceHostThe name of the host server. As the stager must be executed on the source MCMS server, the value is typically http://localhost. But for sites with map channel names to host header turned on, you can specify the host name instead (e.g. http://www.tropicalgreen.net).http://www.tropicalgreen.net
m_UserAgentAllows you to specify the value of the UserAgent HTTP header, which identifies the browser version and platform of the client. This accommodates sites that are rendered differently for different client platforms or browsers.Mozilla/4.0 (compatible MSIE 6.0 Windows NT 5.1)
m_StageAsUserThe account that will be used to retrieve all MCMS objects from the repository. Restricting the access rights of the ‘Stage As’ user will limit the stager’s scope. Equivalent to the Stage As User field of Site Stager, minus the domain name, which is defined separately here.StagerUser
m_StageAsPwdThe password of the ‘Stage As’ user account. Equivalent to the User Password field of Site Stager.StagerPassword
m_StageAsDomainThe domain of the ‘Stage As’ user account.localmachine
m_DoNotExportHiddenItemsA flag to indicate whether or not hidden files and channels will be staged as well. A value of false stages hidden files.True
m_DefaultFileNameThe name of the file generated for channel rendering scripts and default postings. Equivalent to the Default Filename field in Site Stager.default
m_DefaultFileExtensionThe file extension of all generated postings. Equivalent to the Default Extension for HTML files field in Site Stager.htm
m_HttpHeaderThis is an additional header that will be added to the request to allow the application to behave differently if the site is hit by the stager or by a browser. For example, you could replace active scripts that work only on dynamic pages with content that will work on a static copy.DotNetSiteStager
m_CodePageThe default encoding used to download a static version of each page. If your site uses different character sets (for instance, if it is a multilingual site), you may define a different code page.UTF-8
m_BaseUrlThe RobotMetaTag inserted in all template files injects a <base> tag into all postings. If you are planning to stage the files to a different host from the source, such as when generating files from http://www.tropicalgreen.net to http://tropicalgreen, you could set this value to http://tropicalgreen.http://tropicalgreen

As the behavior of the methods within the class depends on the values of these settings, let’s declare all of them as class variables. We will also declare an ArrayList object for storing attachment URLs, a CmsApplicationContext variable for working with the MCMS PAPI and a NetworkCredential object for downloading pages later. Add the following code above the Main() method:

private static string m_LogFile;
						private static string m_StageAsUser;
						private static string m_StageAsPwd;
						private static string m_StageAsDomain;
						private static bool m_DoNotExportHiddenItems;
						private static string m_StartChannel;
						private static string m_SourceHost;
						private static string m_UserAgent;
						private static string m_HttpHeader;
						private static string m_DefaultFileName;
						private static string m_DestinationDirectory;
						private static string m_DefaultFileExtension;
						private static string m_CodePage;
						private static string m_BaseUrl;
						private static string m_LocalBaseUrl;
						// ArrayLists for handling attachments
						private static ArrayList m_AttachmentUrls;
						// CmsApplicationContext for working with the MCMS PAPI
						private static CmsApplicationContext cmsContext;
						// Network credentials for downloading pages
						private static NetworkCredential m_credentials;
[STAThread]
static void Main(string[] args)
{
  . . . code continues . . .
}

					  

Our application will handle two types of files:

  • ContentPage: Postings and channel rendering scripts

  • ContentBinary: Images, Office documents, and other attachments

We will declare an enumeration named EnumBinary to identify each of these file types. Add the following code above the Main() routine.

// Have enum values for each file type handled
enum EnumBinary
{
  ContentBinary,
  ContentPage
}

Within the Main() routine, we will initialize each of the variables declared above. Go ahead and change their values. You will at the very least have to set the ‘Stage As’ user, domain, and password as well as the start channel and the destination directory to match the environment of your computer.

[STAThread]
static void Main(string[] args)
{
  // Set parameter values
						m_LogFile = @"c:\StagedSite\logs\";
						m_StageAsDomain = "localmachine";
						m_StageAsUser = "StagerUser";
						m_StageAsPwd = "StagerPassword";
						m_DoNotExportHiddenItems = true;
						m_StartChannel = "/Channels/www.tropicalgreen.net/";
						m_SourceHost = "http://www.tropicalgreen.net";
						m_UserAgent = "Mozilla/4.0 (compatible MSIE 6.0 Windows NT 5.1)";
						m_HttpHeader = "DotNetSiteStager";
						m_DefaultFileName = "default.htm";
						m_DestinationDirectory = @"c:\StagedSite\";
						m_DefaultFileExtension = "htm";
						m_CodePage = "UTF-8";
						m_BaseUrl = "http://tropicalgreen";
						m_LocalBaseUrl = m_BaseUrl;
						m_AttachmentUrls = new ArrayList();
}

A better idea would be to store the settings within an Application configuration file (app.config). In this way, you don’t have to re-compile the code each time any of the settings changes. For simplicity, we will leave them as class variables in this example.


Recording Messages to a Log File

As the stager progresses through its job, it may encounter exceptions when staging certain URLs. Instead of terminating the entire process, we will trap all exceptions and write all error messages to a log file. The location of the log file is set in the m_LogFile variable defined earlier.

The helper function that writes messages to the log file is shown below. Add it directly below the Main() method.

private static void WriteToLog(string message)
{
  Console.WriteLine(message);
  FileStream fsLog = new FileStream(m_LogFile, FileMode.Append,
                                    FileAccess.Write);
  StreamWriter wLog = new StreamWriter(fsLog);
  wLog.WriteLine(message);
  wLog.Flush();
  wLog.Close();
  fsLog.Close();
}

For audit purposes, we will record the current date and time as well as the settings that we defined earlier in the log file. Within the Main() routine, add the following code:

[STAThread]
static void Main(string[] args)
{
  . . . code continues . . .
  // Ensure that the logfile directory is created
						Directory.CreateDirectory(m_LogFile);
						// Generate the name of the log file (in the format log_yyyyMMdd_HHmm.txt)
						if(!m_LogFile.EndsWith("\\"))
						{
						m_LogFile = m_LogFile + "\\";
						}
						m_LogFile = m_LogFile + "log_" + DateTime.Now.ToString("yyyyMMdd_HHmm")
						+ ".txt";
						System.Text.StringBuilder sb = new System.Text.StringBuilder();
						string newLine = System.Environment.NewLine;
						// Write the timestamp to the log file
						sb.Append(DateTime.Now.ToString("dd MMM yyyy HH:mm") + newLine);
						sb.Append("----------" + newLine);
						// Write the settings to the log file
						sb.Append("Log File = " + m_LogFile + newLine);
						sb.Append("Stage As Domain = " + m_StageAsDomain + newLine);
						sb.Append("Stage As User = " + m_StageAsUser + newLine);
						sb.Append("Do No Export Hidden Items = " + m_DoNotExportHiddenItems
						+ newLine);
						sb.Append("Start Channel = " + m_StartChannel + newLine);
						sb.Append("HTTP Host = " + m_SourceHost + newLine);
						sb.Append("User Agent = " + m_UserAgent + newLine);
						sb.Append("HTTP Header = " + m_HttpHeader + newLine);
						sb.Append("Default File Name = " + m_DefaultFileName + newLine);
						sb.Append("Destination Directory = " + m_DestinationDirectory + newLine);
						sb.Append("Default File Extension = " + m_DefaultFileExtension + newLine);
						sb.Append("Base Url = " + m_BaseUrl + newLine);
						sb.Append("Code Page = " + m_CodePage + newLine);
						WriteToLog(sb.ToString());
}

Other -----------------
- Microsoft Content Management Server : Staging Static Pages - Site Stager in Brief
- BizTalk 2010 : WCF LOB SQL Adapter - Consuming ASDK SQL Adapter in Visual Studio (part 2)
- BizTalk 2010 : WCF LOB SQL Adapter - Consuming ASDK SQL Adapter in Visual Studio (part 1)
- Windows Server 2008 Server Core : Renaming a File with the Ren and Rename Commands, Sorting File Content with the Sort Utility
- Windows Server 2008 Server Core : Moving Files and Renaming Files and Directories with the Move Command, Recovering Lost Files with the Recover Utility
- Windows Server 2008 : Moving Accounts with dsmove, Removing Objects with dsrm, Retrieving Information about Objects with dsquery
- Windows Server 2008 : Modifying Accounts with dsmod
- Designing and Configuring Unified Messaging in Exchange Server 2007 : Unified Messaging Shell Commands
- Designing and Configuring Unified Messaging in Exchange Server 2007 : Monitoring and Troubleshooting Unified Messaging (part 3) - Event Logs
- Designing and Configuring Unified Messaging in Exchange Server 2007 : Monitoring and Troubleshooting Unified Messaging (part 2) - Performance Monitors
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server