This is a migrated thread and some comments may be shown as answers.

Additional text found in JSON string

25 Answers 2171 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Sulu
Top achievements
Rank 1
Sulu asked on 02 May 2014, 12:41 PM
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;

25 Answers, 1 is accepted

Sort by
0
Anton Dobrev
Telerik team
answered on 02 May 2014, 01:44 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 09 May 2014, 01:38 PM
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
0
Anton Dobrev
Telerik team
answered on 12 May 2014, 02:59 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 12 May 2014, 04:40 PM
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.}


    
0
Anton Dobrev
Telerik team
answered on 13 May 2014, 02:11 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 13 May 2014, 02:13 PM
Cool, Anton, I'm trying it right now. Thanks!
0
Sulu
Top achievements
Rank 1
answered on 13 May 2014, 02:23 PM
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: 
0
Sulu
Top achievements
Rank 1
answered on 13 May 2014, 02:25 PM
Incidentally, my Newtonsoft DLL is version: v4.0.30319. Just for more info.
0
Anton Dobrev
Telerik team
answered on 13 May 2014, 03:14 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 13 May 2014, 05:58 PM
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
0
Sulu
Top achievements
Rank 1
answered on 15 May 2014, 01:01 PM
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;
       }
0
Anton Dobrev
Telerik team
answered on 15 May 2014, 03:14 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 16 May 2014, 07:39 PM
That's certainly reasonable. I'll check and make sure I'm loading the wrong Newtonsoft DLL. Many many thanks!
0
Sulu
Top achievements
Rank 1
answered on 20 May 2014, 01:33 PM
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));
            }
        }
    }
}
0
Anton Dobrev
Telerik team
answered on 23 May 2014, 12:07 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 23 May 2014, 01:40 PM
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
0
Anton Dobrev
Telerik team
answered on 27 May 2014, 10:15 AM

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.
 
0
Sulu
Top achievements
Rank 1
answered on 27 May 2014, 02:23 PM
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
0
Anton Dobrev
Telerik team
answered on 29 May 2014, 04:38 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 02 Jun 2014, 01:02 PM
Thank you, Anton! I'm trying it out right now.  -sulu
0
Sulu
Top achievements
Rank 1
answered on 02 Jun 2014, 08:16 PM
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
0
Sulu
Top achievements
Rank 1
answered on 04 Jun 2014, 07:33 PM
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
0
Anton Dobrev
Telerik team
answered on 09 Jun 2014, 02:57 PM
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.
 
0
Sulu
Top achievements
Rank 1
answered on 09 Jun 2014, 04:33 PM
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
0
Anton Dobrev
Telerik team
answered on 12 Jun 2014, 12:34 PM
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.
 
Tags
General Discussions
Asked by
Sulu
Top achievements
Rank 1
Answers by
Anton Dobrev
Telerik team
Sulu
Top achievements
Rank 1
Share this question
or