C# type serialization not as a collection of key value pairs
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
add a comment |
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
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
add a comment |
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
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
serialization serializable datacontract
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
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
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 23 '18 at 1:00
Dave KniseDave Knise
517
517
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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