Additional text found in JSON string

26 posts, 0 answers
  1. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 02 May 2014 Link to this post

    When I try to run my .NET app to talk to Telerik Backend Services, I see this exception:
    Telerik.Everlive.Sdk.Core.Transport.EverliveException: Additional text found in JSON string after finishing deserializing object. ---> Newtonsoft.Json.JsonSerializationException: Additional text found in JSON string after finishing deserializing object.
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
       at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
       at Telerik.Everlive.Sdk.Core.Transport.JsonResponse.GetResultAsEnumerable[T](Type objectType)
       --- End of inner exception stack trace ---

    I was wondering if anyone had seen this before and what I could do to fix it. It happens when I try to fetch records from the backend, like this:

     var timesheets = Task.Run<IEnumerable<Timesheet>>(async () =>
                    {
                        TimeSpan timespanvalue = new TimeSpan(72, 0, 0);
                        DateTime dt = DateTime.Now.Subtract(timespanvalue);
                        // DateTime test = new DateTime(2014, 4, 1, 0, 0, 0, DateTimeKind.Local);
                        var temp =  await app.WorkWith().Data<Timesheet>().Get().Where(timesheet => timesheet.StartTime > dt).IncludeFields(t =>
                            t.Id).IncludeFields(t => t.Employee).IncludeFields(t => t.StartTime).IncludeFields(t => t.Type).IncludeFields(t => t.Latitude).IncludeFields(t => t.Longitude).IncludeFields(t => t.Location).ExecuteAsync();   //IncludeFields(t => t.Location).IncludeFields(t=>t.StartTime).IncludeFields(t=>t.Type).IncludeFields(t=>t.CreatedAt).IncludeFields(t => t.ModifiedAt).ExecuteAsync();
                        return temp;
                    }).Result;
  2. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 02 May 2014 Link to this post

    Hi,

    Unfortunately, this code will not be sufficient to isolate why is this exception thrown. Hopefully, the message of the exception appears to be quite informative. The exception is thrown at the time of deserialization from JSON string to .NET objects. It is thrown by the Newtonsoft.JSON lib used by Everlive for JSON serialization.

    The block that retrieves the data looks pretty much valid. Could you please verify the mapping between the content type and the .NET model class? Probably the mapping is forcing some JSON fields to deserializing but they does not exist. Are you casting the fetched timesheets (IEnumerable<Timesheet>) to another type?

    Could you please provide some screenshots of several JSON objects before deserializing and the .NET model?

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  3. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 09 May 2014 in reply to Anton Dobrev Link to this post

    You asked if I was casting the IEnumerable<Timesheet> to another type. Well, not really, however, I am enumerating this way: 
    var timesheets = GetTimesheets(app);
    foreach (Timesheet t in timesheets)
    {
     // etc.

    Does the enumeration constitute some kind of inferred cast?

    I have also checked the mapping of the fields to the Everlive database, and it matches. Would getting only certain fields and excluding others have any bearing on the problem. (My gut says it can't, but I thought I'd ask.)

    -sulu
  4. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 12 May 2014 Link to this post

    Hello Sulu,

    Unfortunately we were unable to reproduce the exception on our side. Could you please provide the exact model class for the Timesheet entity?

    Indeed, excluding/Including certain fields is unlikely to be the cause for the exception.

    In addition, you can specify the desired subset of fields in the following, more convenient way:
    .IncludeFields(t => new { t.Employee, t.AuditInfo, t.Type}).ExcludeFields(t => t.Id)

    EDIT:
    This expression will return all selected fields and exclude the 'Id' which is always returned by default. In all other cases you need to use either an IncludeFields (returns all specified fields) or an ExcludeFields (returns all but the specified fields) expression. 

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  5. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 12 May 2014 in reply to Anton Dobrev Link to this post

    Hi, Anton! 
    Here is the class. I noticed that if I restrict the getter method excessively by limiting it to one day's worth of data, I can get data back. But if I want to see 72 hours worth, I get an aggregation exception. -sulu


    01.public class Timesheet : DataItem, IComparable
    02.{   
    03.    // Property Id
    04.    public Guid Id { get; set; }
    05. 
    06.    // Property CreatedAt
    07.    public DateTime CreatedAt { get; set; }
    08. 
    09.    // Property ModifiedAt
    10.    public DateTime ModifiedAt { get; set; }
    11. 
    12.    // Property CreatedBy
    13.    public Users CreatedBy { internal get; set; }
    14.     
    15.    // Property ModifiedBy
    16.    public Users ModifiedBy { internal get; set; }
    17. 
    18.    // Property Owner
    19.    public Users Owner { internal get; set; }
    20. 
    21.    // Property IsOnClock
    22.    public int IsOnClock { get; set; }
    23. 
    24.    // Property Location
    25.    public GeoPoint Location { get; set; }
    26. 
    27.    public double Latitude { get; set; }
    28.    public double Longitude { get; set; }
    29. 
    30.    // Property Note
    31.    public string Note { get; set; }
    32. 
    33.    // Property ServiceOrder
    34.    public IEnumerable<ServiceOrder> ServiceOrder { internal get; set; }
    35. 
    36.    // Property StartTime
    37.    public DateTime StartTime { get; set; }
    38. 
    39.    // Property Title
    40.    public string Title { get; set; }
    41. 
    42.    // Property Type
    43.    public int Type { get; set; }
    44. 
    45.    // Property Worker
    46.    //public Users Worker { get; set; }
    47. 
    48.    public string Employee { get; set; }
    49. 
    50.    public string KnownLocation { get; set; }
    51. 
    52.    public string AuditInfo { get; set; }
    53. 
    54.    public string Text { get; set; }
    55. 
    56.    public int CompareTo(Object obj)
    57.    {
    58.        if (obj.GetType() != typeof(Timesheet))
    59.        {
    60.            return 0;
    61.        }
    62. 
    63.        Timesheet comparor = (Timesheet)obj;
    64.        return Employee.CompareTo(comparor.Employee);
    65.    }
    66. 
    67.}


        
  6. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 13 May 2014 Link to this post

    Hello Sulu,

    We have tried to reproduce the error in various ways but to no avail. Please, find attached a simple console app that we used for testing (currently is it is stripped down only to the code you have provided). Probably you would not mind to commit to the project continuously the missing parts until the problem can be reproduced and return it to us?

    The API key for the backend app is not included in the project, you need to enter it manually in order to test it.

    One thing we have noticed is that there are items whose "IsOnClock" field is set to a boolean, and others have this field set to an integer. Though it is unlikely the cause, you may consider adding some consistency to all values, as this may impact the filtering on this field.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  7. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 13 May 2014 in reply to Anton Dobrev Link to this post

    Cool, Anton, I'm trying it right now. Thanks!
  8. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 13 May 2014 in reply to Sulu Link to this post

    Interesting... I'm seeing the same exact Aggregation exception in trying the console app. (FYI, I pasted in our API key to the noted place in the Program.cs). Here are the exception details:
    System.AggregateException was unhandled
      HResult=-2146233088
      Message=One or more errors occurred.
      Source=mscorlib
      StackTrace:
           at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
           at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
           at System.Threading.Tasks.Task`1.get_Result()
           at TimesheetsConsoleApp.Program.GetTimesheets() in c:\Users\sllewellyn.CREATIVEMICRO\Documents\Visual Studio 2012\Projects\TimesheetsConsoleApp\Program.cs:line 26
           at TimesheetsConsoleApp.Program.Main() in c:\Users\sllewellyn.CREATIVEMICRO\Documents\Visual Studio 2012\Projects\TimesheetsConsoleApp\Program.cs:line 15
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: Telerik.Everlive.Sdk.Core.Transport.EverliveException
           HResult=-2146233088
           Message=Current error context error is different to requested error.
           Source=Telerik.Everlive.Sdk
           Code=10001
           StackTrace:
                at Telerik.Everlive.Sdk.Core.Transport.JsonResponse.GetResultAsEnumerable[T](Type objectType)
                at Telerik.Everlive.Sdk.Core.Facades.Read.GetByFilterFacade`1.GetResult(Response response)
                at Telerik.Everlive.Sdk.Core.Facades.RequestFacade`1.<>c__DisplayClass7.<TryExecute>b__6(Response response)
                at Telerik.Everlive.Sdk.Core.EverliveConnection.<>c__DisplayClass1.<ExecuteRequest>b__0(Response response)
                at Telerik.Everlive.Sdk.Communicator.GetResponseStream[T](IAsyncResult result)
             --- End of stack trace from previous location where exception was thrown ---
                at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
                at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
                at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
                at TimesheetsConsoleApp.Program.<<GetTimesheets>b__0>d__4.MoveNext() in c:\Users\sllewellyn.CREATIVEMICRO\Documents\Visual Studio 2012\Projects\TimesheetsConsoleApp\Program.cs:line 31
           InnerException: System.InvalidOperationException
                HResult=-2146233079
                Message=Current error context error is different to requested error.
                Source=Newtonsoft.Json
                StackTrace:
                     at Newtonsoft.Json.Serialization.JsonSerializerInternalBase.GetErrorContext(Object currentObject, Object member, String path, Exception error)
                     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
                     at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
                     at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
                     at Telerik.Everlive.Sdk.Core.Transport.JsonResponse.GetResultAsEnumerable[T](Type objectType)
                InnerException: 
  9. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 13 May 2014 in reply to Sulu Link to this post

    Incidentally, my Newtonsoft DLL is version: v4.0.30319. Just for more info.
  10. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 13 May 2014 Link to this post

    Hi Sulu,

    Thank you for verifying this.

    Could you please log to the console the assembly version of the Newtonsoft.JSON? Snippet:
    var assemblyVersion = typeof(JObject).Assembly;
     
    Console.WriteLine(assemblyVersion);

    The working project is using Newtonsoft.Json, Version=4.5.0.0.

    We assume that the app is loading the Newtonsoft.JSON.dll from the GAC and the loaded version is somehow not completely compatible with the .NET SDK.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  11. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 13 May 2014 in reply to Anton Dobrev Link to this post

    This is what it printed out:
         Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed

    I do think it has something to do with Newtonsoft... just not sure what yet.
    Thanks so much!
    -sulu
  12. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 15 May 2014 in reply to Sulu Link to this post

    Hmmm. Even just getting a simple count of records generates the System.Aggregate exception. Here's the function that does this:
    private int GetTimesheetCount(EverliveApp app)
           {
               if (app != null)
               {
                   int count =
                       Task.Run<int>(async () =>
                       {
                           return await app.WorkWith().Data<Timesheet>().GetCount().ExecuteAsync();
                       }).Result;
     
                   return count;
               }
               return 0;
           }
  13. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 15 May 2014 Link to this post

    Hello Sulu,

    We are sorry to hear that you are still experiencing these issues.

    This last function worked seamlessly with us.

    Actually, we managed to reproduce the "Additional text..." exception by installing the latest JSON.NET assembly from NuGet. After the installation, the exception was thrown at the moment of fetching the items from the backend. Trying to get the count worked though. Uninstalling the JSON assembly package via the NuGet PM and reverting back to the version included with the .NET SDK worked again.

    Could you please verify if there is no other JSON assembly loaded, for example, from some controls or frameworks that you are using that can cause some compatibility issues? Do you have the chance to run the console app at another workstation? Also, I have noticed some similar posts by you in the Telerik Forums, did you manage to solve the issues back then?

    Please, keep us posted with the results.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  14. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 16 May 2014 in reply to Anton Dobrev Link to this post

    That's certainly reasonable. I'll check and make sure I'm loading the wrong Newtonsoft DLL. Many many thanks!
  15. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 20 May 2014 Link to this post

    Hi, Anton!
    I found a solution to this problem that seems to have solved it. I wanted to pass it on to you in case someone else runs into it.
    You have to override the ReadJson method. I found this on Stack Overflow:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;
     
    namespace SomeNamespaceHere
    {
        public class StringEnumConverterEx : StringEnumConverter
        {
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                // the message in the response, once an serialization exception is thrown, after the version 4.5.1 of Newtonsoft.JSON library,
                // has changed. As we do not want to expose the full namespace of our Enums, we are catching the exception and re-throwing it
                // with a different message.
                try
                {
                    return base.ReadJson(reader, objectType, existingValue, serializer);
                }
                catch (JsonSerializationException)
                {
                    string values = objectType.IsEnum ? String.Join(",", Enum.GetNames(objectType)) : string.Empty;
     
                    throw new JsonSerializationException(string.Format("Error converting value {0}, possible values are: {1}",
                        objectType.Name, values));
                }
            }
        }
    }
  16. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 23 May 2014 Link to this post

    Hello Sulu,

    Thank you for sharing this! However, we'd rather recommend to developers to make sure they are using the Newtonsoft.Json.dll coming with the .NET SDK build.

    I suppose that this is the original link to Stack Overflow, could you please confirm?

    Did you manage to isolate the cause for the problem, was it some specifics of the referenced version of the dll?

    We have updated your Telerik Points as a token of gratitude for your commitment.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  17. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 23 May 2014 in reply to Anton Dobrev Link to this post

    Hi, Anton! Well, I perhaps jumped to conclusions. (I am so impulsive!) Anyways, the link to the Stack Overflow article is correct. My manager took a look at my code and warned me that I could be masking the underlying issue. So, I'm taking a second look at the Timesheet table and how we interpret the fields. So here's the summary of what I've found so far:
    (1) If I restrict the number of records returned, I don't see the exception.
    (2) I need to go over the fields in the table one more time and make sure that I've mapped over to .NET fields in the class correctly.
    (3) And, since I do have a way to reproduce it, (by getting more days' worth of data), I can try debugging down into my application. Since the AggregationException points to multiple errors, I'll just have to go over it more detail and more carefully.

    You mentioned that the correct Netwonsoft.Json.dll should come from the .NET SDK build. I'll go look for that. The latest one I have was from CodePlex. I suspect I still have the wrong one.
    So that is where I'm at. (Thanks for the points!)  -sulu
  18. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 27 May 2014 Link to this post

    Hello Sulu,

    Below are some guidelines that might help you in the debugging process.

    1. Probably there are some discrepancies in the structure of the items on a database-level.  Continuing on point 1 and 2 : You can verify if the fields of your content type are of the same type in all entries. Here is how to do this:

    • Compose the following filter object:
      {"IsOnClock" : { "$type" : 8}}
    • Send it as as the value of a X-Everlive-Filter header to api.everlive.com/v1/{{ApiKey}}/Timesheet via Postman or Fiddler.
    • Verify if the amount of retrieved records matches the count of all records in the table. Otherwise, the field's type is not consistent across the entire dataset.

    The different types of fields are explained in this article : MongoDB Query Element Operators - $type.

    2. You can download the latest version of the .NET SDK from the Downloads section for Backend Services in your Telerik Platform account. The compatible version of Newtonsoft.JSON.dll is included in the archive.

    Please, let us know if this helps.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  19. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 27 May 2014 in reply to Anton Dobrev Link to this post

    Hi, Anton! I'll give it a try. Should I zip up my project in case you'd like to take a look? I just don't know how to get it to you. -sulu
  20. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 29 May 2014 Link to this post

    Hi Sulu,

    The only way to upload a project so that it remains private would be to submit a support ticket. This option depends on your license.

    Alternatively, I can suggest that you prepare a basic project that illustrates the issue and post it here without including the API key for the backend project.

    In addition, we are planning to introduce a custom build of the .NET SDKs with the Newtonsoft.JSON.dll included internally. With this build we aim to protect our customers from such issues with referenced other incompatible versions of the Newtonsoft.JSON library.

    In this case, the developers will need to reference only the dll of the Backend Services .NET SDK for working with Backend Services. At the same time they can continue to use the other Newtonsoft.JSON version where needed throughout the same project.

    Please, find attached a unofficial, beta version of this build. The official version will be available from the Downloads section of the Telerik Platform portal.

    Please, keep us posted with your progress.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  21. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 02 Jun 2014 in reply to Anton Dobrev Link to this post

    Thank you, Anton! I'm trying it out right now.  -sulu
  22. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 02 Jun 2014 in reply to Sulu Link to this post

    Hi, Anton! I ran a test of the DLL and it seems to be working. I'll do some further testing, but I think Telerik's plan to incorporate the Newtonsoft features is a fantastic idea!
    -sulu
  23. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 04 Jun 2014 in reply to Sulu Link to this post

    Hi, Anton!
    Well, I ran into the problem with the beta build of Telerik that you provided me. But it only happens if I try to introduce a copy constructor to my Timesheet class.

    I'm going to work around the problem and take out the copy constructor.

    -sulu
  24. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 09 Jun 2014 Link to this post

    Hello Sulu,

    Thank you for specifying this. We are also making some further adjustments to the .NET SDK.

    Is everything up and running now on your side?

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
  25. Sulu
    Sulu avatar
    34 posts
    Member since:
    Aug 2013

    Posted 09 Jun 2014 in reply to Anton Dobrev Link to this post

    Hello, Anton. Everything is running okay right now.  I'll be doing some further, more detailed testing. Would you like me to keep you posted on such details? Or am I wearing you out?  :) 

    -sulu
  26. Anton Dobrev
    Admin
    Anton Dobrev avatar
    539 posts

    Posted 12 Jun 2014 Link to this post

    Hello Sulu,

    Yes please, do not hesitate to contact us if any issues or technical questions occur.

    Further, we have now officially integrated the Newtonsoft.Json library in our .NET SDK. The latest build can be downloaded from the Downloads > Backend Services > .NET or Windows Phone sections in your Telerik Platform account.

    With this integration you no longer need to reference Newtonsoft.Json.dll in your projects when you use the Telerik Backend Services .NET SDK distributions.

    If you are using the Newtonsoft.Json library in your project outside the scope of Backend Services, you can use whatever version fits your project, it will not conflict with the internal version in the Backend Services SDK.

    Please, let us know if this works for you.

    Regards,
    Anton Dobrev
    Telerik
     
    Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
     
Back to Top