понедельник, 8 ноября 2010 г.

QBFC: UTFDataFormatException exception workaround.

Steps to reproduce: application tries to perform simple QBFC query to QuickBooks 2010 on purpose of all customers retrieval using next code (creation of connection to QuickBooks is omitted for the sake of simplicity):
 

protected IMsgSetRequest _requests = _session.CreateMsgSetRequest("US", 7, 0);
...
_requests.ClearRequests();
ICustomerQuery customerQuery = _requests.AppendCustomerQueryRq();
String requestsXml = _requests.ToXMLString();
String responsesXml = RequestProcessor.ProcessRequest(Ticket, requestsXml);
_responses = ConversionHelper.ToMsgSetResponse(responsesXml, Session);


This code worked absolutely correctly for ages, but particular client faced with exception System.Runtime.InteropServices.COMException (0x80040301): An exception occurred! Type:UTFDataFormatException, Message:invalid byte 2 (M) of a 2-byte sequence.SAXParseException: error at line 82732, column 4 in XML data. which was thrown in the last line of the code snippet above. Firstly I thought that such exception can be related with QuickBooks company data corruption, but its verification and rebuilding neither revealed any inconsistencies nor eliminated mentioned issue. I tried to investigate content of responsesXml string, but it contained absolutely valid data. I tried to delete customer related with XML document line mentioned in the exception, but exception started to raise in other absolutely correct places. But finally I found workaround which didn't explain reasons of this issue, but at least helped to eliminate given exception. This workaround consists in addition of fake filter to the customer request before its performing. I used next variant:

customerQuery.ORCustomerListQuery.CustomerListFilter.FromModifiedDate.SetValue(DateTime.Parse("1/1/1971"), true);

As you probably know, TimeModified element of QuickBooks entity can't be less than 1/1/1971, so any data can't be filtered out using this expression. Final version of the code snippet looks like:

 
protected IMsgSetRequest _requests = _session.CreateMsgSetRequest("US", 7, 0);
...
_requests.ClearRequests();
ICustomerQuery customerQuery = _requests.AppendCustomerQueryRq();

customerQuery.ORCustomerListQuery.CustomerListFilter.FromModifiedDate.SetValue(DateTime.Parse("1/1/1971"), true);
String requestsXml = _requests.ToXMLString();
String responsesXml = RequestProcessor.ProcessRequest(Ticket, requestsXml);
_responses = ConversionHelper.ToMsgSetResponse(responsesXml, Session);


This code works absolutely correctly and returns all customers from the mentioned client's QuickBooks company.

четверг, 21 октября 2010 г.

.NET 2.0: Query to MS Access database throws "The provider could not determine the Object value" exception.

Recently I faced with the weird issue. My .NET 2.0 application tried to perform very simple query to table located in MS Access 2007 database, but call of ICriteria.List() method was throwing exception "could not execute query {QUERY_TEXT}". Inner exception looked like this: "The provider could not determine the Object value. For example, the row was just created, the default for the Object column was not available, and the consumer had not yet set a new Object value.". I want to pay your attention on the fact that given table contained field of Memo data type.
I spent I lot of time on investigation of this issue and finally found cause of the problem. The fact is one of values in Memo field was corrupted somehow. Exception was eliminated after Access utility Compact and Repair Database/Project launching (you can find it on the Tools menu) on my database.
Hopefully, this post will save some time for somebody :)
P.S. Value of corrupted field, of course, wasn't restored and was replaced with line of '#' characters. Some time later I faced with it when my application threw new exception during attempt of deserialization of binary value stored there.