C# type serialization not as a collection of key value pairs












0















I have a class that when serialized, I want to return as a single string without key value pairs. A string becomes a string. An int becomes an int. How do I make my class become a string?



Looking at DataContract and Serializable, it doesn't look that this is possible. The SerializationInfo.AddValue(name, value) setup forces your whole object into a key-value approach. I just want to return "A and B".



[DataContract]
public class MyObject
{
public int A { get; set; }
public int B { get; set; }
}


When serialized using the DataContractJsonSerializer, for example, I want it to be:



4 and 2


Not



{
"A": 4,
"B": 2
}


So let's say I have a parent class that uses both of these custom types:



[DataContract]
public class Parent
{
[DataMember]
public MyObject One { get; set; }

[DataMember]
public MyObject Two { get; set; }
}


I want to it serialize like this:



{
"One": "4 and 2",
"Two": "6 and 8"
}


Instead, the only thing I seem to be able to make it do is:



{
"One": {
"A": 4,
"B": 2
},
"Two": {
"A": 6,
"B": 8
}
}


The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.



Can I serialize a type as a single return value? Or do all types besides built-in ones like int and string have to serialize to an object?










share|improve this question























  • docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

    – Dave Knise
    Nov 22 '18 at 21:56


















0















I have a class that when serialized, I want to return as a single string without key value pairs. A string becomes a string. An int becomes an int. How do I make my class become a string?



Looking at DataContract and Serializable, it doesn't look that this is possible. The SerializationInfo.AddValue(name, value) setup forces your whole object into a key-value approach. I just want to return "A and B".



[DataContract]
public class MyObject
{
public int A { get; set; }
public int B { get; set; }
}


When serialized using the DataContractJsonSerializer, for example, I want it to be:



4 and 2


Not



{
"A": 4,
"B": 2
}


So let's say I have a parent class that uses both of these custom types:



[DataContract]
public class Parent
{
[DataMember]
public MyObject One { get; set; }

[DataMember]
public MyObject Two { get; set; }
}


I want to it serialize like this:



{
"One": "4 and 2",
"Two": "6 and 8"
}


Instead, the only thing I seem to be able to make it do is:



{
"One": {
"A": 4,
"B": 2
},
"Two": {
"A": 6,
"B": 8
}
}


The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.



Can I serialize a type as a single return value? Or do all types besides built-in ones like int and string have to serialize to an object?










share|improve this question























  • docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

    – Dave Knise
    Nov 22 '18 at 21:56
















0












0








0


1






I have a class that when serialized, I want to return as a single string without key value pairs. A string becomes a string. An int becomes an int. How do I make my class become a string?



Looking at DataContract and Serializable, it doesn't look that this is possible. The SerializationInfo.AddValue(name, value) setup forces your whole object into a key-value approach. I just want to return "A and B".



[DataContract]
public class MyObject
{
public int A { get; set; }
public int B { get; set; }
}


When serialized using the DataContractJsonSerializer, for example, I want it to be:



4 and 2


Not



{
"A": 4,
"B": 2
}


So let's say I have a parent class that uses both of these custom types:



[DataContract]
public class Parent
{
[DataMember]
public MyObject One { get; set; }

[DataMember]
public MyObject Two { get; set; }
}


I want to it serialize like this:



{
"One": "4 and 2",
"Two": "6 and 8"
}


Instead, the only thing I seem to be able to make it do is:



{
"One": {
"A": 4,
"B": 2
},
"Two": {
"A": 6,
"B": 8
}
}


The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.



Can I serialize a type as a single return value? Or do all types besides built-in ones like int and string have to serialize to an object?










share|improve this question














I have a class that when serialized, I want to return as a single string without key value pairs. A string becomes a string. An int becomes an int. How do I make my class become a string?



Looking at DataContract and Serializable, it doesn't look that this is possible. The SerializationInfo.AddValue(name, value) setup forces your whole object into a key-value approach. I just want to return "A and B".



[DataContract]
public class MyObject
{
public int A { get; set; }
public int B { get; set; }
}


When serialized using the DataContractJsonSerializer, for example, I want it to be:



4 and 2


Not



{
"A": 4,
"B": 2
}


So let's say I have a parent class that uses both of these custom types:



[DataContract]
public class Parent
{
[DataMember]
public MyObject One { get; set; }

[DataMember]
public MyObject Two { get; set; }
}


I want to it serialize like this:



{
"One": "4 and 2",
"Two": "6 and 8"
}


Instead, the only thing I seem to be able to make it do is:



{
"One": {
"A": 4,
"B": 2
},
"Two": {
"A": 6,
"B": 8
}
}


The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.



Can I serialize a type as a single return value? Or do all types besides built-in ones like int and string have to serialize to an object?







serialization serializable datacontract






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 '18 at 21:55









Dave KniseDave Knise

517




517













  • docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

    – Dave Knise
    Nov 22 '18 at 21:56





















  • docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

    – Dave Knise
    Nov 22 '18 at 21:56



















docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

– Dave Knise
Nov 22 '18 at 21:56







docs.microsoft.com/en-us/dotnet/standard/serialization/… For the record, this is the documentation I've been reading. It does not (as far as I can see) instruct on how to do this. Only key value pairs as it assumes all serialization of a type breaks down into one or more DataMembers.

– Dave Knise
Nov 22 '18 at 21:56














2 Answers
2






active

oldest

votes


















0














You can simply add a get attribute that returns the attributes as a string in any way that you like...



public class MyObject
{
public int A { get; set; }
public int B { get; set; }
public string MyNewStringAttribute {
get{
return A + " and " + B;
}
}
}


Then, when you can serialize from the controller using the new attribute from an array, linq, etc.






share|improve this answer
























  • Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

    – Dave Knise
    Nov 23 '18 at 0:30













  • [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

    – spadelives
    Nov 23 '18 at 19:38











  • > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

    – Dave Knise
    Nov 26 '18 at 16:31



















0














My answer: You can't.



The parent class, MyObject has to implement ISerializable to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.



[Serializable]
public class Parent : ISerializable
{
public MyObject One { get; set; }

public MyObject Two { get; set; }

public (SerializerInfo info, SerializerContext context)
{
string oneString = info.GetString("One");
One = new MyObject(oneString);

string twoString = info.GetString("Two");
Two = new MyObject(twoString);
}

public override void GetObjectData(SerializerInfo info, SerializerContext context)
{
info.AddValue("One", One.ToString());
info.AddValue("Two", Two.ToString());
}
}


Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438381%2fc-sharp-type-serialization-not-as-a-collection-of-key-value-pairs%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You can simply add a get attribute that returns the attributes as a string in any way that you like...



    public class MyObject
    {
    public int A { get; set; }
    public int B { get; set; }
    public string MyNewStringAttribute {
    get{
    return A + " and " + B;
    }
    }
    }


    Then, when you can serialize from the controller using the new attribute from an array, linq, etc.






    share|improve this answer
























    • Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

      – Dave Knise
      Nov 23 '18 at 0:30













    • [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

      – spadelives
      Nov 23 '18 at 19:38











    • > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

      – Dave Knise
      Nov 26 '18 at 16:31
















    0














    You can simply add a get attribute that returns the attributes as a string in any way that you like...



    public class MyObject
    {
    public int A { get; set; }
    public int B { get; set; }
    public string MyNewStringAttribute {
    get{
    return A + " and " + B;
    }
    }
    }


    Then, when you can serialize from the controller using the new attribute from an array, linq, etc.






    share|improve this answer
























    • Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

      – Dave Knise
      Nov 23 '18 at 0:30













    • [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

      – spadelives
      Nov 23 '18 at 19:38











    • > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

      – Dave Knise
      Nov 26 '18 at 16:31














    0












    0








    0







    You can simply add a get attribute that returns the attributes as a string in any way that you like...



    public class MyObject
    {
    public int A { get; set; }
    public int B { get; set; }
    public string MyNewStringAttribute {
    get{
    return A + " and " + B;
    }
    }
    }


    Then, when you can serialize from the controller using the new attribute from an array, linq, etc.






    share|improve this answer













    You can simply add a get attribute that returns the attributes as a string in any way that you like...



    public class MyObject
    {
    public int A { get; set; }
    public int B { get; set; }
    public string MyNewStringAttribute {
    get{
    return A + " and " + B;
    }
    }
    }


    Then, when you can serialize from the controller using the new attribute from an array, linq, etc.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 '18 at 22:27









    spadelivesspadelives

    1,2031120




    1,2031120













    • Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

      – Dave Knise
      Nov 23 '18 at 0:30













    • [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

      – spadelives
      Nov 23 '18 at 19:38











    • > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

      – Dave Knise
      Nov 26 '18 at 16:31



















    • Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

      – Dave Knise
      Nov 23 '18 at 0:30













    • [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

      – spadelives
      Nov 23 '18 at 19:38











    • > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

      – Dave Knise
      Nov 26 '18 at 16:31

















    Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

    – Dave Knise
    Nov 23 '18 at 0:30







    Do you mean serialize it so you have: ` { "One": { "A": 4, "B": 2, "C": "4 and 2" }, "Two": { "A": 6, "B": 8, "C": "6 and 8" } } ` That is not the desired experience.

    – Dave Knise
    Nov 23 '18 at 0:30















    [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

    – spadelives
    Nov 23 '18 at 19:38





    [DataContract] public class Parent { [DataMember] public MyObject One { get{ return MyNewStringAttribute; } ... [DataMember] public MyObject Two { get{ return MyNewStringAttribute; } ... }

    – spadelives
    Nov 23 '18 at 19:38













    > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

    – Dave Knise
    Nov 26 '18 at 16:31





    > The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.

    – Dave Knise
    Nov 26 '18 at 16:31













    0














    My answer: You can't.



    The parent class, MyObject has to implement ISerializable to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.



    [Serializable]
    public class Parent : ISerializable
    {
    public MyObject One { get; set; }

    public MyObject Two { get; set; }

    public (SerializerInfo info, SerializerContext context)
    {
    string oneString = info.GetString("One");
    One = new MyObject(oneString);

    string twoString = info.GetString("Two");
    Two = new MyObject(twoString);
    }

    public override void GetObjectData(SerializerInfo info, SerializerContext context)
    {
    info.AddValue("One", One.ToString());
    info.AddValue("Two", Two.ToString());
    }
    }


    Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.






    share|improve this answer




























      0














      My answer: You can't.



      The parent class, MyObject has to implement ISerializable to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.



      [Serializable]
      public class Parent : ISerializable
      {
      public MyObject One { get; set; }

      public MyObject Two { get; set; }

      public (SerializerInfo info, SerializerContext context)
      {
      string oneString = info.GetString("One");
      One = new MyObject(oneString);

      string twoString = info.GetString("Two");
      Two = new MyObject(twoString);
      }

      public override void GetObjectData(SerializerInfo info, SerializerContext context)
      {
      info.AddValue("One", One.ToString());
      info.AddValue("Two", Two.ToString());
      }
      }


      Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.






      share|improve this answer


























        0












        0








        0







        My answer: You can't.



        The parent class, MyObject has to implement ISerializable to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.



        [Serializable]
        public class Parent : ISerializable
        {
        public MyObject One { get; set; }

        public MyObject Two { get; set; }

        public (SerializerInfo info, SerializerContext context)
        {
        string oneString = info.GetString("One");
        One = new MyObject(oneString);

        string twoString = info.GetString("Two");
        Two = new MyObject(twoString);
        }

        public override void GetObjectData(SerializerInfo info, SerializerContext context)
        {
        info.AddValue("One", One.ToString());
        info.AddValue("Two", Two.ToString());
        }
        }


        Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.






        share|improve this answer













        My answer: You can't.



        The parent class, MyObject has to implement ISerializable to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.



        [Serializable]
        public class Parent : ISerializable
        {
        public MyObject One { get; set; }

        public MyObject Two { get; set; }

        public (SerializerInfo info, SerializerContext context)
        {
        string oneString = info.GetString("One");
        One = new MyObject(oneString);

        string twoString = info.GetString("Two");
        Two = new MyObject(twoString);
        }

        public override void GetObjectData(SerializerInfo info, SerializerContext context)
        {
        info.AddValue("One", One.ToString());
        info.AddValue("Two", Two.ToString());
        }
        }


        Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 1:00









        Dave KniseDave Knise

        517




        517






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438381%2fc-sharp-type-serialization-not-as-a-collection-of-key-value-pairs%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Paul Cézanne

            UIScrollView CustomStickyHeader Resize height generates problems when scroll is too fast

            Angular material date-picker (MatDatepicker) auto completes the date on focus out