Deserializing object throws "Sequence contains more than one element " error

Aug 6, 2009 at 9:41 PM
Edited Aug 6, 2009 at 9:59 PM

Hello,

I've been getting stuck trying to deserialize an object - even a DeserializeObject call directly on the output of SerializeObject seems to generate errors. I'm using Json.NET 3.0. I suspect that I'm one level of indirection away from what I want, but I can't figure out the exact problem. Below is the string and the errors with various calls.

Thanks!

 

 

{"sublocation":"AlertEmailSender.Program.Main","userId":0,"type":0,"summary":"Loading settings variables","details":null,"stackTrace":"   at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n   at System.Environment.get_StackTrace()\r\n   at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n   at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25","tag":null,"time":"\/Date(1249591032026-0400)\/"}

 

 

Newtonsoft.Json.JavaScriptConvert.DeserializeObject(Of List(Of [Event]))("[" & sEvent & "]")
System.InvalidOperationException - Sequence contains more than one element 

Newtonsoft.Json.JavaScriptConvert.DeserializeObject(Of List(Of [Event]))(sEvent)
Newtonsoft.Json.JsonSerializationException - Could not find member 'sublocation' on object of type 'RuntimeType'  

Newtonsoft.Json.JavaScriptConvert.DeserializeObject(Of [Event])("[" & sEvent & "]")
System.Exception - Cannot create and populate list type Logging.Event.  

Newtonsoft.Json.JavaScriptConvert.DeserializeObject(Of [Event])(sEvent)
System.InvalidOperationException - Sequence contains more than one element

Coordinator
Aug 7, 2009 at 9:45 AM

I can't find out is wrong without the source code for Event.

Aug 7, 2009 at 3:27 PM
Edited Aug 7, 2009 at 3:31 PM

OK, here it is. Apologies that it's in VB.NET, we're a migrating shop:

 

Imports System.Web
Imports Newtonsoft.Json

Namespace Logging
    ''' <summary>
    ''' What types of events are there? Just sticking to a basic set of four for now.
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum EventType
        Debug = 0
        Info = 1
        Warning = 2
        [Error] = 3
    End Enum

    <DebuggerDisplay("\{ sublocation = {sublocation}, userId = {userId}, type = {type}, summary = {summary}, details = {details}, stackTrace = {stackTrace}, tag = {tag} \}")> _
    <Serializable()> _
        Public NotInheritable Class [Event]

        ''' <summary>
        ''' If no current user is specified, returns Nothing (0 from VB)
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function GetCurrentUserId() As Integer
...
        End Function

        ''' <summary>
        ''' Gets either the application path or the current stack trace.
        ''' NOTE: You MUST call this from the top level entry point. Otherwise,
        ''' the stack trace will be buried in Logger itself.
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function GetCurrentSubLocation() As String
...
        End Function

        Private _sublocation As String
        Private _userId As Integer
        Private _type As EventType
        Private _summary As String
        Private _details As String
        Private _stackTrace As String
        Private _tag As String
        Private _time As DateTime

        Public Sub New(ByVal summary As String)
            _summary = summary
            _time = DateTime.Now

            If _userId = Nothing Then _userId = GetCurrentUserId()
            If _sublocation Is Nothing Then _sublocation = GetCurrentSubLocation() 'This call only works at top level for now.
            'If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace
        End Sub

        Public Sub New(ByVal sublocation As String, ByVal userId As Integer, ByVal type As EventType, ByVal summary As String, ByVal details As String, _
ByVal stackTrace As String, ByVal tag As String) _sublocation = sublocation _userId = userId _type = type _summary = summary _details = details _stackTrace = stackTrace _tag = tag _time = DateTime.Now If _userId = Nothing Then _userId = GetCurrentUserId() If _sublocation Is Nothing Then _sublocation = GetCurrentSubLocation() 'If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace End Sub Public Overrides Function ToString() As String Return String.Format("{{ sublocation = {0}, userId = {1}, type = {2}, summary = {3}, details = {4}, stackTrace = {5}, tag = {6} }}", _sublocation, _
_userId, _type, _summary, _details, _stackTrace, _tag) End Function Public Property sublocation() As String Get Return _sublocation End Get Set(ByVal value As String) _sublocation = value End Set End Property Public Property userId() As Integer Get Return _userId End Get Set(ByVal value As Integer) _userId = value End Set End Property Public Property type() As EventType Get Return _type End Get Set(ByVal value As EventType) _type = value End Set End Property Public Property summary() As String Get Return _summary End Get Set(ByVal value As String) _summary = value End Set End Property Public Property details() As String Get Return _details End Get Set(ByVal value As String) _details = value End Set End Property Public Property stackTrace() As String Get Return _stackTrace End Get Set(ByVal value As String) _stackTrace = value End Set End Property Public Property tag() As String Get Return _tag End Get Set(ByVal value As String) _tag = value End Set End Property Public ReadOnly Property time() As DateTime Get Return _time End Get End Property End Class End Namespace

 

Aug 12, 2009 at 7:28 PM
using System.Web;
using Newtonsoft.Json;
using System;

namespace Logging
{
    /// <summary>
    /// What types of events are there? Just sticking to a basic set of four for now.
    /// </summary>
    /// <remarks></remarks>
    public enum EventType
    {
        Debug = 0,
        Info = 1,
        Warning = 2,
        Error = 3
    }
   
    [Serializable()]
    public sealed class Event
    {
       
        /// <summary>
        /// If no current user is specified, returns Nothing (0 from VB)
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static int GetCurrentUserId()
        {
            return 0;
        }
       
        /// <summary>
        /// Gets either the application path or the current stack trace.
        /// NOTE: You MUST call this from the top level entry point. Otherwise,
        /// the stack trace will be buried in Logger itself.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static string GetCurrentSubLocation()
        {
            return "";
        }
       
        private string _sublocation;
        private int _userId;
        private EventType _type;
        private string _summary;
        private string _details;
        private string _stackTrace;
        private string _tag;
        private DateTime _time;
       
        public Event(string summary)
        {
            _summary = summary;
            _time = DateTime.Now;
           
            if (_userId == 0) _userId = GetCurrentUserId();
                //This call only works at top level for now.
                //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace
            if (_sublocation == null) _sublocation = GetCurrentSubLocation();
        }
       
        public Event(string sublocation, int userId, EventType type, string summary, string details, string stackTrace, string tag)
        {
            _sublocation = sublocation;
            _userId = userId;
            _type = type;
            _summary = summary;
            _details = details;
            _stackTrace = stackTrace;
            _tag = tag;
            _time = DateTime.Now;
           
            if (_userId == 0) _userId = GetCurrentUserId();
                //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace
            if (_sublocation == null) _sublocation = GetCurrentSubLocation();
        }
       
        public override string ToString()
        {
            return string.Format("{{ sublocation = {0}, userId = {1}, type = {2}, summary = {3}, details = {4}, stackTrace = {5}, tag = {6} }}", _sublocation, _userId, _type, _summary, _details, _stackTrace, _tag);
        }
       
        public string sublocation {
            get { return _sublocation; }
            set { _sublocation = value; }
        }
        public int userId {
            get { return _userId; }
            set { _userId = value; }
        }
        public EventType type {
            get { return _type; }
            set { _type = value; }
        }
        public string summary {
            get { return _summary; }
            set { _summary = value; }
        }
        public string details {
            get { return _details; }
            set { _details = value; }
        }
        public string stackTrace {
            get { return _stackTrace; }
            set { _stackTrace = value; }
        }
        public string tag {
            get { return _tag; }
            set { _tag = value; }
        }
        public DateTime time {
            get { return _time; }
        }
    }
}
Coordinator
Aug 15, 2009 at 2:19 AM

The problem is Event has no default constructor and multiple constructors with arguments. Json.NET doesn't know which constructor to use.

I'll make the error message more descriptive.

Aug 17, 2009 at 3:53 PM

That explains it, thanks!