SBX - Search With Button

SBX - Forum Post Title

Econnect Exception Handling doesn't work in WEB API 2 application

Microsoft Dynamics GP Forum

Wulala asked a question on 24 Feb 2017 3:27 AM

Question Status

Verified

I was trying to retrieve error infomation like this 

Error Number = 8053 Stored Procedure= taPopRcptLineInsert Error Description = Input variable contains a duplicate document (POPRCTNM)
Node Identifier Parameters: taPopRcptLineInsert

However my code isn't working as below(exception is working fine, but not the econnect exception):

....

catch(eConnectException exc)
{
result = "eConnect Exception - " + exc.ToString();
}
catch (Exception ex)
{

result = "Exception - " + ex.ToString();
}

.....

Hope someone can give me some hints!!

THANKS !!!!

 

Reply
Tim Wappat responded on 24 Feb 2017 3:43 PM
My Badges

Thoughts,

Check your namespaces, is eConnectException actually the same type as eConnect is raising (no one has created another eConenctException type?

catch(eConnectException exc)

If your catch block is not catching then the types can't be the same, so look at the exception type, write it out to debug, what type is it? No being able to see your code block, you might have managed to get the eConnect Exception wrapped in an outer exception?

What you are attempting to do looks fundamentally correct so its to do with your local implementation.

Tim.

Reply
Wulala responded on 27 Feb 2017 3:47 AM

Hi, Tim. This is the Try-Catch block of my code. thanks for the reply !!

...

using Microsoft.Dynamics.GP.eConnect;

using Microsoft.Dynamics.GP.eConnect.Serialization;

...

try

               {

                   result = SerializePurchasesOrderObject(value, xmlFile);

                   XmlDocument xmldoc = new XmlDocument();

                   xmldoc.Load(xmlFile);

                   string pOrderDocument = xmldoc.OuterXml;

                   ConnectionStringSettings mySetting = ConfigurationManager.ConnectionStrings["econString"];

                   if (mySetting == null || string.IsNullOrEmpty(mySetting.ConnectionString))

                       throw new Exception("Fatal error: missing connecting string in web.config file");

                   sConnectionString = mySetting.ConnectionString;

                   string pOrder = e.CreateTransactionEntity(sConnectionString, pOrderDocument);

                   //result = 3;

               }

               catch(FaultException<eConnectSqlErrorCollection> ex)

               {

                   result = "sqlFault - " + ex.Detail.ToString();

               }

               catch(FaultException<eConnectFault> ex)

               {

                   result = "eConnect Fault - " + ex.Detail.Message.ToString();

               }

               catch(eConnectException ex)

               {

                   result = "eConnect Exception - " + ex.Message.ToString();

               catch(System.Security.SecurityException ex)

               {

                   result = "security message - " + ex.Message.ToString();

               }

               catch (Exception ex)

               {

                   result = "Exception - " + ex.InnerException.ToString();

               }

               finally

               {

                   e.Dispose();

               }

...

Reply
Tim Wappat responded on 27 Feb 2017 4:08 AM
My Badges

I would check you have an InnerException before calling .ToString() on it, or you'll get an exception someday in your exception handler when you have an unexpected error that does not have an InnerException. In fact I would just call .ToString on the exception itself as from the help it does that checking for you....

Same with the detail message to string. Exceptions in exception handlers can be a pain to identify and debug...

ToString returns a representation of the current exception that is intended to be understood by humans. Where the exception contains culture-sensitive data, the string representation returned by ToString is required to take into account the current system culture. Although there are no exact requirements for the format of the returned string, it should attempt to reflect the value of the object as perceived by the user.

The default implementation of ToString obtains the name of the class that threw the current exception, the message, the result of calling ToString on the inner exception, and the result of calling Environment.StackTrace. If any of these members is nullNothingnullptrunita null reference (Nothing in Visual Basic), its value is not included in the returned string.

If there is no error message or if it is an empty string (""), then no error message is returned. The name of the inner exception and the stack trace are returned only if they are not nullNothingnullptrunita null reference (Nothing in Visual Basic).

So if you change these to ex.ToString() what is the exception you get?

Tim.

Reply
Wulala responded on 27 Feb 2017 4:18 AM

Here are the exception message. Thanks again Tim, for replying me !!

Exception - System.NullReferenceException: Object reference not set to an instance of an object.

  at Microsoft.Dynamics.GP.eConnect.EventLogHelper.AddExceptionHeader(String action, Object[] inputParameters, StringBuilder errorString)

  at Microsoft.Dynamics.GP.eConnect.EventLogHelper.CreateEventLogEntry(Exception exception, String action, Object[] inputParameters)

  at Microsoft.Dynamics.GP.eConnect.eConnectMethods.CreateTransactionEntity(String connectionString, String sXML)

  at WebAppDemo.Controllers.PoUpdateController.PoUpdate(JArray value) in C:\Users\kc\documents\visual studio 2015\Projects\WebAppDemo\WebAppDemo\Controllers\PoUpdateController.cs:line 89

Reply
Tim Wappat responded on 27 Feb 2017 8:47 AM
My Badges
Verified Answer

This just got interesting, its not you then!...

Could you see if Thread.CurrentPrincipal.Identity or Thread.CurrentPrincipal.Identity.Name is null just before you call the CreateEntity? 

Are you running this under something like iisexpress/WCF with anon access? (I know the title of the post gives a clue, but you might have broken the code out into another app)

My working theory is that is will be null, thus the AddExceptionHeader in the eConnect exception helper is then throwing and error when it tries to get the string of the Identity Name...

[Edit]

http://stackoverflow.com/questions/26787423/currentprincipal-user-is-empty-in-web-api-service

This post seems to prove my theory that web api has empty identity, so you need to set it.

Tim.

Reply
Wulala responded on 27 Feb 2017 8:41 PM

The return i get from the thread is as below:

Identity - System.Security.Claims.ClaimsIdentity

Name -

So, the name is null and identity is existing. What can i do about that? and where to set the thread that u mention in last reply ?

thanks!

Reply
Wulala responded on 27 Feb 2017 9:00 PM

Hi Tim, i couldnt express how much i appreciate your help on this topic, i just fixed this after i set a generic name on the thread ! Thanks man !

Reply
Tim Wappat responded on 28 Feb 2017 4:26 AM
My Badges

My pleasure, it was a fun problem to solve!

I'll submit a connect for this as I think that is a flaw in eConnect, might have been ok back in the day, but today it is going to cause people issues.

Tim.

Reply
Code Beginner responded on 23 Jan 2018 6:08 AM

HI Wulala,

Im also getting the same Error that is 'object reference is not set to be..............' at EconnectMethod.GetEntity(constring,OuterXml). How can u fix that error and where to set that thread ?.

Please help me.

Reply
Tim Wappat responded on 23 Jan 2018 6:22 AM
My Badges

[Edit]

The document: 

https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

says:

If your application performs any custom authentication logic, you must set the principal on two places:

    • Thread.CurrentPrincipal. This property is the standard way to set the thread's principal in .NET.
    • HttpContext.Current.User. This property is specific to ASP.NET.

The following code shows how to set the principal:+

private void SetPrincipal(IPrincipal principal)
{
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
        HttpContext.Current.User = principal;
    }
}

I'm not in a position to play with this right now but this looks like the starting point. 

Reply
Code Beginner responded on 23 Jan 2018 6:48 AM

Hi Tim,

i'm new to the Web API, could u please tell me where i set the Threading options.i checked my solution.but i didn't get any threading in my solution.So could u please explain to me in detail.

Reply
Tim Wappat responded on 27 Feb 2017 8:47 AM
My Badges
Verified Answer

This just got interesting, its not you then!...

Could you see if Thread.CurrentPrincipal.Identity or Thread.CurrentPrincipal.Identity.Name is null just before you call the CreateEntity? 

Are you running this under something like iisexpress/WCF with anon access? (I know the title of the post gives a clue, but you might have broken the code out into another app)

My working theory is that is will be null, thus the AddExceptionHeader in the eConnect exception helper is then throwing and error when it tries to get the string of the Identity Name...

[Edit]

http://stackoverflow.com/questions/26787423/currentprincipal-user-is-empty-in-web-api-service

This post seems to prove my theory that web api has empty identity, so you need to set it.

Tim.

Reply

SBX - Two Col Forum

SBX - Migrated JS