Microsoft Corporation
October 2002
Applies to:
Microsoft Content Management Server (MCMS) 2002
Summary: Learn how to use Microsoft Content Management Server (MCMS) 2002 as a consumer or publisher of XML Web services. (28 printed pages)
Contents
Introduction
Business Benefits
Publishing Web Services in MCMS 2002
Consuming Web Services in MCMS 2002
Architecture and Design Considerations
Examples
Conclusion
Additional Resources
Introduction
MCMS provides an enterprise Web content management system that can be used to manage and publish content for Internet, intranet, and extranet Web applications. Web services offer a way for distributed applications to communicate, regardless of implementation platform or geographical location. With the power of Web services, the Internet becomes a giant distributed database that can be used to increase the impact and effectiveness of Web sites.
When coupled with the MCMS 2002 platform, Web services can be used within two broad scenarios:
- To syndicate content managed within MCMS to other applications regardless of platform or physical location.
- To aggregate content stored within remote applications to be displayed as part of the MCMS–managed Web site, and to provide automatic maintenance of site content from the remote data sources.
From a technical perspective, these two scenarios are distinguished by whether the MCMS system will be the consumer or publisher of Web services. Of course, it is possible that a single MCMS system will fulfill both roles should the solution require it. However, since the two scenarios can be treated distinctly, this paper will discuss the business benefits and architectural considerations of each separately. Examples are also included to provide guidance and code samples for both scenarios.
Business Benefits
The integration of Microsoft Content Management Server 2002 and XML Web services will empower businesses to integrate their Web sites with other applications without having to wrestle with many of the restrictions placed by earlier technologies. This will create the ability to build powerful distributed solutions spanning internal users, business partners, and/or customers, while keeping implementation costs under control.
Given the increasing complexity of today's Web sites, solutions managed within MCMS can rarely be treated as "standalone" applications. Until now, the fundamental usage model for MCMS was to enable the flow of content from a source (knowledge workers) to a destination (Web site browsers). Clearly, many of today's Web sites have requirements which exceed that model. Businesses want the ability to treat their Web site content as part of a larger ecosystem across their organization and even throughout the Internet.
A common approach to solving this problem is to replicate data across systems, commonly done as a batch process running at a fixed time interval. However, this approach causes duplication of data across systems, and therefore creates a disconnection between the data being used by the destination applications and the up-to-date data held by the source system. Also, as these processes multiply, they often become very complex to manage and prone to failure.
Of course, the need for real-time interaction between applications is not a new one. Technologies like DCOM and CORBA have been designed to allow remote procedure calls between distributed applications. However, those technologies also have restrictions which often limit their reach. By using Web technologies and an open standards-based design, Web services bring improvements around platform independence, network security, complexity of implementation, and more. Also, the fundamental technologies and protocols that can be used to build Web services (HTTP, XML, ASP.NET and so on) make it a natural fit for MCMS, which is based upon many of the same concepts. Although there are several ways to implement Web services on the Microsoft platform, this paper will focus on using the inherent support of Web services in ASP.NET. Since MCMS 2002 is also fully integrated with ASP.NET, it is possible to leverage the power of Visual Studio .NET and the .NET Framework to facilitate the development of Web services in MCMS. As a result, developers already familiar with building Web services in a .NET environment can build upon that knowledge using this paper in order to extend MCMS using Web services. Conversely, developers that are new to Web services can make use of a wealth of existing resources on Web services and the .NET platform along with this paper to build solutions using MCMS and Web services. In addition, MCMS 2002 adds support for storing XML content. This fits very well with Web services, which encodes transmitted data using XML and the XML schema specification. Using MCMS with Web services will facilitate:
- The re-use of content in the system by other applications, rather than just Web site browsers.
- Management and publishing of content in the system that originates from sources other than knowledge workers.
Each scenario for using MCMS with Web services can bring a unique set of benefits to an organization.
Publishing Web Services in MCMS 2002
By publishing Web services in an MCMS system, businesses will significantly enhance their ability to syndicate the content managed within the system to a wide-range of consumers. Given the location and platform transparency afforded by Web services, MCMS–provided Web services can be consumed by any other Web, desktop, server, or mobile application built on any platform that can consume Web services.
.gif)
Figure 1. MCMS–provided Web services
Because Web services provide the ability to share a centralized data source, the syndication of content using MCMS and Web services allows organizations to ensure that its subscribers (Web service consumers) have access to accurate and up-to-date data. This will also allow companies to empower their content subscribers to re-use their content in a robust and automated fashion, without resorting to techniques such as "screen scraping" or manual cutting and pasting.
Furthermore, by providing a centralized data source, businesses will gain the ability to track the usage of the syndicated content. In addition to providing useful feedback, this could lead to potential revenue generating scenarios where the Web service consumers are charged a subscription fee.
By using MCMS to manage the content that is inputted into the system, the Web service(s) will automatically leverage the infrastructure provided by the system to create, manage, and publish content. Because of this, the content entered using the MCMS Web Author or Authoring Connector for Microsoft Word 2002 and published through a Web service will not be available as syndicated content until it has been approved for publishing through the workflow.
Given the wide reach of Web services and the pervasiveness of Web content, there is a multitude of potential applications for publishing Web services in MCMS. For example:
- A car manufacturer provides a Web service that shares the features, specifications, and description of the automobiles that it builds. This content is maintained within MCMS and displayed on the manufacturer Internet site. Car comparison and review sites, such as MSN Carpoint, can re-use that data on their pages by consuming the Web service. The car manufacturer regulates which sites use its content by requiring authentication when calling the Web service.
- A business news site manages and publishes stories on its Internet site using MCMS. The news site provides a Web service which provides headlines and hyperlinks to the related news stories pertinent to any given company. Businesses pay a subscription fee to consume the Web service and display the headlines on their intranet portal.
- A marketing employee frequently distributes Word documents that share content already published on their MCMS–maintained Web site. Since the content is published through a Web service, the employee can use a special Word template to prepopulate the document with the content found on the Web site.
Consuming Web Services in MCMS 2002
By consuming Web services in an MCMS system, companies will enhance their ability to enrich the content maintained and published by their knowledge workers with data aggregated from other applications, such as back-end systems. The Web services platform will allow aggregation from a wide range of sources, regardless of platform or location.
.gif)
Figure 2. Web services platform allows aggregation from wide range of sources
Consuming Web services in an MCMS Web site will allow businesses to provide a more unified experience for users browsing the site. By using Web services to share content, Web developers can present content from other systems in a controlled fashion. Rather than being linked to another site, or having the new content pop up in a new browser window, the user can be presented with all of the relevant data in one place without necessarily knowing the "true" source of the content. Web services and the .NET Framework make this automated and timely content aggregation possible without "screen scraping" or other complex implementation techniques.
By implementing a regular process, content on the MCMS maintained Web site can be created and updated automatically by consuming Web services from a back-end data source. Therefore, as the data on the back-end data source changes, the Web site will continuously be updated without knowledge worker interaction. This can be hugely beneficial, particularly if the volume of data being published is large. Notice that, although these pages are being maintained automatically by the synchronization process, it is also possible that the pages would also include unstructured, editorial content provided by knowledge workers. In this case, part of the page content would be maintained manually, while another part would be maintained automatically. The MCMS workflow could also be leveraged to require approval of manual, automatic, or both types of updates.
.gif)
Figure 3. MCMS workflow
It is also possible to provide greater control over the content being consumed. For example, the application might require the knowledge worker to choose a parameter in order to receive the correct content from the Web service. In another scenario, the knowledge worker might be given a choice to either accept the latest content from the Web service, or keep the previously downloaded content already stored in MCMS.
As with the publisher scenario, there is much potential for uses for the consumption of Web services in MCMS. For instance:
- A car comparison or review site, maintained in MCMS, wishes to include vehicle specifications and features with relevant articles on its site. Rather than maintain this information itself, the company consumes Web services provided by automobile manufacturers which provide that data.
- A company intranet human resources site is maintained within MCMS to manage its policy information, but needs to show users their pay stub information, held within SAP. To accomplish this, the Web developers consume a secured Web service and display the pay stub information within the context of their site.
- A company manages a complex set of back-end processes needed before new content is ready for publishing on the Web site using Microsoft BizTalk Server 2002. When the new content is ready, it is made available in a well-known XML schema using a Web service by BizTalk. An automated process on the MCMS consumes the Web service, and updates the Web site as needed.
Architecture and Design Considerations
This section will describe recommended architectural and design practices when using MCMS 2002 with Web services. In particular, the interfaces and interactions between MCMS and the Web services will be examined closely. General Web service design considerations that are most relevant to this discussion will also be raised, but will not be discussed in detail in this white paper.
Publishing Web Services in MCMS 2002
The high-level architecture and design used to publish Web services in MCMS is analogous to the generic architecture and design used to expose a back-end data repository using Web services. In general terms, the Web service developer designs an interface available to the consumer, and uses programmatic access to the data source to extract and return the relevant data to the consumer. In this case, MCMS acts as the data repository, storing loosely structured content. The developer will expose methods available from the Web service and use the MCMS Publishing API to retrieve data (typically placeholder content) from the system.
An important factor in implementing a Web service in MCMS is the design of the interface available to consumers, represented by its Web Service Description Language (WSDL) contract. The WSDL document contains method, parameter, and protocol information used by consumers to properly form the SOAP messages used to interact with the Web service.
There are two main approaches when designing a Web service interface to MCMS. The first approach can be referred to as the "horizontal" approach because it essentially mirrors parts of the MCMS Publishing API in your Web service WSDL. In other words, the consumers will be interacting with the Web service in Content Management Server terms such as channels, pages, and placeholders. The second approach can be called the "vertical" approach because it creates separation between the consumer and the MCMS system and presents an interface specific to the business domain. In this case, consumers will have an interface relative to their requirements and may be completely unaware of the underlying data repository.
The considerations in choosing an approach can be summarized in Table 1.
Table 1. Considerations in choosing an approach
| Interface Design | Advantages | Disadvantages |
| Horizontal Approach | Allows re-use of Web service code across MCMS applications.
May avoid the need to store/maintain a separate, structured data source. | Does not provide business domain abstraction; may be difficult to provide an appropriate interface to consumers.
Web service consumers are required to have knowledge of underlying MCMS data source. |
| Vertical Approach | Provides abstraction between consumer and data source; allows free design of interface according to business domain.
Web service consumers do not have knowledge of underlying MCMS data source. | Requires application-specific Web service code.
Will likely require a structured data source to map queries into MCMS data. |
While a certain design may borrow from both approaches, a key outcome of these decisions is whether there will be the need for a separate, structured data source. MCMS only provides structure to the content in terms of the channel hierarchy and the placeholders within a posting. A more structured data source is often necessary, particularly when using the "vertical" approach, in order to provide the appropriate structured queries to the Web service consumer. Posting metadata should not be queried in order to provide the desired interface because MCMS custom properties are not intended to fill the role of a proper structured data source. The Examples section of this white paper illustrates both interface design approaches.
If there is no need for a structured data source, then it is business as usual from a content input perspective. The published Web service can take advantage of the MCMS Web Author, Authoring Connector, and workflow to control data entry into the system, or it might use content that originated from a consumed Web service. However, these processes will be invisible to the published Web service application, which will just use whatever published data is available in the MCMS Content Repository.
On the other hand, if a structured data source is required, then this separate data source will be used to map queries into results from the MCMS Content Repository. Typically, the mapping is done by storing MCMS object GUIDs in the structured data source. This allows us to retrieve objects from MCMS by GUID, which is by far the most efficient method.
In a product-based scenario, an ideal fit as the structured data source is Microsoft Commerce Server 2002. Part of the functionality provided the Content Connector for Commerce Server add-in that ships with MCMS is to associate a Commerce Server product to an MCMS posting by storing the GUID posting as a product property. Methods exposed by the Web service can perform a specification search on the Commerce Server product catalog and then use the mapping to retrieve the appropriate content from MCMS as necessary. A major advantage gained in this scenario is that the Content Connector is designed to handle the synchronization of the mapping data between the two data sources.
In other scenarios, it may be necessary to introduce a custom structured data source, such as a custom Microsoft SQL Server application. If this is required, changes to the content in MCMS must be synchronized with the structured data source to ensure an accurate mapping between the two. One approach is to design a custom placeholder control which saves content to the structured data source, rather than the standard MCMS Content Repository. This is appropriate if the data is not also needed within MCMS (as posting custom properties, for example). Another approach is to leverage the extensible workflow events to copy data into the structured data source. In this case the data would be available both as metadata in MCMS and as structured data in the separate data source. In either case, the deletion of a posting in MCMS will need to trigger the removal of appropriate records in the structured data source.
.gif)
Figure 4. Custom structured data source and MCMS
Another important consideration when publishing Web services using MCMS 2002 is how to apply security to the Web service. In general, it is advisable to create any Web services in a separate Web application from the "main" Web application (containing MCMS templates, and so forth), so that different security settings can be applied to the MCMS Web site, and the Web services that it publishes. The key distinction to be made is whether you will want the Web service consumer's credentials to determine their access to MCMS objects (authorization), or whether all consumers can have the same authorization rights in MCMS.
If the Web service consumer's credentials must be used to determine their MCMS authorization rights, then the Web application should be configured to use Windows Integrated authentication in the application's Web.config file. In this case, the Web service itself will access MCMS objects using the CmsHttpContext.Current entry point. The Web service consumer must then use the SoapHttpClientProtocol.Credentials property to provide appropriate credentials that have rights in MCMS. The property can be populated using the CredentialCache.DefaultCredentials property (for the currently logged-in user), or by providing an instance of the NetworkCredential class. Of course, in this case the Web service itself must be coded in a way that is flexible enough to handle the various levels of authorization that may be provided to the authenticated user.
If all consumers can have a common set of authorization rights to MCMS, then the situation is simpler. If MCMS guest access is enabled, then the Web service can use either CmsHttpContext.Current or CmsApplicationContext.AuthenticateAsGuest() to gain access to MCMS. However, since guest access is set at the MCMS level (through the Server Configuration Application (SCA) and Site Manager), this will require that the Web site itself have guest access, even if a separate Web application is created. In these cases, a specific, non-guest user can be specified, and CmsApplicationContext.AuthenticateAsUser() can be used as an entry point. An advantage of using the CmsApplicationContext is that the "CmsAuthorizationModule" HTTP module can be removed from the Web.config file, providing increased performance. Also, note that although all Web service consumers may authenticate to MCMS as the same user, you can still provide an additional layer of security at the IIS/ASP.NET level.
For more information on HTTP Security and ASP.NET Web services, refer to the resources section at the end of this document.
In addition, there are also several general design and implementation factors for Web services that must also be taken into consideration. Fortunately, the .NET platform has been designed with many of these tasks in mind and provides built-in support to reduce development effort. The topics mentioned here are described in greater detail in resources listed at the end of the white paper.
WSDL: As discussed earlier, a WSDL document is required to describe the methods and parameters exposed by the Web service. By using the [WebMethod] attribute of ASP.NET, the platform will automatically generate the WSDL needed for by Web service consumers.
Performance: From an MCMS perspective, use normal performance best practices when using the Publishing API, such as not looping through large object collections or using custom property searches unless necessary. There are also several general performance factors, such as caching and synchronous/asynchronous invocation. The ASP.NET platform provides built-in support for all of these aspects.
Consuming Web Services in MCMS 2002
Because templates in MCMS 2002 are ASPX files, it is possible to consume a Web service in a template using the same methodology as any other ASP.NET page. While this guarantees that the latest data from the Web service is being shown to the browsers, it may cause performance problems if the page sees heavy traffic, and may also be unnecessary if the data retrieved from the Web service does not change frequently. In addition, knowledge workers on the site that consumes the Web service will not have the opportunity to control if the "foreign" content is shown on the site. A superior approach is to make a copy of the data into an MCMS placeholder, thereby eliminating the need to invoke a Web service upon every page request. This section will address considerations for designing around this approach.
If data will not be pulled from the Web service upon every page request, a strategy must be devised to synchronize the data between MCMS and the Web service. Depending on the application requirements, the synchronization may use a regular process that regularly updates the data automatically, or it may be tied to a manual content update process through the MCMS Web Author.
An application designer would choose the polling approach if the content should be created or updated from the Web service on a regular interval. For this to work, an automated process must be able to determine what queries to make to the Web service and use business logic to translate the returned data into updates that must be made on the MCMS site. The synchronization is carried out by a console application (EXE) that accesses the Web service and uses the MCMS Publishing API to update the Web site. Since one of the goals of this approach is likely to avoid manual intervention, the synchronization application could also approve any new or modified objects as necessary. The application can then be executed on a timed interval using the Windows Task Scheduler.
.gif)
Figure 5. Synchronization carried out by console application (EXE) that accesses Web service and uses MCMS Publishing API to update Web site
To grant more control to the knowledge worker during the process, a custom MCMS placeholder control can be used. This placeholder control will override the default load/save behavior depending on the current MCMS mode. For example, the author may need to specify parameters (input using the placeholder authoring controls) to pass to the Web service in order to retrieve the appropriate content. In other cases, a check box may be provided by the custom placeholder to allow the author to choose whether or not to accept the latest content consumed from the Web service.
.gif)
Figure 6. Authoring scenario
.gif)
Figure 7. Published scenario
Depending on the format of the data being received from the Web service, the type of MCMS placeholder used to store the content must be chosen. In addition, the content must be formatted to fit within the look and feel of the consumer Web site. The following table summarizes common options for the data format.
Table 2. Common options for data format
| Data Format | Placeholder Type | Formatted By |
| Text | HTML | Consumer template or custom placeholder control using HTML tags or styles |
| XHTML | HTML | Publisher or consumer using HTML tags or styles |
| XML | XML | Template or custom placeholder control likely using XSL transformation |
Once again, there are other general design factors involved with consuming Web services. Similar to the publisher scenario, these factors are handled elegantly using the .NET platform.
Proxy: In order for the application to interact with the remote application seamlessly, a local proxy must be created. However, when using Visual Studio .NET, using the Add Web Reference command will automatically parse the Web service's WSDL and create a functional proxy class.
Error Handling: Since the consumer cannot guarantee the availability of the remote Web service, it must be prepared for scenarios where the data cannot successfully be retrieved. By using the Timeout property on the proxy class and the inherent exception handling of the .NET platform, it is possible to gracefully detect and react to these error conditions.
Examples
Since Web services are such a broad tool for integrating applications, there are many scenarios in which they could be used within an MCMS solution. In this section, we will look at several examples with the purpose of illustrating how to apply the concepts discussed in this white paper. The examples shown will use hypothetical scenarios in the video game industry, using the Microsoft Xbox game console and Xbox.com.
Code excerpts are written in Microsoft Visual C#. For simplicity, the code presented is designed to demonstrate the concepts and therefore does not have the level of error handling necessary for a production application.
Publishing a Simple Web Service
Scenario
Suppose that the Xbox.com team would like to share content maintained on the site in MCMS by publishing a Web service. For starters, they will cater to internal users who already have knowledge of the site structure, in order to allow them to extract placeholder content from pages within the site.
Design
To enable this, they will publish a Web service called XBoxWebService that exposes a method called RetrievePlaceholderText. The method will take an MCMS posting path and HTML placeholder name as parameters. If the placeholder is found successfully then the text within the placeholder is returned. If not then an empty result is returned.
This example will illustrate the fundamentals of publishing a Web service that shares data from MCMS. Notice that it is also an example of a "horizontal" interface because it provides functionality using a direct mapping to the Publishing API. Therefore, the Web service code used could be used for any MCMS site, regardless of the business domain, but effective use requires that the consumer have knowledge of the site structure.
Implementation
Start by creating a MCMS Web service project as illustrated in the following figure.
.gif)
Figure 8. New MCMS Web service
Now, we can create a Web service called XBoxWebService.asmx that will contain our Web service class. To gain shorthand access to the MCMS Publishing API, we will add the appropriate references at the top of the file. We will use the CmsApplicationContext object, which is the main Publishing API object for applications, which do not have HTTP context such as this one. We will assume that the Web service can authenticate to MCMS as the default guest user. Because the RetrievePlaceholderText method just mirrors functionality provided by the Publishing API, we can use the following code for the method:
[WebMethod]
public string RetrievePlaceholderText(string path, string placeholderName)
{
// Retrieve CMS application context and login.
CmsApplicationContext cmsContext = new CmsApplicationContext();
cmsContext.AuthenticateAsGuest();
// Need a try clause in case a channel is returned.
try
{
Posting targetPosting =
(Posting)cmsContext.Searches.GetByPath(path);
return GetTextFromPlaceholder(targetPosting, placeholderName);
}
catch
{
return String.Empty;
}
}
private string GetTextFromPlaceholder(Posting targetPosting, string
placeholderName)
{
if (targetPosting != null)
{
HtmlPlaceholder targetPh =
(HtmlPlaceholder)targetPosting.Placeholders[placeholderName]);
return (targetPh != null ? targetPh.Text : String.Empty);
}
else
{
return String.Empty;
}
}
Adding a Structured Data Source
Scenario
Rather than requiring knowledge of the underlying MCMS system, suppose the Xbox.com team would like to extend services to external Xbox fan sites. Specifically, they would like to provide the ability for consumers to query for a list of titles being released during a particular month and to retrieve the description of a game by providing its title.
Design
In this scenario, we will need a "vertical" interface, which abstracts the underlying MCMS data repository. We will assume that we have one template for games, which contains custom properties indicating the game release date. Notice that we could implement this by crawling the system using the Publishing API and returning the appropriate results. However, a superior approach is to introduce a proper structured data source in order to provide efficient queries.
For simplicity, we will design this application to use a simple Microsoft SQL Server database, which contains a single table GameTitles. The table stores metadata about the game (GameTitle, ReleaseMonth, ReleaseYear) as well as the GUID corresponding to the game page's posting within MCMS. The data will be synchronized between MCMS and SQL Server using the workflow extensibility events.
Once the structured data source is in place, we will add two methods to the published Web service. The RetrieveGamesByMonth method will query the structured data source for game titles released within a particular month. The RetrieveGameDescription method will take a game title as input and use the structured data source to map to the appropriate MCMS posting.
Implementation
The first task will be to ensure the data sources are synchronized. We will write a handler in global.asax for the Approved event raised by the Publishing API that will retrieve the appropriate data from the posting, and perform and insert or update on the SQL Server table. The following event handler assumes that the PostingEventsModule has been registered with the name CmsPosting in web.config.
For guidance on handling MCMS 2002 workflow events, refer to the product documentation.
public void CmsPosting_Approved(Object sender, ChangedEventArgs e)
{
// Retrieve the posting that was approved.
Posting thisPosting = (Posting)e.Target;
// Attempt to get the custom properties with the release date
// for the game.
CustomProperty releaseMonthProp =
thisPosting.CustomProperties["Release Month"];
CustomProperty releaseYearProp =
thisPosting.CustomProperties["Release Year"];
if ((releaseMonthProp != null) && (releaseYearProp != null))
{
// Assume the values are present and valid.
int releaseMonth = Int32.Parse(releaseMonthProp.Value);
int releaseYear = Int32.Parse(releaseYearProp.Value);
// Retrieve the unique identifier for this posting
// to use as the mapping key.
String postingGuid = thisPosting.Guid;
// Open the database connection using a string stored in
// web.config.
SqlConnection dbConn = new
SqlConnection(ConfigurationSettings.AppSettings["connstring"]);
// Check if the posting already has an entry in the database.
SqlCommand sqlCmd = new SqlCommand("", dbConn);
sqlCmd.CommandText = "SELECT COUNT(*) FROM GameTitles " +
"WHERE PostingGUID='" + postingGuid + "'";
dbConn.Open();
int numRecords = (int)sqlCmd.ExecuteScalar();
if (numRecords == 0)
{
// This is a new game so insert a new database entry.
sqlCmd.CommandText = "INSERT GameTitles VALUES " +
"('" + postingGuid + "', '" +
thisPosting.DisplayName +
"', " + releaseMonth + ", " + releaseYear + ")";
}
else
{
// The game already exists in the database, so update it.
sqlCmd.CommandText = "UPDATE GameTitles SET " +
"PostingGuid='" + postingGuid + "', " +
"GameTitle='" + thisPosting.DisplayName + "', " +
"ReleaseMonth=" + releaseMonth + ", " +
"ReleaseYear=" + releaseYear +
" WHERE PostingGuid='" + postingGuid + "'";
}
int numRows = sqlCmd.ExecuteNonQuery();
dbConn.Close();
}
}
In order to ensure that the data remains synchronized, the Xbox.com developers would also need to capture the posting deletion event and remove the appropriate record from the SQL Server table if necessary.
Next, we will write new methods in XBoxWebService.asmx. The first method, RetrieveGamesByMonth, will accept a month and year as parameters and return an array of strings with the titles of any games released that month. Notice how efficient this code can be using the structured data source rather than crawling through MCMS content.
[WebMethod]
public string[] RetrieveGamesByMonth(int month, int year)
{
// Prepare the SQL database used for structured data.
SqlConnection dbConn = new
SqlConnection(ConfigurationSettings.AppSettings["connstring"]);
SqlCommand sqlCmd = new SqlCommand("", dbConn);
ArrayList gamesList = new ArrayList();
// Query the data source, we'll assume that the input data is valid.
sqlCmd.CommandText = "SELECT GameTitle FROM GameTitles " +
"WHERE ReleaseMonth=" + month + " AND ReleaseYear=" + year;
dbConn.Open();
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
while (sqlReader.Read()) gamesList.Add(sqlReader.GetString(0));
dbConn.Close();
// Convert the ArrayList into a string array and return.
string[] gamesArray = new string[gamesList.Count];
gamesArray = (string[])gamesList.ToArray(typeof(string));
return gamesArray;
}
The other new Web service Method, RetrieveGameDescription, will perform a simple query to retrieve the mapped GUID to the MCMS posting of the game. It will then only need to perform a simple lookup into MCMS to retrieve the content stored in the ShortDescription placeholder.
[WebMethod]
public string RetrieveGameDescription(string gameTitle)
{
// Prepare the SQL database used for structured data.
SqlConnection dbConn = new
SqlConnection(ConfigurationSettings.AppSettings["connstring"]);
string guid;
SqlCommand sqlCmd = new SqlCommand("", dbConn);
// Query the data source for the requested game
// title's location within CMS.
sqlCmd.CommandText = "SELECT PostingGuid FROM GameTitles " +
"WHERE GameTitle='" + gameTitle + "'";
dbConn.Open();
guid = (string)sqlCmd.ExecuteScalar();
dbConn.Close();
// If we found the game, we will have a GUID returned.
if (guid != null)
{
// Retrieve CMS application context and login.
CmsApplicationContext cmsContext = new CmsApplicationContext();
cmsContext.AuthenticateAsGuest();
// Retrieve corresponding posting, assume GUID is
// valid posting.
Posting gamePosting =
(Posting)cmsContext.Searches.GetByGuid(guid);
return GetTextFromPlaceholder(gamePosting, "ShortDescription");
}
// Else the game wasn't found, so return an empty string.
else
{
return String.Empty;
}
}
Automated Web Site Maintenance by Consuming Web Services
Scenario
Suppose that the Xbox.com team has a partnership with another company, which sells strategy guides for Xbox games. Under the terms of the agreement, the company will publish a Web service that will allow the Xbox.com developers to access an XML-formatted list of the currently available strategy guides and their associated data. Using this data, the Xbox.com developers would like to have a "Strategy Guides" section of their MCMS Web site that is regularly updated with the latest information, but with no involvement from their knowledge workers.
Design
To enable automated site maintenance in the "Strategy Guides" section, we will implement a polling application, which will consume the Web service. Polling can be achieved by running the application regularly using the Windows Task Scheduler.
The application will consume the Web service and obtain an XML document representing the latest list of strategy guides. We will assume that all of the strategy guide postings on Xbox.com are held within a single channel, and that there is a field "ShortTitle" that we will use as a mapping key between the Web Service data and the MCMS data. As we iterate through the strategy guides in the XML, we will check if a corresponding posting in MCMS already exists. If so, we will update placeholder content with the latest data from the XML. If not, we will create a new page for the new strategy guide.
Since the developers do not want to require human interaction, we will assume that no manual approval is necessary for the new or updated content to be published. Therefore, the code will take care of any approval necessary.
Implementation
The code for this task can be contained in a console application. We will assume that the application can retrieve the strategy guide list from the Web service and also signal when it is successful. The code below shows how to update the content in MCMS automatically. For simplicity, the code will include minimal error checking.
static void Main(string[] args)
{
// Insert code here to retrieve XML representing the latest
// strategy guide
// list from the Web Service. Load into XMLDocument oDoc.
// . . .
// . . .
// Get the CMS application context and log in
Console.WriteLine("Logging on to CMS...");
CmsApplicationContext pCmsContext = new CmsApplicationContext();
pCmsContext.AuthenticateAsCurrentUser(PublishingMode.Update);
// Walk the XML processing each Strategy Guide node set
XmlNodeList oSGNodeList =
oDoc.SelectNodes("StrategyGuides/StrategyGuide");
foreach(XmlNode oSGNode in oSGNodeList)
{
// Use the 'short title' node for the posting name
XmlNode oTitleNode = oSGNode.SelectSingleNode("ShortTitle");
string postingName = oTitleNode.InnerText;
// Use the 'full title' for the posting description
XmlNode oLongTitleNode = oSGNode.SelectSingleNode("Title");
string description = oLongTitleNode.InnerText;
// Retrieve the channel where the Strategy Guide postings
// are held.
// Assume it exists.
Channel pSGChannel =
(Channel)pCmsContext.Searches.GetByPath("/Channels/XBox/
StrategyGuides");
// See if we already have a posting for this Strategy Guide...
Posting pExistingPosting =
(Posting)pSGChannel.GetByRelativePath(postingName);
if(pExistingPosting != null)
{
// If we do, update its XML and Description. This will
// leave any other placeholders intact.
Console.WriteLine("Updating posting for: {0}",
postingName);
XmlPlaceholder pXmlPlaceholder =
(XmlPlaceholder)pExistingPosting.Placeholders["SGInfo"];
pXmlPlaceholder.XmlAsString = oSGNode.OuterXml;
pExistingPosting.Description = description;
pExistingPosting.Approve();
}
else
{
// If not, we need to create the posting for this guide
Console.WriteLine("Creating posting for: {0}",
postingName);
Template pSGTemplate =
(Template)pCmsContext.Searches.GetByPath
("/Templates/XBoxTemplates/StrategyGuides");
if(pSGTemplate != null)
{
Posting pNewPosting =
pSGChannel.CreatePosting(pSGTemplate);
pNewPosting.Name = postingName;
pNewPosting.Description = description;
XmlPlaceholder pXmlPlaceholder =
(XmlPlaceholder)pNewPosting.Placeholders["SGInfo"];
pXmlPlaceholder.XmlAsString = oSGNode.OuterXml;
pNewPosting.Approve();
}
}
}
Console.WriteLine("Committing changes to CMS...");
pCmsContext.CommitAll();
// Finish by calling Web Service to indicate that the site
// was successfully updated.
// . . .
// . . .
}
Manually Consuming and Replicating Web Service Data
Scenario
Since there are many games available for the Xbox that are not published by Microsoft, suppose that the Xbox.com team would like to leverage a Web service published by a third-party game developer in order to retrieve game descriptions to be published on Xbox.com. For performance reasons, they would like to place a copy of the data into MCMS so that browsing page requests will not need to query the remote Web service. They would like to use a manual process in order to allow their content authors to selectively accept the latest description from the Web service as they edit other aspects of the page.
Design
To enable this functionality, we will design a custom placeholder that will manage the interaction between MCMS and the Web service. We will assume that the Web service will provide a RetrieveGameDescription method analogous to the one we have implemented. For simplicity, we will assume that the author will enter the name of the game to be retrieved and will have the option to replace an existing game description in MCMS. Therefore, the authoring control will be a composite control with a check box and a text box. Alternatively, we could have designed the game title input to be a drop-down with the available games from the developer, populated from another Web service call. The placeholder will output the text, which can be formatted by the template, so the presentation control will be a literal control.
Once the child controls are ready, we will need to implement the load and save functionality for our custom placeholder. When saving the content to MCMS, the placeholder will save the last game specified into a custom property. This will allow the author to update the game being downloaded without necessarily replacing the game description in MCMS. If the check box is also selected, indicating that the author wants to accept the data, the latest description from the Web service will be saved into the MCMS placeholder.
When loading the content, the placeholder will need to behave differently based on the current Web Author mode. If the page is being re-edited, we will just need to populate the name of the game being retrieved from the custom property where it is persisted upon save. This will show the author which game is currently selected. If the page is in "Presentation Unpublished" mode, then we will show the description of the game loaded directly from the Web service. This will allow the author to preview the latest description and decide if they want to update the copy stored in MCMS. Finally, if the page is viewed in "Presentation Published" mode, the content will be loaded from the presentation literal control stored in MCMS, avoiding any calls to the Web service.
Implementation
Our first step will be to implement the child authoring control for the custom placeholder. For this discussion, we will simply assume that we have an authoring control which contains check box and text box controls and will provide the appropriate get/set functionality. The check box value is available from the property ShouldUpdateCms (Boolean), and the text box value is represented by the property SelectedGameTitle (String).
Next, we will implement the custom placeholder class. For this example, we will assume the Web service is available from samplexboxdeveloper.com and publishes a method RetrieveGameDescription with the same signature as the one we implemented above. To call the Web service, we will use the "Add Web Reference" feature of ASP.NET to generate a client proxy.
First, we will look at how the placeholder will save content to MCMS as designed.
protected override void
SavePlaceholderContentsToCMS(WebAuthorPostingEventArgs e)
{
HtmlPlaceholder thisPlaceholder =
(HtmlPlaceholder)this.BoundPlaceholder;
// Retrieve the title from the authoring control and save
// into the custom property.
string gameTitle = authoringControl.SelectedGameTitle;
CmsHttpContext.Current.Posting.CustomProperties["Selected
Game"].Value =
gameTitle;
// If the author indicates they want to keep the content,
// save it into the CMS placeholder.
if (authoringControl.ShouldUpdateCms)
{
thisPlaceholder.Html = RetrieveDescFromWebService(gameTitle);
}
}
private string RetrieveDescFromWebService(string gameTitle)
{
// Instantiate the client proxy and call the Web Service.
com.samplexboxdeveloper.XBoxWebService contentService;
contentService = new com.samplexboxdeveloper.XBoxWebService();
return contentService.RetrieveGameDescription(gameTitle);
}
Now, here is the implementation for the loading of the content from MCMS, depending on the current mode.
protected override void LoadPlaceholderContentsFromCMS()
{
// Retrieve the custom property where we store the selected game.
CustomProperty gameSelectedProperty =
CmsHttpContext.Current.Posting.CustomProperties["Selected
Game"];
if (gameSelectedProperty != null)
{
// Retrieve the name of the previously selected game.
string gameSelected = gameSelectedProperty.Value;
WebAuthorContext webAuthorContext = WebAuthorContext.Current;
// If we're editing the page, populate the previously selected
// game
// into the textbox.
if (webAuthorContext.Mode == WebAuthorContextMode.AuthoringNew ||
webAuthorContext.Mode ==
WebAuthorContextMode.AuthoringReedit ||
webAuthorContext.Mode ==
WebAuthorContextMode.AuthoringReeditUpdate ||
webAuthorContext.Mode ==
WebAuthorContextMode.TemplatePreview)
{
authoringControl.SelectedGameTitle = gameSelected;
}
// If we're in unpublished mode, display the latest description
// from the Web Service.
else if (webAuthorContext.Mode ==
WebAuthorContextMode.PresentationUnpublished ||
webAuthorContext.Mode ==
WebAuthorContextMode.PresentationUnpublishedUpdate ||
webAuthorContext.Mode ==
WebAuthorContextMode.PresentationUnpublishedPreview)
{
if (!gameSelected.Equals(String.Empty))
{
string gameDesc =
RetrieveDescFromWebService(gameSelected);
if (gameDesc.Equals(String.Empty))
{
presentationControl.Text = "The game '" +
gameSelected +
"' does not have a description.";
}
else
{
presentationControl.Text = gameDesc;
}
}
else
{
presentationControl.Text = "Could not get the
selected game" +
" from the authoring control.";
}
}
// If we're in published mode, load the content from the CMS
// placeholder.
else if (webAuthorContext.Mode ==
WebAuthorContextMode.PresentationPublished)
{
// Retrieve the placeholder where we will store the data.
HtmlPlaceholder thisPlaceholder =
(HtmlPlaceholder)this.BoundPlaceholder;
presentationControl.Text = "From placeholder: " +
thisPlaceholder.Html;
}
}
}
Now that the custom placeholder is ready, it can be inserted into the game template, bound to an HTML placeholder definition, and used to selectively retrieve descriptions from the Web service.
Conclusion
This white paper described how using MCMS 2002 with Web services will enable a new level of integration between the Web sites of an organization and other applications within and/or outside the company network.
Using MCMS with Web services will enable Web sites where:
Content from the MCMS site can be syndicated to be re-purposed by another application.
Content from knowledge workers entered through Word and/or the MCMS Web Author is aggregated with relevant content retrieved from back-end systems through Web services. Web site content is regularly updated with an automated process, thereby synchronizing MCMS content with a separate data source with no necessary interaction from knowledge workers.
By leveraging the power of Web services, businesses can create an integrated vision of the Web applications, spanning their organization as well as their business partners.
Additional Resources