Introduction
The Content Studio server, that contains all the callable API:s that can be called to interact with Content Studio data, runs as a serviced application that must be reached via the .NET Remoting infrastructure. Remoting can be somewhat tricky to set up but once correctly configured, it is very convenient and highly reliable. If you are writing your application code in a Content Studio document, the Remoting is already set up correctly but in other applications ex. regular Windows or Console applications this must be done by the developer. This article describes two ways of doing this.
Channels
.NET Remoting is a way for two processes or application domains to communicate by sending serialized data between each other. For this purpose there must be a listenar (server) that accepts calls from a client through a dedicated channel. The channels available in .NET Remoting includes the Http and the Soap channels that are hosted in a Web server as well as the TCP channel and the IPC channel. The two latter is used by Content Studio and are secured, encryped and uses binary formatting when passing messages from and to each other. The TCP channel uses a TCP listener on a particular TCP port (9792) and is available on the same machine or between different trusted machines in the network. The IPC channel uses an underlying named pipe kernel object and is only accessible locally.
When you set up .NET Remoting for your application Content Studio must be installed on the development computer. In addition to this you need to set up a client channel that communicates with the listener that Content Studio server provides. You also need to specify which one of the Content Studio objects that should be accessed remotly. That includes all objects that make database calls or access the Web site's file system directly. Even though that is possible to use different channels for different objects it is wise to use the same channel for all of the objects, the only exception is the SessionManager object that must use the TCP channel. There is a bug (or a feature) in the IPC channel current implementation of .NET Remoting that tends to remember the first caller that created the client listener and since the SessionManager identifies the calling user by impersonating her this will cause identity problems under the IPC channel.
IMPORTANT
You must use the TCP channel when calling the SessionManager object, since the IPC
channel has an identity spoofing problem in impersonation operations in the current
implementation of the IPC channel.
Configuring your application
To configure an application for .NET remoting you typically add code in the constructor of your application or in the Main procedure if you are developing a console application.
In this way you ensure that the configuration process is performed only once per instance of your program. If you try to reconfigure
an application a RemotingException will occur. If you are building a class library (.DLL) you should put the configuration
methods in the calling application rather than in the class library itself. Remember that a class library runs in the
context of the calling process and any configuration code in the class library will affect the calling application directly.
For this reason there is no need to write code to configure .NET Remoting if your class library will be used from Content Studio
but this is not true for any test application you use for debugging your code.
Using a configuration file
The instructions below assumes that you have Content Studio installed locally
Using a configuration file is quite straight forward and requires the following steps (the sample below assumes that you are doing a regular console application that communicates with Content Studio).
- Create a new C# console application in Visual Studio 2005 (or later) and name it RemConfig.
- Add a reference to the CSServer5.dll assembly. Event though that CSServer is installed in the GAC it might not be listed in among the .NET assemblies available in Visual Studio. In that case you can browse to the installed .DLL and is by default located in the Program Files/Teknikhuset/Content Studio 5.0/CSServer sub folder.
- Add a new configuration file to your project and name it RemConfig.exe.config. In the properties window for the configuration, file you should set that Visual Studio should copy the file as a part of the building process since it must be located in the same folder as the resulting executable.
- Download the content of the either the the IPC configuration file or the TCP configuration file depending on whether you prefer to use the IPC or the TCP channel. You find a text version of these files in the links below in this section.
- Paste the content of one of these files into your configuration file and save it.
- Now you should be able to build an run your application.
In Program.cs class file, insert the following code that configures the .NET Remoting
channels to use and makes a call into the
using System;
using System.Runtime.Remoting;
using ContentStudio;
namespace RemConfig
{
class Program
{
static void Main(string[] args)
{
try
{
//Configure the Remoting client channels by using the configuration file
RemotingConfiguration.Configure("RemConfig.exe.config", true);
//Get a list of all registered sites in Content Studio
CSApplication csApp = new CSApplication();
using (System.Xml.XmlReader xrd = System.Xml.XmlReader.Create(csApp.SiteListStream(true)))
{
Console.WriteLine("Id\tName");
while(xrd.Read())
{
if (xrd.NodeType != System.Xml.XmlNodeType.Element)
continue;
if (xrd.Name == "cs_site")
{
Console.Write(xrd.GetAttribute("connectionid"));
Console.Write("\t");
Console.Write(xrd.GetAttribute("sitename"));
Console.WriteLine();
}
}
xrd.Close();
}
}
catch (RemotingException rex)
{
Console.WriteLine("ERROR: There is a problem with your remoting configuration!");
Console.WriteLine(rex.Message);
}
catch (Exception ex)
{
Console.WriteLine("ERROR: There was problem with the call!");
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}
Imports System
Imports System.Runtime.Remoting
Imports ContentStudio
Class Program
Public Shared Sub Main(args() As String)
Try
'Configure the Remoting client channels by using the configuration file
RemotingConfiguration.Configure("RemConfig.exe.config", True)
'Get a list of all registered sites in Content Studio
Dim csApp As New CSApplication()
Using xrd As System.Xml.XmlReader = System.Xml.XmlReader.Create(csApp.SiteListStream(True))
Console.WriteLine("Id" & vbTab & "Name")
While xrd.Read()
If xrd.NodeType = System.Xml.XmlNodeType.Element
If xrd.Name = "cs_site"
Console.Write(xrd.GetAttribute("connectionid"))
Console.Write(vbTab)
Console.Write(xrd.GetAttribute("sitename"))
Console.WriteLine()
End If
End If
End While
xrd.Close()
End Using
Catch rex As RemotingException
Console.WriteLine("ERROR: There is a problem with your remoting configuration!")
Console.WriteLine(rex.Message)
Catch ex As Exception
Console.WriteLine("ERROR: There was problem with the call!")
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub
End Class
You should remove or comment out the entries in the config file that configures objects you don't need. Some of the objects are rarely used and are mainly intended to be used by the Content Studio infrastructure.
Setting up a remoting listener in code
The instructions below assumes that you have Content Studio installed locally
Sometimes you might prefer to configure .NET Remoting programatically instead of through a config file. In this case you do not have to distribute the config file along with your application and you have full control over the configuration. To facilitate this we have prepared a C# class file that does all the dirty work for you. As with the configuration file you should remove or comment out the code that configures objects you don't need. Some of the objects are rarely used and are mainly intended to be used by the Content Studio infrastructure.
Follow the instructions that can be found in the former section but do not create a configuration file. Instead, add a new empty class to the project and name it ChannelConfigurator.cs. Now, overwrite the content of this new class file with the content of our code file that can be obtained in the link below. Before you can build your project you need to add a reference to the System.Runtime.Remoting .NET framwork assembly. All you have to do now is to create an instance of the ChannelConfigurator class and call the OpenChannel method.
Thus now your program will look something like this:
C#using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using ContentStudio;
namespace RemConfig
{
class Program
{
static void Main(string[] args)
{
try
{
//Configure the remoting channels by using the ChannelConfigurator class
ChannelConfigurator chan = new ChannelConfigurator(ChannelConfigurator.TransportProtocol.TCP);
chan.Configure();
//Get a list of all registered sites in Content Studio
CSApplication csApp = new CSApplication();
using (System.Xml.XmlReader xrd = System.Xml.XmlReader.Create(csApp.SiteListStream(true)))
{
Console.WriteLine("Id\tName");
while(xrd.Read())
{
if (xrd.NodeType != System.Xml.XmlNodeType.Element)
continue;
if (xrd.Name == "cs_site")
{
Console.Write(xrd.GetAttribute("connectionid"));
Console.Write("\t");
Console.Write(xrd.GetAttribute("sitename"));
Console.WriteLine();
}
}
xrd.Close();
}
}
catch (RemotingException rex)
{
Console.WriteLine("ERROR: There is a problem with your remoting configuration!");
Console.WriteLine(rex.Message);
}
catch (Exception ex)
{
Console.WriteLine("ERROR: There was problem with the call!");
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}
Imports System
Imports System.Runtime.Remoting
Imports ContentStudio
Class Program
Public Shared Sub Main(args() As String)
Try
'Configure the remoting channels by using the ChannelConfigurator class
Dim chan As New ChannelConfigurator(ChannelConfigurator.TransportProtocol.TCP)
chan.Configure()
'Get a list of all registered sites in Content Studio
Dim csApp As New CSApplication()
Using xrd As System.Xml.XmlReader = System.Xml.XmlReader.Create(csApp.SiteListStream(True))
Console.WriteLine("Id" & vbTab & "Name")
While xrd.Read()
If xrd.NodeType = System.Xml.XmlNodeType.Element
If xrd.Name = "cs_site"
Console.Write(xrd.GetAttribute("connectionid"))
Console.Write(vbTab)
Console.Write(xrd.GetAttribute("sitename"))
Console.WriteLine()
End If
End If
End While
xrd.Close()
End Using
Catch rex As RemotingException
Console.WriteLine("ERROR: There is a problem with your remoting configuration!")
Console.WriteLine(rex.Message)
Catch ex As Exception
Console.WriteLine("ERROR: There was problem with the call!")
Console.WriteLine(ex.Message)
End Try
Console.Read()
End Sub
End Class