ServiceStack Json deserializing incorrectely - c#

I've got a RequestDto, let's say Class A Dto, it contains a self defined type property:
// C# code
public Class MyObject
{
public string A { get; set; }
public string B { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
When I am trying to send the Dto using Json, the Json object looks like this:
{"MO":[{"A":"String","B":"a"},{"A":"String","B":"b"}]}
but the object I am receiving will be null.
However if I change the Json string into:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
I lose the quotation marks on the objects' names and it works.
The correct format of Json should include those quotation marks right?
Why is this happening?

ServiceStack does serializes and deserializes valid JSON which requires every property name to be quoted however you're saying that the text below works:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
However this isn't valid JSON, it instead looks like ServiceStack's JSV Format
You haven't mentioned where you're sending the JSV Format or have provided the Raw HTTP Request (for us to work it out), but I'm assuming if you're using Postman (mentioned in your comments) than you're trying to send JSON in the ?QueryString which isn't allowed.
But ServiceStack does support sending complex object graphs on the QueryString using JSV.
Since you're sending a complex type you'd either POST the request as either JSON or www-form-urlencoded Form Data or if you want to pass it in the QueryString you need to convert it to JSV.
In future please include the Raw HTTP Request as this question lacks any context on where you're changing the JSON string, how you're trying to use it or what's actually being sent, where you're sending it to, etc - making it impossible to guess what the issue is.

Change your class to
public Class MyObject
{
public string Mobile { get; set; }
public string Name { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
Then your json should be
{MO:[{Mobile:"0556604",Name:"Peter"},{Mobile:"4565466",Name:"John"}]}

Related

Parse heterogeneous JSON objects

I send JSON objects from a client to a server. In the server I need to do some action based on the object type. I could send a filed type in every request then try to parse JSON against base Message class:
public class Message
{
string type { get; set; }
}
...
JsonSerializer.Deserialize<Message>(data);
then read the type and deserialize again:
public class SpecificMessage : Message
{
public string command;
}
var message = JsonSerializer.Deserialize<SpecificMessage>(data);
But it requires the data to be parsed twice.
I thought about solution like adding message type in front of JSON message but then thought that maybe it's not worth to reinvent the wheel.

Deserialize JSON response using Newtonsoft.Json

I have a web service which return response in JSON format as below.
{"123":{"Name":"Abcd", "Age":"30"},"231":{"Name":"xyz", "Age":"20"}, "543":{"Name":"pqr", "Age":"35"}}
I want to deserialize this response in C# and wants to display it.
How can I do with Newtonsoft.Json library.
Please help me.
I'm going to assume that "123", "231", and "543" are identifiers and not constant property names. In that case what you have is a dictionary of objects. First, define a class that maps to the object.
public class Something
{
public string Name { get; set; }
public string Age { get; set; }
}
Then deserialize into a dictionary of those objects.
var whatever = JsonConvert.DeserializeObject<Dictionary<string, Something>>(json);

How to ignore data in JSON.NET that changes between returns

I'm parsing JSON data return by a third party.
I have my class generated with JSON2CSharp which works for the first sample we received. I tweaked it to have some JsonProperty settings so that it doesn't require certain properties that are not always present.
Now I received more samples and one of the datablobs changed format
from needing
public Translations Translations { get; set; }
to
public List<Translations> Translations { get; set; }
The blob however is information we do not need, for both performance and not having to deal with that and other pieces of information we do not need changing format, it would be ideal to just ignore it when deserializing it.
Now the real question is, should "JsonIgnore" just ignore the entire blob of data irregardless if it is in a different format then defined in the class? Or do I have to program around that?
So if I do
[JsonIgnore]
public string Translations { get; set; }
will it also ignore Translations when it gets sent a list or an object?
Can I use the same syntax with JsonIgnore as I can with JsonProperty and just say
[JsonIgnore(PropertyName = "translations")]
or does JsonIgnore just toss out anything it receives?
Additionally question:
Is it convention that when there are no translations, I get:
"translations":[]
and when there are translations I get:
"translations":{"CA":"blabla","DD":"C : blablah"}
Or is this likely a bug in the third party's website?
ADDED:
1: The Translations can switch between string, list and object between every fetch of the JSON.
2: For using DataMembers ignoring everything I don't actually need, in a class with subclasses, do I have to tell it that the subclass is [DataMember] or the subclasses properties are [DataMember]?
I would explicitly specify exactly the properties I wanted serialized/deserialized in my data class using DataContractAttribute and DataMemberAttributes for the members you actually want to deserialize.
This is opt in, so no attempt is made to shoehorn anything extra in your JSON into your data class, and anything extra in your data class doesn't show up in serialized JSON.
So assuming your class right now looks like this:
class MyData {
// Old member
// public Translations Translations { get; set; }
public List<Translation> Translations { get; set; }
public string ThisShouldBeSerialized { get; set; }
}
You can change it so things that you want serialized are explicitly marked as such, and anything not marked for serialization is ignored by default:
[DataContract]
class MyData {
// Old member
// public Translations Translations { get; set; }
public List<Translation> Translations { get; set; }
[DataMember]
public string ThisShouldBeSerialized { get; set; }
}
And then:
var myJSON = #"{
'ThisShouldBeSerialized': 'test',
'Translations': {
'Some' : 'Strange',
'Data' : 'Blob'
}
}";
var result = JsonConvert.DeserializeObject<MyData>(myJSON);

Deserializing of Google's Translate API result in C#

I'm trying to deserialize Google's Translate API JSON response into an C# object using JavaScriptSerializer. However, it always says Type 'TranslateAPI.Models.Translations' is not supported for deserialization of an array.. I double checked whether I have correctly created models for this object and it seems right. Here are my models:
TranslateResult
public TranslateData data { get; set; }
TranslateData
public Translations translations { get; set; }
Translations
public TranslatedText[] translatedText { get; set; } // I have also tried List<TranslatedText> which also doesn't work
TranslatedText
public string translatedText { get; set; }
The json returned from Google looks like this:
{data: {
translations: [
{translatedText: "Hello world"}
]
}
Any idea what I'm doing wrong?
Thanks
PS. It could be useful to mention, that I'm deserializing it like so: TranslateResult translateResult = js.Deserialize <TranslateResult>(json);
I suspect you don't need the Translations class at all. You've got:
An object containing a data property
The data property value is an object containing a translations property
The translations property value is an array
Each element of the array is an object with a translatedText property
So that sounds to me like your TranslateData class should be:
TranslateData
public Translation[] translations { get; set; }
Translation // Renamed from TranslatedText
public string translatedText { get; set }
(I'd also recommend that you rename the properties to follow normal C# naming conventions, and then apply attributes to help with the JSON conversion if you need to. I haven't used JavaScriptSerializer for a while, but I'm sure it's feasible. You shouldn't need to work with nasty property names in your C# code.)

JSON RPC Serializing Object with SPECIFIC naming

Im using NewtonSoft linq 2 json to serialize objects from classes straight to a json string
The class object I'm using is very simple :
public class OverviewQuery
{
public string id { get; set; }
public string method { get; set; }
public string Params { get; set; }
public OverviewQuery(string sid, string smethod, string sparam)
{
this.id = sid;
this.method = smethod;
this.Params = sparam;
}
}
If I serialise this, I get the Json string :
"{\"id\":\"1\",\"method\":\"getStockItemDetails\",\"Params\":\"0000000002\"}"
The Oracle server I'm connecting to (through WebAPI's) requires me to use very very specific naming,
here it should be
"{\"id\":\"1\",\"method\":\"getStockItemDetails\",\"Params\":[\"0000000002\"]}"
Is there any way NewtonSoft implemented a way to achieve this formatting ?
Without correct formatting, the only way to send the information is through hardcoding everything..
What the serialiser is doing with your class seems straightforward.
Generally JSON-RPC services will require that the params value in the envelope be a JSON Array (for indexed parameters) or an Object (for named parameters).
Could you just change your class such that Params is an Array of String ?

Categories

Resources