Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. serialization / type cast differs between service and console execution

serialization / type cast differs between service and console execution

Scheduled Pinned Locked Moved C#
debuggingquestionjson
11 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JudyL_MD
    wrote on last edited by
    #1

    I've got a service than runs on two machines and communicates back and forth through a socket connection. To make debugging easier, I've wrapped the OnStart and OnStop stuff inside a console program. The only difference in the two running instances is a) how the exe starts (SCM versus double-clicking the console exe) and b) the account the exe runs in (LocalSystem versus current user). Actual code of the "guts" of the program is the same. When the following runs with two consoles communicating, everything is fine. When it runs with a console app on one machine talking to a service on the other, it fails on the indicated line, throwing a System.InvalidCastException with the message unable to cast object of type 'OverarchingServer.DerivedMessage' to type 'OverarchingServer.DerivedMessage' A breakpoint in the debugger of the running service at the line in question shows that msg IS of the expected 'DerivedMessage' type and the fields are fully and correctly populated. The exception thrown indicates the types ARE the same. So why can't I do the type cast? I haven't tried service to service yet - that is rather difficult to set up on my development system. Besides, I want to know why this doesn't work when run this way. Any ideas? Thanks, Judy

    namespace ClientMessages
    {
    [Serializable]
    abstract public class BaseMessageClass
    {
    // common stuff of type int, string and an enum
    public int type;
    }
    }

    namespace OverarchingServer
    {
    using ClientMessages;

    public enum MessageTypeEnum : int
    {
        DerivedMessageType = 1,
        AnotherType,
        YetAnotherType
    }
    
    \[Serializable\]
    public class DerivedMessage : BaseMessageClass
    {
        // specific stuff including a structure { Guid, string, int } and an enum
    }
    
    public class SendingServer
    {
        private Socket client;      // opened in code not shown
    
        public void DoingWork ()
        {
            DerivedMessage msg = new DerivedMessage ();
            // fill the fields
            this.Send (msg);
        }
    
        public void Send (BaseMessageClass msg)
        {
            MemoryStream mem = new MemoryStream ();
            BinaryFormatter bf = new BinaryFormatter ();
    
            bf.Serialize (mem, msg);
            byte\[\] data = mem.ToArray ();
    
            NetworkStream stream = new NetworkStream (this.client);
            BinaryWriter binWrite = new BinaryWriter (stream);
    
            binWrit
    
    J D 2 Replies Last reply
    0
    • J JudyL_MD

      I've got a service than runs on two machines and communicates back and forth through a socket connection. To make debugging easier, I've wrapped the OnStart and OnStop stuff inside a console program. The only difference in the two running instances is a) how the exe starts (SCM versus double-clicking the console exe) and b) the account the exe runs in (LocalSystem versus current user). Actual code of the "guts" of the program is the same. When the following runs with two consoles communicating, everything is fine. When it runs with a console app on one machine talking to a service on the other, it fails on the indicated line, throwing a System.InvalidCastException with the message unable to cast object of type 'OverarchingServer.DerivedMessage' to type 'OverarchingServer.DerivedMessage' A breakpoint in the debugger of the running service at the line in question shows that msg IS of the expected 'DerivedMessage' type and the fields are fully and correctly populated. The exception thrown indicates the types ARE the same. So why can't I do the type cast? I haven't tried service to service yet - that is rather difficult to set up on my development system. Besides, I want to know why this doesn't work when run this way. Any ideas? Thanks, Judy

      namespace ClientMessages
      {
      [Serializable]
      abstract public class BaseMessageClass
      {
      // common stuff of type int, string and an enum
      public int type;
      }
      }

      namespace OverarchingServer
      {
      using ClientMessages;

      public enum MessageTypeEnum : int
      {
          DerivedMessageType = 1,
          AnotherType,
          YetAnotherType
      }
      
      \[Serializable\]
      public class DerivedMessage : BaseMessageClass
      {
          // specific stuff including a structure { Guid, string, int } and an enum
      }
      
      public class SendingServer
      {
          private Socket client;      // opened in code not shown
      
          public void DoingWork ()
          {
              DerivedMessage msg = new DerivedMessage ();
              // fill the fields
              this.Send (msg);
          }
      
          public void Send (BaseMessageClass msg)
          {
              MemoryStream mem = new MemoryStream ();
              BinaryFormatter bf = new BinaryFormatter ();
      
              bf.Serialize (mem, msg);
              byte\[\] data = mem.ToArray ();
      
              NetworkStream stream = new NetworkStream (this.client);
              BinaryWriter binWrite = new BinaryWriter (stream);
      
              binWrit
      
      J Offline
      J Offline
      JudyL_MD
      wrote on last edited by
      #2

      Oops forgot ... Windows XP and .NET 3.5

      Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

      1 Reply Last reply
      0
      • J JudyL_MD

        I've got a service than runs on two machines and communicates back and forth through a socket connection. To make debugging easier, I've wrapped the OnStart and OnStop stuff inside a console program. The only difference in the two running instances is a) how the exe starts (SCM versus double-clicking the console exe) and b) the account the exe runs in (LocalSystem versus current user). Actual code of the "guts" of the program is the same. When the following runs with two consoles communicating, everything is fine. When it runs with a console app on one machine talking to a service on the other, it fails on the indicated line, throwing a System.InvalidCastException with the message unable to cast object of type 'OverarchingServer.DerivedMessage' to type 'OverarchingServer.DerivedMessage' A breakpoint in the debugger of the running service at the line in question shows that msg IS of the expected 'DerivedMessage' type and the fields are fully and correctly populated. The exception thrown indicates the types ARE the same. So why can't I do the type cast? I haven't tried service to service yet - that is rather difficult to set up on my development system. Besides, I want to know why this doesn't work when run this way. Any ideas? Thanks, Judy

        namespace ClientMessages
        {
        [Serializable]
        abstract public class BaseMessageClass
        {
        // common stuff of type int, string and an enum
        public int type;
        }
        }

        namespace OverarchingServer
        {
        using ClientMessages;

        public enum MessageTypeEnum : int
        {
            DerivedMessageType = 1,
            AnotherType,
            YetAnotherType
        }
        
        \[Serializable\]
        public class DerivedMessage : BaseMessageClass
        {
            // specific stuff including a structure { Guid, string, int } and an enum
        }
        
        public class SendingServer
        {
            private Socket client;      // opened in code not shown
        
            public void DoingWork ()
            {
                DerivedMessage msg = new DerivedMessage ();
                // fill the fields
                this.Send (msg);
            }
        
            public void Send (BaseMessageClass msg)
            {
                MemoryStream mem = new MemoryStream ();
                BinaryFormatter bf = new BinaryFormatter ();
        
                bf.Serialize (mem, msg);
                byte\[\] data = mem.ToArray ();
        
                NetworkStream stream = new NetworkStream (this.client);
                BinaryWriter binWrite = new BinaryWriter (stream);
        
                binWrit
        
        D Offline
        D Offline
        Dave Kreskowiak
        wrote on last edited by
        #3

        Move your message classes (everything used by more than one project) to another project and reference that project from both your server service project and your console project.

        A guide to posting questions on CodeProject[^]
        Dave Kreskowiak

        J 1 Reply Last reply
        0
        • D Dave Kreskowiak

          Move your message classes (everything used by more than one project) to another project and reference that project from both your server service project and your console project.

          A guide to posting questions on CodeProject[^]
          Dave Kreskowiak

          J Offline
          J Offline
          JudyL_MD
          wrote on last edited by
          #4

          I'll try that at work tomorrow ... I'm guessing the point you're making is ... the same namespace in the same DLL running on both machines, versus the exact same namespace compiled into two distinct executables. My question is then, how will it deal with versioning? The messages can, and mostly likely will, change with the version of the program suite. I'll then have the same namespace in two differently versioned DLLs -- two different DLLs containing differently versioned messages on the two machines. They must still exchange messages, with the versioning controlled by the support in serialization. Am I going to have the same issue then? Judy

          Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

          M 1 Reply Last reply
          0
          • J JudyL_MD

            I'll try that at work tomorrow ... I'm guessing the point you're making is ... the same namespace in the same DLL running on both machines, versus the exact same namespace compiled into two distinct executables. My question is then, how will it deal with versioning? The messages can, and mostly likely will, change with the version of the program suite. I'll then have the same namespace in two differently versioned DLLs -- two different DLLs containing differently versioned messages on the two machines. They must still exchange messages, with the versioning controlled by the support in serialization. Am I going to have the same issue then? Judy

            Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

            M Offline
            M Offline
            Mycroft Holmes
            wrote on last edited by
            #5

            Hah another RAH fan :) I would think that if your message structure changes so dramatically that it cannot inherit from the original there is a fault in the design! I would expect it to become another message type.

            Never underestimate the power of human stupidity RAH

            J 1 Reply Last reply
            0
            • M Mycroft Holmes

              Hah another RAH fan :) I would think that if your message structure changes so dramatically that it cannot inherit from the original there is a fault in the design! I would expect it to become another message type.

              Never underestimate the power of human stupidity RAH

              J Offline
              J Offline
              JudyL_MD
              wrote on last edited by
              #6

              I wouldn't say it would change dramatically, but for a given release one message out of the 25 or so total may add a single field. That's why I wanted to use the versioning support in serialization. I've done this lots of times before, but those were C / C++ program where I did it manually with just simple byte transfers where I would read a length, a type, a version and then deal with putting the different versions into the the message that came out of the receive function. Wasn't C# supposed to make this stuff easier? ... handling versioning (mostly) for you, and the ability to serialize and transfer something beyond an agnostic byte stream. If I can't even have the exact same code compiled into a different executable unit and have something in that namespace transfer between those units, I'll just trash the C# serialize portion of the transfer and go back to doing it manually. I must be able to have different versions running on different machines communicate with each other. What I'm trying to do can't be that unusual. Do I need to transfer structures instead of classes? I've only been doing C# for about 2 years -- I've got the feeling I'm just missing something ... Judy

              Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

              M D 2 Replies Last reply
              0
              • J JudyL_MD

                I wouldn't say it would change dramatically, but for a given release one message out of the 25 or so total may add a single field. That's why I wanted to use the versioning support in serialization. I've done this lots of times before, but those were C / C++ program where I did it manually with just simple byte transfers where I would read a length, a type, a version and then deal with putting the different versions into the the message that came out of the receive function. Wasn't C# supposed to make this stuff easier? ... handling versioning (mostly) for you, and the ability to serialize and transfer something beyond an agnostic byte stream. If I can't even have the exact same code compiled into a different executable unit and have something in that namespace transfer between those units, I'll just trash the C# serialize portion of the transfer and go back to doing it manually. I must be able to have different versions running on different machines communicate with each other. What I'm trying to do can't be that unusual. Do I need to transfer structures instead of classes? I've only been doing C# for about 2 years -- I've got the feeling I'm just missing something ... Judy

                Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

                M Offline
                M Offline
                Mycroft Holmes
                wrote on last edited by
                #7

                I think I may be missing something as, while I use WCF, I don't do any messaging as such. I use Dave's method of externalising the models (I use Silverlight) and reference them from both client and service. I have not had any issues with differing versions, I do know a missing field in the sent object is ignored by the deserialiser and ends up with a null value.

                Never underestimate the power of human stupidity RAH

                1 Reply Last reply
                0
                • J JudyL_MD

                  I wouldn't say it would change dramatically, but for a given release one message out of the 25 or so total may add a single field. That's why I wanted to use the versioning support in serialization. I've done this lots of times before, but those were C / C++ program where I did it manually with just simple byte transfers where I would read a length, a type, a version and then deal with putting the different versions into the the message that came out of the receive function. Wasn't C# supposed to make this stuff easier? ... handling versioning (mostly) for you, and the ability to serialize and transfer something beyond an agnostic byte stream. If I can't even have the exact same code compiled into a different executable unit and have something in that namespace transfer between those units, I'll just trash the C# serialize portion of the transfer and go back to doing it manually. I must be able to have different versions running on different machines communicate with each other. What I'm trying to do can't be that unusual. Do I need to transfer structures instead of classes? I've only been doing C# for about 2 years -- I've got the feeling I'm just missing something ... Judy

                  Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

                  D Offline
                  D Offline
                  Dave Kreskowiak
                  wrote on last edited by
                  #8

                  I haven't used binary serialization but XML will try to fill in all the data it can from the serialization data. If there's a field that isn't there in the data, it just won't get filled. If there is an extra field in the data that doesn't have a coresponding field in the object, it gets ignored. ...IIRC...

                  A guide to posting questions on CodeProject[^]
                  Dave Kreskowiak

                  J 1 Reply Last reply
                  0
                  • D Dave Kreskowiak

                    I haven't used binary serialization but XML will try to fill in all the data it can from the serialization data. If there's a field that isn't there in the data, it just won't get filled. If there is an extra field in the data that doesn't have a coresponding field in the object, it gets ignored. ...IIRC...

                    A guide to posting questions on CodeProject[^]
                    Dave Kreskowiak

                    J Offline
                    J Offline
                    JudyL_MD
                    wrote on last edited by
                    #9

                    Moving the messages into their own namespace in their own DLL fixed the problem. I tested the versioning as well and it works fine. Looks like C# doesn't consider identically defined elements of an identically named namespace to be the same if they come out of two different executable units (i.e. my two original different EXEs); but they are the same if they come out of two different versions of the same executable unit (i.e. the new DLL). Thanks Dave!! Judy

                    Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

                    D 1 Reply Last reply
                    0
                    • J JudyL_MD

                      Moving the messages into their own namespace in their own DLL fixed the problem. I tested the versioning as well and it works fine. Looks like C# doesn't consider identically defined elements of an identically named namespace to be the same if they come out of two different executable units (i.e. my two original different EXEs); but they are the same if they come out of two different versions of the same executable unit (i.e. the new DLL). Thanks Dave!! Judy

                      Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

                      D Offline
                      D Offline
                      Dave Kreskowiak
                      wrote on last edited by
                      #10

                      Part of the fully qualified name of the object is the assembly its defined in. Two assemblies can have the namespace names in them but still be different objects.

                      A guide to posting questions on CodeProject[^]
                      Dave Kreskowiak

                      J 1 Reply Last reply
                      0
                      • D Dave Kreskowiak

                        Part of the fully qualified name of the object is the assembly its defined in. Two assemblies can have the namespace names in them but still be different objects.

                        A guide to posting questions on CodeProject[^]
                        Dave Kreskowiak

                        J Offline
                        J Offline
                        JudyL_MD
                        wrote on last edited by
                        #11

                        That explains it then! I'll add that tidbit to the C# file in my brain. Would have been nice if the exception message showed the fully-qualified name instead of telling me that 'x' couldn't be typecast to 'x' ;P

                        Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups