I have created a Blazor Server application using the Epicor Rest Helper. Since EpicorRest is a static class, a scoped instance can not be created and this has led to the settings being shared between users, matching the last user logged in. Transactions are being saved to the db under the last user login instead of the current user. Any suggestions to separate the calls with Blazor Server app?
Please excuse my ignorance, but won’t placing the session in a using statement dispose of that session at the end of the function and require a new session each time a function call is placed to EpicorRest? If the EpicorRest.UserID and .Password are revised each time a user logs in, and possibly the .AppPoolInstance (Production vs Test), will it not result in the same behavior?
I have uploaded a video of what I am experiencing. After a second user logs on, the EpicorRest.UserID, EpicorRest.Password and EpicorRest.AppPoolInstance are updated to the last users login information. Creating a new EpicorRestSession would be based on the other user given the current state of EpicorRest. To avoid this without being able to scope an instance of EpicorRest, I would have to reassign the userID and password before each EpicorRest call.
Yes you need to do that re-assign the username and password on every call. I can look into turning it into an instance class but even if I did its a single backend so you would still have to do somehow keep track of who the user is and swap user’s or class instance
Having the class not be static wouldn’t really help you here
No, and that seems to be the issue. On login, the userID and password are stored to EpicorRest and then used for subsequent calls. Problem is the next user login overwrites the previous credentials and next calls are written under those user details. I need a scoped instance to keep the calls separate.
However here’s what I recommend instead. User an impersonation header
Establish a server side username / password config for an account that has impersonation rights
for the Login screen (only) use the provided username / password to validate / authenticate. Establish a user session which keeps the username as part of the state
For every subsequent call use the impersonation header to make any rest calls simply apply the impersonate property before every call with the username from the request using the configured account with impersonation rights.
Something like this, mind you this is pseudo code
EpicorRest.AppPoolHost = Settings.Default.Host; //TLD to your Epicor Server
EpicorRest.AppPoolInstance = Settings.Default.Instance; //Epicor AppServer Insdtance
EpicorRest.UserName = Settings.Default.User; //Epicor Username
EpicorRest.Password = Settings.Default.Password; //Epicor Password
EpicorRest.APIKey =Settings.Default.API; //API key required with V2
EpicorRest.APIVersion = EpicorRestVersion.V2; //Defaults to V2
Session = new Session(); //Scoped Session variable
public Login(stirng user, string password)
{
EpicorRest.UserName = user; //Epicor Username
EpicorRest.Password = password; //Epicor Password
var getEnvironemtn = EpicorRest.GetEnvironment();
if (all is good)
{
Session.CurrentUser = user;
}
//Reset Class Back to Impesonation Account
EpicorRest.UserName = Settings.Default.User; //Epicor Username
EpicorRest.Password = Settings.Default.Password; //Epicor Password
}
public MakeACall()
{
EpicorRest.ImpersonateUser = Session.CurrentUser;
var result = EpicorRest.BaqGet("zCustomer01");
}
I can think of (2) instances where this may not work. Both are timing issues.
More than 1 user logging in at the same time (low probability)
More than 1 user making rest calls at the same time while logged into different instances - Production vs Test environments (higher probability especially during program changes / testing)
If you are going to be connecting to multiple Epicor instances I’d recommand two running instances of the app
prod.app.tld, and dev.app.tld
Much easier to manage than also passing in the Epicor / Host and API keys on every call… That failing
You can make your own HTTP calls and deal with the Epicor stuff directly too if that’s the case, it isn’t hard the library is just making it easier (for some) but if it doesn’t work for what you need then implement HttpClient
Hm, I guess that means if I ever have time I could make my REST based configurator have it show the user running the configurator changing the price/description,etc. Learn something every day