I'm having trouble deserializing the following XML w/ restsharp
<Xid>
<Id>118</Id>
<Active>true</Active>
<Xid>20</Xid>
<CreatedDate>2011-09-16T18:15:32</CreatedDate>
<CreatedUserId>1782</CreatedUserId>
<ModifiedDate>2011-09-16T18:15:32</ModifiedDate>
<ModifiedUserId>1782</ModifiedUserId>
<TableName>ProjectRate</TableName>
<ObjectId>644</ObjectId>
<SystemGuid>157f2e2d-5e8b-41c7-b932-09c1d75d0ccc</SystemGuid>
</Xid>
I can't use a class named 'Xid' with a member named 'Xid' as there is a conflict in C#. I have tried manually declaring the XmlRoot on the XidClass object, but it doesn't seem to be getting picked up by RestSharp's deserializer. Is there a way to do this with RestSharp, or am I going to need to write a custome deserializer for this particular chunk of xml?
You need to create the class by hand, befoe you can deserialize the XML:
public class Xid
{
public int Id { get; set; }
public bool Active { get; set; }
public int Xid { get; set; }
...
}
The you should be able to deserialize using something like:
Xid xid = xml.Deserialize<Xid>(response);
(Have a look here: Testing the Deserialization of RestSharp without proper REST-Api)
Related
I have an object, Project, that contains many fields, some complex some not. It is an EF class, so I can't edit it to add attributes.
I just want to generate a JSON object containing 2 of the fields (one int (id) and one string (name))
I'd hate to create another ViewModel just for this...
In my viewmodel I have a List<Project>. Is there a way to use HTML helpers to get a JSON representation of only the properties I choose without using attributes?
Here is an example of the Project class:
public class Project
{
public int Id {get; set; } <-- Serialize this
public string Name { get; set; } <-- Serialize this
public Object AnotherObject [ Get; Set; } <-- Ignore this
....
}
I'd like it to become:
[{"id":"27","name":"test1"},{"id":"34","name":"test2"},{"id":"35","name":"test3"}]
The ultimate goal here to is output the json directly to the view as a var so that it can be used in building a JsGrid.
If there is a way to do it with Html helpers, that would be great.
Thanks!
Json.NET has a great built in ignore feature. If you tag the Property you want to exclude with the [JsonIgnore] attribute, the serializer will not serialize that property.
[JsonIgnore]
public bool IsValid { get; set; }
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);
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.)
I am implementing a mongodb cache for this asp.net webapi output cache (I agree redis would be better / faster but for now, I need a mongodb implementation!)
Anyway,
I have a CachedItem class that holds my key / value:
[BsonIgnoreExtraElements]
public class CachedItem
{
[BsonElement("key")]
public string Key { get; set; }
[BsonElement("value")]
public object Value { get; set; }
}
Value is an object, that could be anything, we don't control that.
In one of my tests, I have a very simple poco:
public class UserFixture
{
public UserFixture()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
When this is set to the Value it is serialized and persisted.
When I try to retrieve it, it fails to deserialize, as it has automatically grabbed the "Id" property.
An error occurred while deserializing the Id property of class WebAPI.OutputCache.MongoDb.Tests.UserFixture: Cannot deserialize Guid from BsonType ObjectId
Obviously, I can't decorate UserFixture
Is there any way I can tell MongoDB driver to basically serialize CachedItem.Value, as say, a string?
I could use JSON.net to do this before saving, and deserialize it on the way back out, but I was hoping to avoid this.
It's also on GitHub
That link should take you straight to the relevent commit if you'd like to try the failing test.
You can of course tell MongoDB to serialize your class as a string by building your own custom BsonSerializer. I have found it easier to inherit from their BsonStringSerializer. You also need to register that serializer with your specific type. (I suggest using a BsonSerializationProvider for that)
What you do need to think about is how to represent all your possible data as a string so you could deserialize it back to your application (Consider for example that you probably need to save the type information).
I have a JSON response that I'm trying to deserialize with RestSharp, and it looks like this:
{"devices":[{"device":{"id":7,"deviceid":"abc123","name":"Name"}},
{"device":{"id":1,"deviceid":"def456","name":"Name"}}],
"total":2,
"start":0,
"count":2}
Based off of some suggestions I've found, I've tried to setup my POCO like this:
public class DevicesList
{
public List<DeviceContainer> Devices;
}
public class DeviceContainer
{
public Device Device;
}
public class Device
{
public int Id { get; set; }
public string DeviceId { get; set; }
public string Name { get; set; }
}
And then my execution looks like this:
// execute the request
var response = client.Execute<DevicesList>(request);
However, response.Data is NULL, and I've tried other variations with no luck.
So, what class structure and mapping should be used for this situation? I've also tried this without the extra DeviceContainer class.
Thanks for the help.
I had a slightly different issue when my deserialization POCO contained an array..
Changing it from Devices[] to List<Devices> resolved the issue and it deserialized correctly.
RestSharp only operates on properties, it does not deserialize to fields, so make sure to convert your Devices and Device fields to properties.
Also, double check the Content-Type of the response, if the responses is something non-default, RestSharp may not uses the JsonDeserializer at all. See my answer on RestSharp client returns all properties as null when deserializing JSON response
Something that I ran into is, it does not work if your using interfaces like: IEnumerable or IList, it has to be a concrete type.
This will not work, where as it does for some other json serializers like json.net.
public class DevicesList
{
public IEnumerable<DeviceContainer> Devices { get; set; }
}
public class DeviceContainer
{
...
}
it would have to be something like this:
public class DevicesList
{
public List<DeviceContainer> Devices { get; set; }
}
public class DeviceContainer
{
...
}
RestShartp doesn't support DataAnnotation/DataMember, rename your properties with no maj:
Devices -> devices
Device -> device
AND don't forget the {get; set;} ;).
My problem was entirely different, I naively thought JsonDeserializer supports JsonProperty attribute, but thats not true. So when trying to deserialize into
public class AvailableUserDatasApi
{
[JsonProperty("available-user-data")]
public List<AvailableUserDataApi> AvailableUserDatas { get; set; }
}
it failed.. But changing AvailableUserDatas to AvailableUserData was enough for things to start working.