Error with There was no endpoint listening at https://erp-apps/ERP102/Ice/Lib/SessionMod.svc

Hi any expert,
I have a customized application program which load some service, previously with the old server still working fine, just recently we has move to the new environment on VM for our Epicor 10.2.400 and I would like to seek for any solution to solve my issue for error as follow:

There was no endpoint listening at https://erp-apps_vm/ERP102/Ice/Lib/SessionMod.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

The application locate in other machine and is not on the local server, I suspect the new web.config must enable to something regards end point stuff.
I did run the service tools which unable to connect the service and please if anyone have the same experience and willing to help.

  <remove scheme="http" />
  <add scheme="http" binding="wsHttpBinding" bindingConfiguration="SOAPHttp" />
  <remove scheme="https" />
  <add scheme="https" binding="basicHttpBinding" bindingConfiguration="BasicHttp" />

I did try to add the statement as above in web.config but the Epicor unable to start and load:

I understand might be in IIS have to enable ws load, and if anyone have experience mine to share with me.

Any reason you’re not using REST instead of SOAP?

1 Like

Might I suggest you dont manually just edit the web config. If you need to change the bindings on your deployment, use the Admin Console to configure\deploy that. Aside from the fact that’s what is designed to do, manually changing the web config can BREAK the Admin Console (it’s ability to configure your environment).

First, obviously check your host name, can you ping it? Have you tried the FQDN? Do you have the HTTPS binding enabled on the deployment?

1 Like

Hi Chris,
Yes I able to ping the host, but after few round test i notify that the certificate file was different name from different machine and i have to rebind in IIS, once save the IIS i found it auto adjust the config file path for loading the certificate name.
I copy the old machine certificate and reuse in the new machine IIS (rebinding) and its works.

1 Like

Thanks Mark,
I’m still fresh on using this web service, is there any reference name guide pdf can be download for this?

Thanks

The REST services are self documenting, just follow the basic documentation, they will guide you to the API page, and then the documentation for each method call is directly in the page.

I agree that REST is probably a better option. You can use SOAP services, but they have some particularities that make them tricky to use without issue. In particular with the opening and closing of sessions (so you don’t keep sessions opened using up licenses), and certificate validation.

The advantage of SOAP services is the strong typing and intellisense support you get in Visual Studio, and in some cases SOAP services can offer better performance. If you enable compression in your REST requests however (Accept-Encoding: gzip,deflate) performance is pretty much on par. REST plays best with JSON and javascript, but it’s still reasonably straightforward in C# with JSON.NET… You can also make your REST requests so that the server returns XML, if you prefer working with Linq to XML axes (Accept: application/atom+xml)…

Here are the helper classes I use to connect to the SOAP services without these issues:

using ECS.SessionModSvcRef;
using System;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace ECS
{
    public class EpicorSession
    {
        private readonly string _username;
        private readonly string _password;

        private SessionModSvcContractClient _session;

        private string _companyId;
        private string _plantId;
        private string _plantName;
        private string _workstationId;
        private string _workstationDesc;
        private string _employeeId;
        private string _countryGroupCode;
        private string _countryCode;
        private string _tenantId;
        

        public Guid SessionId { get; private set; } = Guid.Empty;
        
        public string CompanyId
        {
            get { return _companyId; }
            set
            {
                _companyId = value;
                _session.SetCompany(_companyId,
                                    out _plantId,
                                    out _plantName,
                                    out _workstationId,
                                    out _workstationDesc,
                                    out _employeeId,
                                    out _countryGroupCode,
                                    out _countryCode,
                                    out _tenantId);
            }
        }

        public string PlantId { get { return _plantId; } }
        public string PlantName { get { return _plantName; } }
        public string WorkstationId { get { return _workstationId; } }
        public string WorkstationDesc { get { return _workstationDesc; } }
        public string EmployeeId { get { return _employeeId; } }
        public string CountryGroupCode { get { return _countryGroupCode; } }
        public string CountryCode { get { return _countryCode; } }
        public string TenantId { get { return _tenantId; } }


        public EpicorSession(string username, string password)
        {
            // Disable certificate validation. Necessary for self-signed certs and speeds up calls.
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate (object thesender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                { return true; };

            _username = username;
            _password = password;

            _session = GetClient<SessionModSvcContractClient, SessionModSvcContract>();
            SessionId = _session.Login();

            // Create a new instance of the SessionModSvc. Do this because when you call any method on the service
            // client class, you cannot modify its Endpointbehaviors, and if a HookServiceBehavior is not present
            // when calling Logout, the call fails with a NullReferenceException, and the session stays opened on
            // the server.
            _session = GetClient<SessionModSvcContractClient, SessionModSvcContract>();

        }


        public void Logout()
        {
            if (SessionId != Guid.Empty)
            {
                _session.Logout();
                SessionId = Guid.Empty;
            }
        }


        public TClient GetClient<TClient, TInterface>()
            where TClient : ClientBase<TInterface>
            where TInterface : class
        {
            var client = Activator.CreateInstance<TClient>();
            client.ClientCredentials.UserName.UserName = _username;
            client.ClientCredentials.UserName.Password = _password;

            if (SessionId != Guid.Empty) client.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(SessionId, _username));

            return client;
        }

    }
        

   class CustomMessageInspector : IClientMessageInspector
    {
        private Guid _sessionId;
        private string _epicorUserId;

        public CustomMessageInspector(Guid SessionId, string EpicorUserId)
        {
            _sessionId = SessionId;
            _epicorUserId = EpicorUserId;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            if (_sessionId != null && _sessionId != Guid.Empty)
            {
                var sessionHeader = new SessionInfoHeader() { SessionId = _sessionId, EpicorUserId = _epicorUserId };
                request.Headers.Add(sessionHeader);
            }
            return request;
        }

    }
        
        
   class HookServiceBehavior : IEndpointBehavior
    {
        private Guid _sessionId;
        private string _epicorUserId;

        public HookServiceBehavior(Guid SessionId, string EpicorUserId)
        {
            _sessionId = SessionId;
            _epicorUserId = EpicorUserId;
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector(_sessionId, _epicorUserId));
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {

        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }
    }
        
        
   class SessionInfoHeader : MessageHeader
    {
        protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteElementString("SessionID", @"http://schemas.datacontract.org/2004/07/Epicor.Hosting", SessionId.ToString());
            writer.WriteElementString("UserID", @"http://schemas.datacontract.org/2004/07/Epicor.Hosting", EpicorUserId);
        }

        public override string Name
        {
            get { return "SessionInfo"; }
        }

        public override string Namespace
        {
            get { return "urn:epic:headers:SessionInfo"; }
        }

        public Guid SessionId { get; set; }
        public string EpicorUserId { get; set; }
    }
}

And the binding configuration:

  <basicHttpBinding>
    <binding name="BasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
        maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
      <security mode="TransportWithMessageCredential" />
    </binding>
  </basicHttpBinding>
1 Like

Yes Sir. If you go to https://epicweb.epicor.com/products/epicor-erp-10/documentation, browse to your base version (10.2.600, 10.2.500, etc.), go to Technical Reference folder then you will find the v1 and v2 REST guides there.

1 Like

Thanks you very much Mr Mark

Thanks for lovely guide!

1 Like

If you use sessions, then you can just use custom binding, like It will allow login using name and password

1 Like