Referencing the Epicor Server Host Name (Session Variable) within a Form Customization

This post is directed towards people, like myself, who have struggled trying to gain a clear understanding of how to reference a session within an Epicor form module customization in order to isolate the Epicor application server/host name.

Most of you already know how to do this, but some of us may find this information useful.

For my particular requirement, I wanted to write a log file back to the Epicor server whenever someone clicked on a certain checkbox on the Sales Order Entry form. Therefore, the customization was applied to:

App.SalesOrderEntry.SalesOrderForm

I started by instantiating a session reference within the top-level public class of the form module:

Note here that I have also reserved a string variable (“strEpiServer”) that I will use later to parse the server host name (you’ll see why as you read further).

With the _currSession reference instantiated, I now need to define it within the context of the form upon which I’m applying the customization. In my case, I did this task within the BeforeFieldChange form event, but the decision concerning when you might do this will depend on your specific needs:

_currSession = (Ice.Core.Session)oTrans.Session;

Perfect. Now I have the current session referenced within the object namespace.

The Epicor application server session variable can now be “pulled” from the namespace in this fashion (other session variables can be referenced from this point, as well) :

_currSession.AppServer

… however, this value is returned as a fully qualified “Net.TCP” value:

net.tcp://ERPSERVERNAME/EpicorApplicationInstance

Here, the Epicor server name (“host name”) needs to be parsed out of that string.

To do this, I created a small method that specifically targets the Epicor server name within an array and returns it back to the calling process:

To call into this method, I simply used the previously reserved string object to hold the return value from the method; passing along the AppServer object from the previously acquired session namespace :

strEpiServer = GetAppServer(_currSession.AppServer);

Now, I can use Epicor server string value to reference a path in which to write a log file:

string strPath = @“\” + strEpiServer + @"\EpicorData\CustomCodeLogging" + strLogFileName;


Remember - this example applies to client-side session referencing from an Epicor form module customization. It does not apply to BPMs.

4 Likes

You could use the Uri Helper:

1st Option - Quick Extract of Host

string sHost = (new Uri("net.tcp://ERPSERVERNAME/EpicorApplicationInstance")).Host; // Output: ERPSERVERNAME
string sHost = (new Uri( ((Ice.Core.Session)oTrans.Session).AppServer) )).Host; // Output: ERPSERVERNAME

2nd Option - Create Object

var url = new Uri("net.tcp://ERPSERVERNAME/EpicorApplicationInstance");

url.Host // ERPSERVERNAME
url.AbsoluteUri // EpicorApplicationInstance
url.Port // 808
url.Scheme // net.tcp

Easy Path Concat

string sLogFile = System.IO.Path.Combine(@"\\"+ sHost, "EpicorData", "CustomLog.log");

More info for anyone who hasn’t used it yet

System.IO.Path.Combine(@"C:\abc", "MyFileName.xml") // C:\abc\MyFileName.xml
System.IO.Path.Combine(@"C:\abc\", "MyFileName.xml") // C:\abc\MyFileName.xml
System.IO.Path.Combine(@"\\SERVERPATH", "MyFileName.xml") // \\SERVERPATH\MyFileName.xml
System.IO.Path.Combine(@"\\SERVERPATH\", "MyFileName.xml") // \\SERVERPATH\MyFileName.xml
6 Likes

Thanks, @hkeric.wci.

I’ll certainly want to try your example the next time I need to parse out the Epicor server host name.

I appreciate your follow-up!

I think url.AbsoluteUri should be url.AbsolutePath. Link to run → example

@josecgomez can we integrate sharplab/try.dot.net into this forum? It should be nice feature.

How can you get the same information in a C# BPM?
I need to parse out if the BPM is running in E10Live, E10Train, E10Test, etc.

Try

string name = (new Uri(Session.AppServerURL)).AbsoluteUri;

Thank you for your reply. That gave me the name of the server, but not the name of the Epicor environment. I don’t have Visual Studio installed how can I see what properties are available?

string name = (new Uri(Session.AppServerURL)).WhatAreSomeOtherPropertiesToTryHere

MSDN

1 Like

Josh is right MSDN would know it all. Uri Class (System) | Microsoft Learn

But make sure you are using AbsoluteUri, I edited my post quickly after I noticed I had .Host in there

url.Host // ERPSERVERNAME
url.AbsoluteUri // EpicorApplicationInstance
url.Port // 808
url.Scheme // net.tcp
1 Like

Neat that really helped, this is how I got it to work:

string SysAppserverURL = (new Uri(Session.AppServerURL)).AbsoluteUri;   // this string is :   net.tcp://our-server/E10Train
string environmentDB = SysAppserverURL.Split('/')[3];  // this gives E10Train

Now environmentDB is equal to E10Live or E10Train, etc. That’s pretty neat. I checked out the reference, I see all the other properties available too. Thank you very much.

Reduce it down to a single line and make it a class level variable

private string _envDb = (new Uri(Session.AppServerURL)).AbsoluteUri.Split('/')[3];
1 Like

Ah! I guess there is Segments or AbsolutePath you can use too.

Is each BPM a class? Sorry if that’s a dumb question.

On the Server a Business Object with multiple BPMs kind of looks like this:

image

Whoa I see ok so this OP is about UI side you are on BPM side. If that’s the case I use DB connection string not session. Reason being if you call something from REST you have no session and that Session.AppServerURL is no longer going to work for what you want.

Something like:

bool isProd = Db.ConnectionString.Contains("E10Live");

I’m not sure when they introduced it (at least at 500) but there is also a way to flag in Admin console which system is Production and access that in BPM land (see this post I just made and my prior one Ice.SysCompany.IsLive - #5 by jgiese.wci)

I use this in BPM’s to identify what server an email as sent from, it could be modified to suit your need

string dbServ = Db.ConnectionString;

// Checks if LIVE
bool isLive = dbServ.Contains("E10Live");

if (isLive == true)
{
callContextBpmData.Character20 = "This email was created in the LIVE server";
}

// Checks if PILOT
bool isPilot = dbServ.Contains("E10Pilot");

if (isPilot == true)
{
callContextBpmData.Character20 = "***This email was created in the PILOT server, please delete***";
}

//Checks if TEST
bool isTest = dbServ.Contains("E10Test");

if (isTest == true)
{
callContextBpmData.Character20 = "***This email was created in the TEST server, please delete***";
}

It may not be perfect but I’m new to C# and it works for me