I'm passing in an object that's already been transformed into a fully formed QBO Customer Entity. I'd like to use the AddAsync(IEntity) method because it returns the same object from QBO with it's ID (or an Error).
With the code below, I can see that it successfully works at adding the object to QBO, but my callback method never gets called and I only see two of the following DataService error messages and a System.dll error message in my output:
A first chance exception of type 'System.NullReferenceException' occurred in Intuit.Ipp.DataService.dll A first chance exception of type 'System.NullReferenceException' occurred in Intuit.Ipp.DataService.dll A first chance exception of type 'System.NullReferenceException' occurred in System.dll
Here's my code:
public void Add([NotNull] Sales.Customer input)
{
try
{
_customer = input;
var qboInput = QboCustomerTranslate.Current.ToQuickbooksModel(input);
QboAuth.AuthService.OnAddAsyncCompleted += OnAddCallBackUpdateQboId;
QboAuth.AuthService.AddAsync(qboInput);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
public void OnAddCallBackUpdateQboId(object sender, CallCompletedEventArgs<IEntity> e)
{
if (e.Error != null)
{
if (e.Entity != null)
{
var customer = e.Entity as Customer;
if (customer != null)
{
using (var db = DatabaseManager.Current.NewDatabase())
{
_customer.Notes = e.Error.Message;
if (!customer.Id.IsEmpty())
{
_customer.QuickbooksId = customer.Id.AsInt();
}
_customer.Save();
}
}
}
}
else
{
if (e.Entity != null)
{
var customer = e.Entity as Customer;
if (customer != null)
{
using (var db = DatabaseManager.Current.NewDatabase())
{
if (!customer.Id.IsEmpty())
{
_customer.QuickbooksId = customer.Id.AsInt();
}
}
}
}
}
}
My request Json looks like:
{
"BillAddr": {
"Line1": "77 TestStreet",
"Line2": "",
"City": "TestingsVilleTown",
"Country": "USA",
"CountrySubDivisionCode": "TT",
"PostalCode": "77887"
},
"GivenName": "TFirst",
"FamilyName": "TLast",
"CompanyName": "Test22",
"DisplayName": "Test22",
"PrimaryPhone": {
"DeviceType": "Primary",
"FreeFormNumber": "7778884567"
},
"PrimaryEmailAddr": {
"Address": "Test22@Test.com"
}
}
My response Json looks like:
{
"Customer": {
"Taxable": false,
"BillAddr": {
"Id": "9495",
"Line1": "77 TestStreet",
"City": "TestingsVilleTown",
"Country": "USA",
"CountrySubDivisionCode": "TT",
"PostalCode": "77887",
"Lat": "INVALID",
"Long": "INVALID"
},
"Job": false,
"BillWithParent": false,
"Balance": 0,
"BalanceWithJobs": 0,
"PreferredDeliveryMethod": "Print",
"domain": "QBO",
"sparse": false,
"Id": "7291",
"SyncToken": "0",
"MetaData": {
"CreateTime": "2014-03-12T10:06:12-07:00",
"LastUpdatedTime": "2014-03-12T10:06:12-07:00"
},
"GivenName": "TFirst",
"FamilyName": "TLast",
"FullyQualifiedName": "Test22",
"CompanyName": "Test22",
"DisplayName": "Test22",
"PrintOnCheckName": "Test22",
"Active": true,
"PrimaryPhone": {
"FreeFormNumber": "7778884567"
},
"PrimaryEmailAddr": {
"Address": "Test22@Test.com"
}
},
"time": "2014-03-12T10:06:11.796-07:00"
}
-Edit-
These seem to be the related lines from the Tracelog:
WebDev.WebServer40.exe Information: 0 : Info -- 03-13-2014 15:23:37 -- - 0 - Void AddAsyncompleted(System.Object, Intuit.Ipp.Core.AsyncCallCompletedEventArgs) - Finished Executing event AddAsyncompleted in AsyncService object.
WebDev.WebServer40.exe Information: 0 : Info -- 03-13-2014 15:23:37 -- - 0 - Void AddAsyncCompleted(System.Object, Intuit.Ipp.Core.CallCompletedEventArgs`1[Intuit.Ipp.Data.IEntity]) - Finished Executing Method add Async.
WebDev.WebServer40.exe Error: 0 : Error -- 03-13-2014 15:23:37 -- - 0 - Void AddAsyncompleted(System.Object, Intuit.Ipp.Core.AsyncCallCompletedEventArgs) - Intuit.Ipp.Exception.IdsException: Object reference not set to an instance of an object.
WebDev.WebServer40.exe Information: 0 : Info -- 03-13-2014 15:23:37 -- - 0 - Void AddAsyncCompleted(System.Object, Intuit.Ipp.Core.CallCompletedEventArgs`1[Intuit.Ipp.Data.IEntity]) - Finished Executing Method add Async.
Simple Fix - I was having this problem since I wasn't storing my DataService.
DataService.DataService service = new DataService.DataService(context);
bool isAdded = false;
// Used to signal the waiting test thread that a async operation have completed.
System.Threading.ManualResetEvent manualEvent = new ManualResetEvent(false);
// Async callback events are anonomous and are in the same scope as the test code,
// and therefore have access to the manualEvent variable.
service.OnAddAsyncCompleted += (sender, e) =>
{
isAdded = true;
manualEvent.Set();
if (e.Error != null)
{
exp = e.Error;
}
if (exp == null)
{
if (e.Entity != null)
{
actual = (T)e.Entity;
}
}
};
// Call the service method
service.AddAsync(entity);
manualEvent.WaitOne(30000, false); Thread.Sleep(10000);
manualEvent.Reset();
The above is an example using anonymous type. See if this helps!