function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
joe_leojoe_leo 

System.Exception {System.FormatException}

I made this sforce.query() call...
 

m_queryArray = oSFDCQuery.ExecuteQuery("select Support_Code__c, Name, CreatedByID, CreatedDate, Amount__c, Asset_Typ__c from Asset_Activity_Log__C where AccountID__c = '00130000005CZLD' ", oLogin);

With the "CreatedDate" in the query receive the following error...

"String was not recognized as a valid DateTime." as my inner exception

The Full Stack trace is as follows....

at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)

at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)

at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)

at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

at SFDCLibrary.Sforce.SforceService.query(String queryString)

at SFDCLibrary.SFDCQuery.ExecuteQuery(String strQuery, cLogin oLogin)

at LicenceDetails.GetActivityLog() in s:\Projects\2005\AssetManager\LicenceDetails.aspx.cs:line 102

Now when i do not have "CreatedDate" everything works fine. And the query worked fine up until this morning when i made the following change. Thru SFDC setup i adjusted my custom object. I had  field i changed from numeric(7,0) to a text field.  I downloaded a new WSDL and deployed it.

Any ideas or suggestions to what i might have done wrong?

SkowronekSkowronek
Have you tried using the sforce explorer to test this query out? That might give you an idea of the XML data being returned.
joe_leojoe_leo
Thanks Skowronek for you suggestion....
 
I used the sforce explorer and executed the query I was trying to run in my app and.... it worked like a champ.
 
So what this tells me is the soql is well form, the data is good.
 
But what is the missing link???
 
 After testing it thru the sforce explorer, I re-downloaded the WSDL enterprise version, and re-deployed it for my app to use. Still the same error "There is an error in XML document (1, 728)" with the orginal inner exceptions and stack trace...
 
So... what other failure points are there here. I've ripped out my SFDC wrapper, and went back to the barebones standard SFDC call as per the examples, and nothing. Still the same error.
 
Any ideas?
 
Thanks in advance.
 
--Joe
SkowronekSkowronek
Can you post the code (as much as you feel comfortable) found here:

at LicenceDetails.GetActivityLog() in s:\Projects\2005\AssetManager\LicenceDetails.aspx.cs:line 102

That will help to see the error. Also, are you trapping for the SOAP exceptions or just system exceptions?

joe_leojoe_leo

The lines of code in question are as follows...

--------------------------------------------------------------------------------------------------

100: ArrayList m_queryArray = new ArrayList();

101: m_queryArray = oSFDCQuery.ExecuteQuery("Select Amount__c, Asset_Typ__c, AssetActivityLog__c, CreatedById, CreatedDate, Name, Support_Code__c from Asset_Activity_Log__c where AccountID__c = '00130000004B546' ", oLogin);

102: if (m_queryArray.Count > 0)

---------------------------------------------------------------------------------------------------------------------------

The oSFDCQuery object and all of its methods are a custom SFDC wrapper we created to handle different function like internal auditing. As well as the app being able to preform different functions based on the oLogin object we pass in to the method. This specific method... ExecuteQuery is nothing special...

---------------------------------------------------------------------------------------------------------------------------

public ArrayList ExecuteQuery(String strQuery, cLogin oLogin)

{

     try

        {

             //Build the Arraylist to hold results

              ArrayList queryArray = new ArrayList();

             //Set the query options

             oLogin.Binding.QueryOptionsValue = new QueryOptions();

             oLogin.Binding.QueryOptionsValue.batchSize = 10;

             oLogin.Binding.QueryOptionsValue.batchSizeSpecified = true;

             //Invoke the query call and save the result in a QueryResult

             Sforce.QueryResult qr = oLogin.Binding.query(strQuery);

             .....

---------------------------------------------------------------------------------------------------------------------

 

I personally see no reason why the query should be affected by having "CreatedDate" in or out.

SkowronekSkowronek
Since it appears your returning a valid ArrayList as apposed to the sforce object array, I'm not sure why you would be getting any SOAP errors. You didn't include the code on how you are converting the sobjects into arraylist so I couldn't speculate more than that.

Have you added a watch to the
m_queryArray list after you run the ExecuteQuery (line 101) to see what it contains? Since you're not checking to see if the m_queryArray is null or not, it could be null and therefore throwing an error (though it wouldn't be a SOAP error, more invalid object call or something similar).

From what you've given me, thats about all I can see now. I would check the return object and make sure something is getting returned with valid return values. If your getting valid returned object and then getting an error on the .Count property call, I'm not sure what else it could be.

joe_leojoe_leo

Huzzah!

Well the answer is and isn't in the code. So here is the issue. I am updating the custom Sales force object from my code, and pulling the information from my code. The "CreateDate" accepts a datetime fromat but!!!!!!!! you need to make sure it is not the standard datetime format you get from C# date object. It needs to be XML friendly. The call was being made to SFDC and the Date that was posted was poorly formated giving the XML error. I will post the correct DateTime format shortly as soon as i figure out what part of the C# date time format was breaking the XML.

Thanks For your help

--Joe

Bryan WagstaffBryan Wagstaff
 The whole issue sounds exactly like one I was having quite some time ago.  I didn't take the time to completely identify the problem needing to get the mission-critical tasks done, and this sounds like it could easily be what I was seeing.

I'm looking forward to additional details.
Jake_Jake_

Hi Joe,

Have you found the correct time format? I am having the same error, except htat I have never set the created date (is that even possible?). But I have set some other dates in my custom object and those dates look completely different in the returned XML, but that might because they are dates only and not date times:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn: partner.soap.sforce.com" xmlns:sf="urn:sobject.partner.soap.sforce.com">
<soapenv:Body>
  <queryResponse>
    <result xsi:type="QueryResult">
      <done>true</done>
      <queryLocator xsi:nil="true"/>
      <records xsi:type="sf:sObject">
       <sf:type>License__c</sf:type>
       <sf:Id>a0030000004yJAZbA2</sf:Id>
       <sf:Id>a0030000004yJAZbA2</sf:Id>
       <sf:CreatedById>00530000000tc3NAbQ</sf:CreatedById>
       <sf:CreatedDate>2006-05-15T14:05:10.000Z</sf:CreatedDate>
       <sf:LastModifiedById>00530000000tb3NAAQ</sf:LastModifiedById>
       <sf:LastModifiedDate>2006-05-17T08:58:45.000Z</sf:LastModifiedDate>
       <sf:License_Expiration__c>2200-01-01</sf:License_Expiration__c>
       <sf:SU_Expiration__c>2200-01-01</sf:SU_Expiration__c>
....

The funny thing is that it works in SforceExplorer.

Update:

The inner exception stack trace:

[FormatException: String was not recognized as a valid DateTime.]
   System.DateTimeParse.ParseExactMultiple(String s, String[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style) +2283030
   System.DateTime.ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) +46
   System.Xml.XmlConvert.ToDateTime(String s, String[] formats) +26
   System.Xml.Serialization.XmlCustomFormatter.ToDateTime(String value, String[] formats) +9
   System.Xml.Serialization.XmlCustomFormatter.ToDate(String value) +11
   System.Xml.Serialization.XmlSerializationReader.ToDate(String value) +5
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSforceService.Read37_NullableOfDateTime(Boolean checkType) +103
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSforceService.Read66_License__c(Boolean isNullable, Boolean checkType) +1711
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSforceService.Read111_sObject(Boolean isNullable, Boolean checkType) +2002
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSforceService.Read125_QueryResult(Boolean isNullable, Boolean checkType) +754
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSforceService.Read159_queryResponse() +285
   Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer57.Deserialize(XmlSerializationReader reader) +40
   System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +163

I snooped around a bit in the DateTimeParse and I can see that it only throws that exact exception in that method if the input string date has length = 0.

-Jacob

Message Edited by Jake_ on 05-18-2006 01:46 AM

MazAMazA
Hi,
 
I'm having the extact same problem (Except on a custom object).  Any luck with this problem?
 
thanks
Maz.
 
Jake_Jake_
Nope. I am also having this problem on custom objects, but only the Created and lastmodified date gives the error, not my own custom date fields.
 
-Jacob
Bryan WagstaffBryan Wagstaff
While working on a completely different issue, I have found a way to reproduce the error in one of the developer tools downloaded from the site.

I am sending (privately) the query that reproduces the error to the SalesForce developers so they can investigate it at their convenience.
AngryBinaryAngryBinary
I was having the same problem on the field "LastModifiedDate" when querying Tasks.
 
To work around it, I simply changed the type of "LastModifiedDate" under "Task" in the WSDL from "xsd:dateTime" to "xsd:string". Now, I have to parse the string after the query, but at least the query is useable.
 
--Randall
 
PS - It should probably be noted that this does no good if you're trying to update an object, and only provides a means to retrieve LastModifiedDate. This problem still is a major hump in my development.

Message Edited by AngryBinary on 07-26-2006 12:49 PM

SuperfellSuperfell
Can someone who's had this problem please provide some more details about there environment, it appears to be a .NET 2.0 bug, and if it is, I'd like to bug the MSFT guys about it. I haven't been able to reproduce it with .NET 2.0 yet here.
Bryan WagstaffBryan Wagstaff

"The nice thing about standards is that there are so many to choose from"

Microsoft's parser contains a lot of date format strings, with different settings for different cultures like 'en-US', 'en-AU', 'fr-BE', and so on.

When I just checked a few moments ago, there are 14578 date format strings that the .Net 2.0 can handle across all cultures.  They follow and include a bunch of different ISO, ANSI, RFC, and heaven-knows-who standard bodies.

Two of the format strings, ISO8601 (Microsoft calls it 'Universal') and RFC1132, are the ones we are interested in.

The Universal string complies with ISO 8601.  Like so many other ISO standards, it is very complex and has a lot of options. 

The W3C cites RFC1132 on Internet date and time formats, which pulls the definitions from RFC822, which in turn pulls in additional definitions from ANSI X3.51-1975.  These give several different options as well.

Microsoft's parsers include several matching strings that follow both ISO 8501 and RFC822, including these two that closely match the SalesForce format:

  • "yyyy-MM-dd HH:mm:ssZ" (needs a time zone, accepts 'Z' as Universal time)
  • "yyyy-MM-ddTHH:mm:ss" (assumes Universal time)

SalesForce's generated date also follows both ISO 8501 and RFC822.  It looks like this:

  • "yyyy-MM-ddTHH:mm:ssZ" (specifies Universal time zone and uses T separator)

Even though both sides are using the same standards, they are using incompatable but legal variations within the standards. 

I have tried to set new format strings by assigning my own conversion string for the thread.  See System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat and GetAllDateTimePatterns() for more on doing that.  A much more complex solution, but that allows more options to the rest of your program, is to add wrappers and/or extensions for the various SOAP classes that handle this conversion.

Since I assume that Microsoft won't change their format strings until .NET 3.0 (and maybe not even then), I believe it would just be easier if SalesForce used a different standard-compliant format.

 

SuperfellSuperfell
The YYYY-MM-DDTHH:mm:ssZ format is the subset of ISO8601 dictated by XML Schema, and in every test I've done with .NET 1.1 and .NET 2.0 it handles this format dateTime as returned by the Salesforce API correctly.
I don't think its as simple as a blanket .NET 2.0 can't handle the T in the string, Hence the reason for asking about environments, for the people having the problem what exact version of .NET 2.0 are you using? If no-one logs a bug with MSFT with this, it'll never get fixed.
SuperfellSuperfell
Also what type of app it is might be useful (winforms, ASP.NET, console app) etc, oh, and enterprise vs partner WSDL.

Message Edited by SimonF on 07-26-2006 04:39 PM

AngryBinaryAngryBinary
I'm using a .NET (2.0) control from a DLL hosted on my local machine in IIS and an enterprise WSDL. The control runs in the "intranet" trust zone, and currently receives full trust. The SalesForce account I'm using is one of the sandboxes.
 
The only time I receive this error is when trying to retrieve the "LastModifiedDate" field from Tasks. At one point (three days ago), I did not have this problem, but it has been consistent once it appeared. I can still receive the "CreatedDate" field just fine. I'm trying to pinpoint what change I may have made to either the program or the account at the time I started receiving this exception that may have been the catalyst.
 
As someone else also noted, if I use sforce explorer, I do not have this problem.
SuperfellSuperfell
Sforfce Explorer uses .NET 1.1 which has never shown this problem. I suspect its a particular date that causes the problem, it'd be good if you could narrow down the particular task that causes the issue. (I'm also going to work on a test app that cycles through a bunch of date edge cases, see if that'll highlight the problem)
SuperfellSuperfell
Can you be more specific on the .NET version ? What locale are the clients configured for ? Oh, and which API version (7.0, 6.0 etc) are you using ?

Message Edited by SimonF on 07-27-2006 11:07 AM

SuperfellSuperfell
Are you sure that message capture goes with that stack trace? the stack trace looks like an enterprise WSDL stack trace (its has a License__c type in there), but the response is from the partner API.
Bryan WagstaffBryan Wagstaff

I lied.  SalesForce doesn't use "yyyy-MM-ddTHH:mm:ssZ", but "yyyy-MM-ddTHH:mm:ss.000Z".

In any event, here is the work around I am using:

1. Modify your enterprise.wsdl file, change every occourance of "xsd:date" to "xsd:dateTime".  That takes care of a conversion issue with the short dates.

2. Add this regular expression date changer to your SOAP envelope stream somewhere.  That takes care of the extra .000Z.

void CopyAndStripDates( Stream from, Stream to ) {
  TextReader reader = new StreamReader( from );
  TextWriter writer = new StreamWriter( to );
  writer.WriteLine( (
new Regex( @"(>\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d).\d\d\dZ(</sf:)", RegexOptions.None )).Replace( reader.ReadToEnd(), "$1$2" ) );
  writer.Flush();
}

-- NOTE:  On previewing, it looks like the sequence :) is turned into a graphical smiley face instead of the two symbols : and )

Don't thank me for the work-around, just send money.  :-)

Bryan WagstaffBryan Wagstaff

If you're not too familiar with regular expressions, here is a brief explanation:

"(>\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d).\d\d\dZ(</sf:)"

Is just pattern matching for a bunch of digits, it looks like this fragment of the SOAP response:

>yyyy-MM-ddTHH:mm:ss.zzzZ</sf:

Each occourance is replaced with the pattern "$1$2"  The two segments are the part between the parenthesis.  The only stuff that isn't between section 1 and section two is the ".000Z" string that we want to omit.

SuperfellSuperfell
Keep in mind that stripping of the Z changes the semantics of the dateTime represented. It'd be nice to find the actual issue here, as I said in my other post, is not a simple matter of a mismatch between formats, I wrote a test this morning that round tripped a large number of date times from .NET 2.0 through Salesforce and it didn't have a problem. (.NET v2.0.50727, c# console app using the enterprise WSDL).

If someone can get a capture of a response that causes the problem I'd like to see it.


Bryan WagstaffBryan Wagstaff


SimonF wrote:
If someone can get a capture of a response that causes the problem I'd like to see it.

Try it yourself.
 
Download your enterprise WSDL file.
 
Create an scontrol that will expose your session ID and web url.

Open a fresh new install of Visual Studio 2005.  ( I happen to have reformated a test machine two days ago so it has one of those).

Create a new web project.
 
Add a web reference, pointing to the WSDL file just downloaded.
 
Inside the default page's source code, use this code, almost entirely ripped from the sforceExplorer sample:
 
Code:
public partial class _Default : System.Web.UI.Page {

    SForceAPI.SforceService binding;


    protected void Page_Load( object sender, EventArgs e ) {


        Login();
        if ( binding != null )
            GetCommunications();
    }

    #region Select a few columns from all communications
    public void GetCommunications() {
        
        string queryString = "Select Close_Date__c, Close_Rsn__c, CreatedById, CreatedDate, Date_Offer_Made__c, Days_Evaluating__c, Days_Till_Offer__c, Dt_1st_Phone_Intvw__c, Id, LastModifiedById, LastModifiedDate, Match_Comm_HF_Opp__c, Match_Comm_Stat_Form__c, Port_Dt_AP_Appl_Lst_View__c from Matching_Communications__c";

        // **** CRASH IS BELOW THIS LINE ****
        QueryResult qr = binding.query( queryString );
        // **** CRASH IS ABOVE THIS LINE ****


        // Get the returned records 
        sObject[] records = qr.records;

        // Determine whether some records where returned 
        if ( records.Length > 0 ) {
            bool done = false;  // Use this for loop control 
            while ( !done ) {
                for ( int i = 0; i < records.Length; i++ ) {
                    SForceAPI.Matching_Communications__c comm = records[ i ] as SForceAPI.Matching_Communications__c;
                    if ( comm != null )
                        Response.Write( comm.AP_Appl_Type__c + "<br>" +
                            comm.Child_Care_Assess__c + "<br>" +
                            comm.CreatedDate + "<br>" +
                            comm.Name + "<br>" +
                            comm.Id + "<br>" +
                            comm.VRMC1_1__c + "<br>"
                            );
                }
                // Update the loop control 
                done = qr.done;
                // Determine whether we need to retrieve another batch of result records 
                if ( done == false ) {
                    qr = binding.queryMore( qr.queryLocator );
                    records = qr.records;
                } else {
                    done = qr.done;
                }
            }
        } else {
            System.Diagnostics.Trace.WriteLine( "no records matched criteria" );
        }
    }
    #endregion

    #region Login()

    protected bool Login() {

        // from salesforce.com Custom Tab
        string sessionId = Request.QueryString[ "sessionid" ];
        string serverURL = Request.QueryString[ "serverurl" ];

        // declare for all messages below
        string v_message = "";

        // make sure there are values
        if ( sessionId == null || sessionId == "" )
            v_message += "SessionId is missing or blank.<br>";

        if ( serverURL == null || serverURL == "" )
            v_message += "ServerURL is missing or blank.<br>";

        if ( v_message != "" ) {
            Response.Write( v_message );
            return false;
        }


        try {
            Uri uri = new Uri( serverURL );
            if ( !uri.AbsoluteUri.StartsWith( "https://" ) ||
                    !uri.Host.EndsWith( "salesforce.com" ) ||
                    !( uri.Query == "" ) ) {
                // protect against spoofing web request
                // begins with https
                // host ends in salesforce.com
                // does not have a querystring
                Response.Write( "Not a valid API Server URL.<br><br>" + serverURL );
                return false;
            }

            // binding
            binding = new SForceAPI.SforceService();
            binding.SessionHeaderValue = new SForceAPI.SessionHeader();
            binding.SessionHeaderValue.sessionId = sessionId;
            binding.Url = serverURL;

            // TEST a SOAP call
            SForceAPI.GetUserInfoResult userInfoResult = binding.getUserInfo();

            // string userid = userInfoResult.userId;
            // check if user is in your database
            // if not, you can present a signup screen
            Response.Write( userInfoResult.userId + "<br />" );
            Response.Write( userInfoResult.userFullName + "<br />" );
            Response.Write( userInfoResult.userUiSkin + "<br />" );
            Response.Write( userInfoResult.organizationName + "<br />" );
            Response.Write( userInfoResult.currencySymbol + "<br />" );
            Response.Write( userInfoResult.ToString() + "<br />" );

            return true;

        } catch ( System.Web.Services.Protocols.SoapException exsoap ) {
            if ( exsoap.Code.ToString().Contains( "API_DISABLED_FOR_ORG" ) ) {
                v_message += "This edition of salesforce.com does not provide API access.<br>"
                    + "API access is a standard feature of Enterprise "
                    + "and Unlimited Editions.<br>"
                    + "Certify your application to gain API access to "
                    + "Professional Edition as well.<br><br>";
            }
            Response.Write( v_message + exsoap.Message );
        } catch ( System.UriFormatException uriEx ) {
            Response.Write( "The Server URL is invalid.<br><br>" + uriEx.Message );
        } catch ( Exception ex ) {
            Response.Write( "Unable to connect to the API.<br><br>" + ex.Message );
        }

        return false;
    }

    #endregion

}

 
Run the app inside your debugger, putting in the session ID and sever url as specified.  Watch as you get the exception.
 
 
 
If it doesn't crash for you, I can send you a wsdl file for our sandbox that will induce the exception on any machine in my office.
 
SuperfellSuperfell
Thanks for the info Bryan, I had to change the query to run against my test org, but it ran fine (select id, subject, createdDate, lastModifiedDate, systemModStamp, myDateTime__c, myDate__c from case).

I'd like to take you up on the WSDL / Sandbox offer, you can email me directly sfell at salesforce.com.
Bryan WagstaffBryan Wagstaff

I sent the message and hopefully included enough to help with this.  I have as 64.2 MB log file showing all the raw SOAP messages and socket communications for this tiny test app, but I assume you don't want to go through those.

I noticed before sending it this morning that the long date format didn't need to have the .000Z stripped off, whereas when I wrote the test snippit on Thursday afternoon it needed to be stripped off to prevent the exception.  I'm wondering if the date parser is having an additional  problem with afternoon times rather than morning times, but I don't really care to investigate more.

As I said, we do have a functional workaround for my organization with soap extensions.  It doesn't fix the root cause, but I'm really not interested in debugging other people's code if I don't have to.

Brian HoangBrian Hoang

I hate "me-too" type of posts, but unfortunately I feel like I need to log this as well just so you guys (SF developers) are aware that this issue is seriously affecting your customers.  For us, the unit tests would run just fine on local box, but on the build box (which kicks in with continuous integration) it just fails on the errors described by other posters.  This is also intermitten - it has been working fine for weeks while in development and then all of a sudden the problem pops up today (with no code changes). This would explain why it has worked for you (Simon) while you were testing on your dev account (coincidentally, we are developing against a sandbox version like the other poster as well).

The whole situation now makes us very uncomfortable as we can't trust if it will reliably work on prod.  I do believe .net 2.0 has something to do with it as our 1.1 version was just fine.  Having said that, I personally think that you guys should at least try to find some workarounds rather than relying on fixes (if any) from MS.

SuperfellSuperfell
It hard to sugest workarounds or changes when I still have no idea what causes the problem. However the Microsoft folks have suggested setting the DateTimeSerialization setting to local (the default in 2.0 is roundtrip, and this is all new stuff for dateTimes in 2.0). see http://msdn2.microsoft.com/en-us/library/ms229751.aspx You should be able to set this in your web.config file. If you try this out, I'd be interested in your results.
Brian HoangBrian Hoang

Well, guess what ... it just starts working again (without the change you pointed out). 

If I don't know better, I'd say you guys changed something on your end :)

So what we'd do is if we ever see that problem again, we'd put that config on and we see if that fixes it.

Thanks.

SuperfellSuperfell
We didn't change anything. I'd really like to track down what's causing this.
Brian HoangBrian Hoang
It just happened again.  And yes, we did put in

<system.xml.serialization>
    <dateTimeSerialization mode="Local"/>
 </system.xml.serialization>

in all our config files (heck, that caused us to change our code too as it changed all the date values).

Will keep you posted if we can find a fix.