Creating an Object to Maintain Postings
The ASP.NET Web service will be able to load and maintain postings. To do this we will create a class called LightweightPosting. In Visual Studio .NET, right-click on the project McmsAuthoringWebService and add a new class called LightweightPosting. Add the namespaces highlighted below:
using System;
using System.IO;
using System.Security.Principal;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.ContentManagement.Publishing;
namespace McmsAuthoringWebService
{
/// <summary>
/// Summary description for LightweightPosting
/// </summary>
public class LightweightPosting
{
. . . code continues . . .
}
}
The LightweightPosting class needs to contain several public variables:
#region Declarations and public variables
/// <summary>
/// The MCMS name of the posting
/// </summary>
public string Name;
/// <summary>
/// The MCMS Display name of the posting
/// </summary>
public string DisplayName;
/// <summary>
/// The MCMS Path of the posting
/// </summary>
public string Path;
/// <summary>
/// The GUID of the posting
/// </summary>
public Guid ID;
#endregion
To retrieve the CmsContext for the current user in Update mode, we will define a helper property on the class that returns just such a CmsContext. You’ll also notice that, because we require the object to be in Update mode, we are using the CmsApplicationContext class instead of CmsHttpContext.
#region MCMS Current Context
/// <summary>
/// Declare the cms context as a private variable so we
/// don't need to load it every time we access the property.
/// </summary>
private CmsContext _CurrentCmsContext;
/// <summary>
/// Get the current MCMS context in update mode.
/// </summary>
private CmsContext CurrentCmsContext
{
get
{
// Do we need to load the cmscontext?
if (_CurrentCmsContext == null)
{
// Create the new application context
CmsApplicationContext cmsContext = new CmsApplicationContext();
// We need to get the identity of the current user
WindowsIdentity ident = System.Web.HttpContext.Current.User.Identity
as WindowsIdentity;
// Authenticate into update mode
cmsContext.AuthenticateUsingUserHandle(ident.Token,PublishingMode.Update);
// Set the private variable
_CurrentCmsContext = cmsContext;
}
// Return the private variable
return(_CurrentCmsContext);
}
}
#endregion
This process of authenticating the CmsApplicationContext by calling the method AuthenticateUsingUserHandle() will only work when using Windows authentication.
|
Next we’ll define a property to load the Microsoft.ContentManagement.Publishing.Posting object, which corresponds to the current LightweightPosting object. This property will use the Microsoft.ContentManagement.Publishing.Searches class to load the posting, and it will throw an exception if the posting is not found:
#region Related MCMS Posting
/// <summary>
/// The MCMS Posting object private variable
/// (so we don't need to reload it when accessing the property)
/// </summary>
private Posting _Posting;
/// <summary>
/// The MCMS Posting object that corresponds to this Lightweight posting.
/// It loaded from the Path property
/// </summary>
private Posting CmsPosting
{
get
{
// Is the posting object set?
if (_Posting == null)
{
// Make sure the Guid for the posting is set
if (this.Path != null)
{
// Perform a search to get the posting object by path
_Posting = (Posting)CurrentCmsContext.Searches.GetByPath(this.Path);
// Verify the posting object was found
if (_Posting == null)
{
throw new Exception("The posting could not be found at path '"
+ this.Path + "'");
}
}
}
// Return the posting object
return(_Posting);
}
set
{
_Posting = value;
}
}
#endregion
To access the custom properties for the current posting, we will add the CustomProperties property to the LightweightPosting class, which will, if necessary, load a LightweightCustomPropertyCollection:
#region Property - Custom Properties
/// <summary>
/// The lightweight custom properties private variable
/// </summary>
private LightweightCustomPropertyCollection _CustomProperties;
/// <summary>
/// Get/Set the lightweight custom properties collection.
/// If _CustomProperties is null the custom properties will be
/// loaded by the current CmsPosting
/// </summary>
public LightweightCustomPropertyCollection CustomProperties
{
get
{
// Have the custom properties been loaded?
if (_CustomProperties == null)
{
// Instantiate the new lightweight custom properties
_CustomProperties = new LightweightCustomPropertyCollection();
// Load by current MCMS Posting
_CustomProperties.Load(this.CmsPosting);
}
// return the collection
return(_CustomProperties);
}
set
{
// set the local variable
_CustomProperties = value;
}
}
#endregion
Similarly to how we loaded the custom properties for the posting, we will now add the Placeholders property, which instantiates a LightweightPlaceholderCollection and loads it for the current MCMS posting:
#region Property - Placeholders
/// <summary>
/// The lightweight Placeholders private variable
/// </summary>
private LightweightPlaceholderCollection _Placeholders;
/// <summary>
/// Get/Set the lightweight Placeholders collection.
/// If _Placeholders is null the Placeholders will be
/// loaded by the current CmsPosting
/// </summary>
public LightweightPlaceholderCollection Placeholders
{
get
{
// Have the Placeholders been loaded?
if (_Placeholders == null)
{
// Instantiate the new lightweight Placeholders
_Placeholders = new LightweightPlaceholderCollection();
// Load by current MCMS Posting
_Placeholders.Load(this.CmsPosting);
}
// return the collection
return(_Placeholders);
}
set
{
// set the local variable
_Placeholders = value;
}
}
#endregion
The LightweightPosting class will also contain the Template property, which will hold the LightweightTemplate that the posting is using. We instantiate a LightweightTemplate and populate it from the current MCMS posting’s template:
#region Property - Templates
/// <summary>
/// The lightweight Template private variable
/// so the object is not loaded every time
/// the property is requested
/// </summary>
private LightweightTemplate _Template;
public LightweightTemplate Template
{
get
{
// check if the template is already loaded
if(_Template == null)
{
// Instantiate the new lightweight posting class
_Template = new LightweightTemplate();
// Load the lightweight template
// by the current MCMS postings template
_Template.Load(this.CmsPosting.Template);
}
// return the private variable
return(_Template);
}
set
{
// Set the private variable
_Template = value;
}
}
#endregion
Now add in the constructor logic to populate the Name, DisplayName, Path, and ID of LightweightPosting from an MCMS posting object. We will initialize the CustomProperties, Placeholders, and Template properties by calling the ToString()
method, which implicitly instantiates the objects by calling the
default constructor. Once the objects are initialized, they will be
populated. After that, we can dispose of the CurrentCmsContext object as we won’t need it any more.
#region Constructor - Instantiate by MCMS Posting Object
/// <summary>
/// Instantiate and load the LightweightPosting
/// object from an MCMS MCMS Posting object.
/// </summary>
/// <param name="_Posting">MCMS Posting object</param>
public LightweightPosting(Posting _Posting)
{
this.Name = _Posting.Name;
this.DisplayName = _Posting.DisplayName;
this.Path = _Posting.Path;
this.ID = new Guid(_Posting.Guid);
// Initialize the properties
this.CustomProperties.ToString();
this.Placeholders.ToString();
this.Template.ToString();
// Dispose the context
this.CurrentCmsContext.Dispose();
}
#endregion
Now we have defined the
properties to load MCMS objects such as the template, placeholders, and
custom properties, we will add the Save() method to save any changes to the property values or collections to MCMS. The Save() method checks to see if DisplayName or Name have been changed and if they have it will overwrite the values of the Posting object. It then calls the Save() method on the Placeholders property to save the value of each placeholder. The posting is then submitted and the transaction is committed.
#region Save
/// <summary>
/// Save the Lightweight posting object's properties
/// and collections to the MCMS database.
/// </summary>
public void Save()
{
// Check if the display name has changed
if (this.DisplayName != this.CmsPosting.DisplayName)
{
// it has changed - apply the change to the posting object
this.CmsPosting.DisplayName = this.DisplayName;
}
// Check if the posting name has changed
if (this.Name != this.CmsPosting.Name)
{
// it has changed - apply the change to the posting object
this.CmsPosting.Name = this.Name;
}
// Save the placeholders collection passing in the current posting
this.Placeholders.Save(this.CmsPosting);
// Can we submit the posting?
if (this.CmsPosting.CanSubmit)
{
// Yes, submit it
this.CmsPosting.Submit();
// Commit the transaction
this.CurrentCmsContext.CommitAll();
}
// Dispose of the current CMS Context
this.CurrentCmsContext.Dispose();
}
#endregion
The LightweightPosting object should now look like this:
After
finishing the previous steps, we have successfully created the business
layer. Now build the entire solution and verify that there are no
compilation errors.