Epicor 10.1.5 SessionModSvcContractClient logout

1.1k Views Asked by At

Has anybody ever had an issue where the SessionModSvcContractClient Logout function throws an Exception: Additional information:

Object reference not set to an instance of an object.

When I tried LogoutAsync and Close methods they worked fine. Can anybody help me figure out why that's happening or the difference between the 3.

I'm basically trying to use create the test from the WCF guide

    static void Main(string[] args)
    {

        //use a self-signed certificate in IIS, be sure to include the following code. This code speeds up calls to the services and prevents the method from trying to validate the certificate with the known authorities.
        ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { return true; };

        //You can toggle the value assigned to this variable to test the two bindings: SOAPHttp or BasicHttp
        EndpointBindingType bindingType = EndpointBindingType.SOAPHttp;

        //Epicor credentials:
        string epicorUserID = "XXX";
        string epiorUserPassword = "XXX";


        string scheme = "http";
        if (bindingType == EndpointBindingType.BasicHttp)
        {
            scheme = "https";
        }

        UriBuilder builder = new UriBuilder(scheme, "localhost");

        string webServicesLink = "XXX/";

        builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
        SessionModSvcContractClient sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);

        builder.Path = webServicesLink + "Erp/BO/AbcCode.svc";
        ABCCodeSvcContractClient abcCodeClient = GetClient<ABCCodeSvcContractClient, ABCCodeSvcContract>(builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);

        Guid sessionId = Guid.Empty;
        sessionId = sessionModClient.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.
        builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
        sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(),epicorUserID,epiorUserPassword,bindingType);

        sessionModClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));
        abcCodeClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));

        var ts = new ABCCodeTableset();
        abcCodeClient.GetNewABCCode(ref ts);
        var newRow = ts.ABCCode.Where(n => n.RowMod.Equals("A", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
        if (newRow != null)
        {
            newRow.ABCCode = "G";
            newRow.CountFreq = 30;
            newRow.StockValPcnt = 100;
            abcCodeClient.Update(ref ts);
            ts = null;
            ts = abcCodeClient.GetByID("G");
            if (ts != null && ts.ABCCode.Any())
            {
                ABCCodeRow backupRow = new ABCCodeRow();
                var fields = backupRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
                foreach (var field in fields)
                {
                    if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject))
                    { 
                        continue;
                    }
                    var fieldValue = field.GetValue(ts.ABCCode[0]);
                    field.SetValue(backupRow, fieldValue);
                }
                ts.ABCCode.Add(backupRow);
                ts.ABCCode[0].CountFreq = 45;
                ts.ABCCode[0].RowMod = "U";
                abcCodeClient.Update(ref ts);
                ts = null;
                ts = abcCodeClient.GetByID("G");
                if (ts != null && ts.ABCCode.Any())
                {
                    Console.WriteLine("CountFreq = {0}", ts.ABCCode[0].CountFreq);
                    ts.ABCCode[0].RowMod = "D";
                    abcCodeClient.Update(ref ts);
                    try
                    {
                        ts = abcCodeClient.GetByID("G");
                    }
                    catch (FaultException<Epicor.AbcCodeSvc.EpicorFaultDetail> ex)
                    {
                        if (ex.Detail.ExceptionKindValue.Equals("RecordNotFound", StringComparison.InvariantCultureIgnoreCase))
                        {
                            Console.WriteLine("Record deleted.");
                        }
                        else
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
            }
        }
        if (sessionId != Guid.Empty)
        {

                sessionModClient.Logout();


        }
        Console.ReadLine();
    }
2

There are 2 best solutions below

1
On BEST ANSWER

Your code worked fine for me after I changed the config to suit my environment.

It looks like you followed the step 7 on page 15 of the Epicor10_techrefWCFServices_101400.pdf guide and correctly created a new instance of the SessionModSvc after Login(). However, if you copied the full code for the Main method from page 18 then this is missing and I can replicate your issue.

Check the code that you are compiling has created a new instance of the SessionModSvc after the call to .Login().

2
On

See my other answer, but as an alternative you may want to consider this method of accessing the services.

If you have access to the client DLLs then this code might be easier:

    static void Main(string[] args)
    {
        // Hard-coded LogOn method 
        // Reference: Ice.Core.Session.dll
        Ice.Core.Session session = new Ice.Core.Session("manager", "manager", "net.tcp://AppServer/MyCustomerAppserver-99999-10.0.700.2");

        // References: Epicor.ServiceModel.dll, Erp.Contracts.BO.ABCCode.dll
        var abcCodeBO = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.ABCCodeImpl>(session, Erp.Proxy.BO.ABCCodeImpl.UriPath);

        // Call the BO methods
        var ds = abcCodeBO.GetByID("A");
        var row = ds.ABCCode[0];

        System.Console.WriteLine("CountFreq is {0}", row.CountFreq);
        System.Console.ReadKey();
    }

Just add references to:

  • Ice.Core.Session.dll
  • Epicor.ServiceModel.dll
  • Erp.Contracts.BO.ABCCode.dll