OFFICIUM INSERVIO
Your reliable partner for your business software...
Sage 100 AppServer Context Objekt ermitteln / Get AppServer context object (ApplicationContext)
(alle Versionen/all versions)
Freitag, 6. Juni 2025
Anwendungsbeispiel / Example how to use
Minimalen "ApplicationContext" erzeugen / Create a minimal "ApplicationContext"
Übersicht / Overview
Es gibt in der Sage 100 drei verschiedene Klassen für den "ApplicationContext".
You will find three different classes for the "ApplicationContext" in the Sage 100.
Sagede.ApplicationServer.OfficeLine.ApplicationContext
Sagede.Shared.AppDesigner.ApplicationContext : IApplicationContext
Sagede.Shared.RealTimeData.Common.ApplicationContext : IDisposable, IApplicationContextCode snippets
Normalerweise ist es innerhalb von Quellcode , der ohnehin innerhalb eines Sage Applikationsserver Isolationsprozess läuft , mit folgendem Code möglich , den Applikationskontext und somit auch ein gültiges Authentifizierungstoken abzufragen. Dies betrifft den Sage Typen "Sagede.ApplicationServer.OfficeLine.ApplicationContext".
Normally, within source code that is already running inside a Sage application server isolation process, it is possible to query the application context, and thereby also a valid authentication token, using the following code. This applies to the Sage Type "Sagede.ApplicationServer.OfficeLine.ApplicationContext".
private Sagede.Core.Security.TokenAuthenticationTicket GetAuthenticationToken()
{
if (! (Sagede.ApplicationServer.OfficeLine.ServiceContext.Current.ApplicationContext is Sagede.ApplicationServer.OfficeLine.ApplicationContext appContext))
{
const string errorText = "2023020907: Kein Applikationskontext vorhanden!";
throw new InvalidOperationException(errorText);
}
return ( Sagede.Core.Security.TokenAuthenticationTicket ) appContext.Ticket;
}Es gibt jedoch auch Sage Code-Ereignisse oder sonstige Situationen , z.B. in eigenen isolierten Prozessen , in denen die Laufzeitumgebung sich anders darstellt und in denen stattdessen der Sage Typ "Sagede.Shared.RealTimeData.Common.ApplicationContext" benötigt wird.
Nachfolgend ein einfaches Code-Pattern, um in .net-Quellcode eine "Sagede.Shared.RealTimeData.Common.ApplicationContext" Instanz bereitzustellen , falls diese nicht auf andere Weise von Sage zur Verfügung gestellt wird.
However, there are also Sage code events or other situations, such as in custom isolated processes, where the runtime environment is different and the Sage type "Sagede.Shared.RealTimeData.Common.ApplicationContext" is needed instead.
Below is a simple code pattern to provide an instance of "Sagede.Shared.RealTimeData.Common.ApplicationContext" in .net source code , in case it is not made available by Sage through other means.
/// <summary>
/// Private static instance with the Sage ERP application contexts per Sage ERP mandator instance (collection key).<br/>
/// May be <c>null</c> !
/// </summary>
private static System.Collections.Concurrent.ConcurrentDictionary<Sagede.OfficeLine.Engine.Mandant , Sagede.Shared.RealTimeData.Common.ApplicationContext> _appContexts;
/// <summary>
/// Gets an Sage ERP application context for <paramref name="mandator"/>.<br/>
/// <br/>
/// Note, the application context instance will only created once per unique <paramref name="mandator"/> instance!<br />
/// <br />
/// <b>ATTENTION:</b> Any exception is <b>not</b> caught, but thrown!<br />
/// </summary>
/// <param name="mandator">Required: The Sage ERP mandator instance (German "<c>Mandant</c>").</param>
/// <returns>
/// Sage ERP application context or <c>null</c>, if not possible to determine.
/// </returns>
public static Sagede.Shared.RealTimeData.Common.ApplicationContext GetAppContext( Sagede.OfficeLine.Engine.Mandant mandator )
{
if ( mandator == null ) return null;
if ( _appContexts == null )
{
_appContexts = new System.Collections.Concurrent.ConcurrentDictionary<Sagede.OfficeLine.Engine.Mandant , Sagede.Shared.RealTimeData.Common.ApplicationContext>();
}
var exists = false;
if ( _appContexts.Any( p => ReferenceEquals( p.Key , mandator ) ) )
{
exists = true;
var existingContext = _appContexts.First( p => ReferenceEquals( p.Key , mandator ) ).Value;
if ( existingContext != null ) return existingContext;
}
var bag = new ParameterBag();
bag.StringValues["ApplicationId"] = "Abf"; // TODO: Consider a parameter!
bag.StringValues["ApplicationTitle"] = typeof( TODOYourClassNameHere ).FullName;
var newAppContext = Sagede.OfficeLine.Shared.RealTimeData.Client.SharedFunctions.GetApplicationInfo( mandator , bag );
newAppContext.Includes = new[] { "$children" , "SelectionPart" };
if ( exists )
{
_appContexts.TryRemove( mandator , out _ );
}
_appContexts.TryAdd( mandator , newAppContext );
return newAppContext;
}Anmerkung zum o.g. Code , wenn dieser ausschließlich innerhalb des Sage Applikationsservers benötigt wird:
Die eingangs erklärte Variante ist zwar die einfachste , um an diverse Sage Objekte zu gelangen , betrifft aber den speziellen Sage Applikationsserver Kontext , also eine andere Klasse!
Ein Sage Applikationsserver Isolationsprozess ist üblicherweise nur für einen einzigen konkreten Sage Mandanten und Benutzer zuständig. Insofern ist eine Verwaltung mehrere Mandanten-Instanzen nicht zwingend notwendig!
Note regarding the aforementioned code if the code is solely needed within the Sage Application Server:
The initially explained approach is then the simplest way to access various Sage objects , however , this applies to the special Sage Application Server context which is a different class!
A Sage application server isolation process is typically responsible for only a single specific Sage mandator instance and user. As such , managing multiple mandator instances is not strictly necessary!
Anwendungsbeispiel / Example how to use
var xRmProjektPos = new MySoftfolio.OfficeEdition.BusinessObjects.Dto.Position( this.Mandant , parameters.IdProjectPos );
if ( !string.IsNullOrWhiteSpace( parameters.IdProjectPosStatus ) )
{
xRmProjektPos.Status = parameters.IdProjectPosStatus.ToInt16();
}
if ( parameters.IdProjectPosContact != 0 )
{
xRmProjektPos.Ansprechpartner = string.Empty; // Will be loaded by save method using "AnsprechpartnerHandle" !
xRmProjektPos.AnsprechpartnerHandle = parameters.IdProjectPosContact;
}
xRmProjektPos.Save( this._appContext );Die Definition von "this._appContext" erfolgt einmalig im Konstruktor der Klasse, wie der nachfolgende Quellcode zeigt.
"this._appContext" is defined once in the constructor of the class, as the following source code demonstrates.
/// <summary>
/// Initializes a new instance of the <see cref="XrmManagerBase"/> class.
/// </summary>
/// <param name="mandator">The Sage ERP mandator instance (German "<c>Mandant</c>").</param>
/// <param name="appContext">Recommended: The Sage ERP application context, if available.</param>
protected XrmManagerBase( Sagede.OfficeLine.Engine.Mandant mandator ,
Sagede.Shared.RealTimeData.Common.ApplicationContext appContext )
{
this._mandator = mandator ?? throw new ArgumentNullException( "mandator" );
if ( appContext == null )
{
// Call the method which gets the Sage ERP application context
appContext = GetAppContext( this._mandator );
}
this._appContext = appContext;
}Minimalen "ApplicationContext" erzeugen / Create a minimal "ApplicationContext"
An vielen Stellen genügt für Funktionsaufrufe ein minimaler ApplicationContext , den man sich laut Sage wie folgt erzeugen kann.
Dies betrifft die Klasse "Sagede.Shared.RealTimeData.Common.ApplicationContext".
In many cases, a minimal ApplicationContext is sufficient for function calls, which, according to Sage, can be created as follows. This concerns the class "Sagede.Shared.RealTimeData.Common.ApplicationContext".
var applicationContext = new Sagede.Shared.RealTimeData.Common.ApplicationContext
{
ApplicationDate = DateTime.Today,
IsLegacyClient = false
}Wo steht der ApplicationContext seitens Sage zur Verfügung? / Where is the ApplicationContext provided by Sage?
In folgenden Situationen steht bereits seitens Sage ein ApplicationContext bereit.
In the following situations, an ApplicationContext is already available from Sage.


