I'm in the process of making a RESTful client (consumption side) and so far I have all my requests and responses fairly consistent. I have something like this:
public class RESTClient
{
public T Execute<T>(RESTRequest request);
}
My RESTRequest
contains things like the base URI, authentication, resource URI and any object(s) to serialize. So far so good, until I came across a situation where the result can't be deserialized to a concrete type. This result is a collection of, for example, SomeClass
with (at the same level) the number of results in the collection. So let's say SomeClass
looks like this:
public class SomeClass
{
public int Id { get; set; }
public string Name { get; set; }
}
If I request the specific resource, then it deserializes perfectly fine - but I can't do that unless I have the ID, so for that I need to get it from a list that when requested returns JSON that looks like this:
{
"-1":
{
"id": -1,
"name": "There is *always* a -1 in the collection as default"
},
"3":
{
"id": 3,
"name": "This would be one I've added later"
},
"recordsCount": 2
}
So as you can see the ID of the object is the name of the object... and at the same level we have recordsCount
which is just an int
.
My first attempt was (as I'm working with JSON.Net) was to go through the result as JObject
first, check if the name of the current object matched my selector and then do another request for SomeClass
by ID to get the nicely deserialized concrete class. Basically trawling through the JSON until I find something I can deserialize to my target class.
After refactoring the first attempt (and decoupling my serializer from JSON.Net) I decided to pass in a custom serializer (say SomeClassSerializer
) via the RESTRequest
itself, so in most cases I can use the basic JSON <--> Concrete
version, and when I need to I can override it with this specific one.
My actual questions are:
IEnumerable<TWeirdType>
.Cheers for any help.
It was a lot simpler (and more obvious) than I initially thought... I wanted a solution that would keep my RESTClient
and JSON.Net loosely coupled, and I can do just that with JsonConverter
(which is part of JSON.Net but the logic is outside of my client and all happens through type).
What I've got instead is:
public interface IMySerializer
{
string Serialize<T>(T target);
T Deserialize<T>(string json);
}
Which is used by my RESTClient
with a concrete type of BasicJsonSerializer
(which has JSON.Net's serializer inside it) and this custom converter (passed through JsonSerializerSettings
).
public IEnumerableSomeClassConverter : JsonConverter
{
public override bool CanConvert(Type objectType) {}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Handle the weirdness here and return my IEnumerable
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {}
}
Handling it very well.