Issues deserializing with service stack - c#

I am having issues getting a list of an object out of redis using servicestack. The error is 'Type definitions should start with a '{' array....'
using (var redis = _redisService.GetClient())
{
redis.Set(key, myListOfThings.SerializeToString());
}
Appears to be valid formattable JSON in the cache:
[{"id":34,"someid":1012,"stuff":"blah"},{"id":33,"someid":1012,"stuff":"dfsfd"}]
But I am getting an error thrown in retrieval:
using (var redis = _redisService.GetClient())
{
return redis.Get<List<MyThing>>(key);
}
"Additional information: Type definitions should start with a '{',
expecting serialized type 'MyThing', got string starting with: [my
json string from cache]"
I even wrapped it so that the list is a child of a main object, which made the JSON start with a '{' but I still got the same error...
I also tried deserializing to an array, and various methods to deserialize but all within the servicestack library,
Any ideas?
EDIT for anyone else's info
GetValue method should go hand in hand with SetValue and not Set because of the way it does encoding. I still don't know why Get with a type does not deserialize.
redis.Get<DataResponse>(key);
This method seems to do the trick:
redis.Get<string>(key).FromJson<DataResponse>()

Your API usage is unbalanced:
If you're serializing the POCO's yourself and saving the POCO as a string you should be retrieving the value as a string and deserializing it yourself, e.g:
redis.SetValue(key, myListOfThings.ToJson());
var dtos = redis.GetValue(key).FromJson<List<MyThing>>();
If you want to instead let the Redis Client serialize it, then you should be using the equivalent typed API's for doing that instead, e.g:
redis.Set(key, myListOfThings);
var dtos = redis.Get<List<MyThing>>(key);

Related

Which data types can be used when communicating with an App Service in UWP

I have created an UWP app with an app service and communication between those are done using value sets in an AppServiceConnection. I can however not find out what types of data that are supported in the value sets that are transferred.
Here is some test code
class MyClass { public int Prop1 { get; set; } }
var data = new ValueSet();
var stringlist = new List<string>() {"a string"};
// This does not work
// data.Add("data", new MyClass() { Prop1 = 1});
// This does not work
// data.Add("data", stringlist);
// This works fine!!
data.Add("data", stringlist.ToArray());
When using a not supported data type I get the error below, thus it is pretty clear that it is not supported. I can however not find any documentation around this and I cannot find out exactly what is supposed to be supported.
Unhandled Exception: System.Exception: Data of this type is not supported.
(Exception from HRESULT: 0x8007065E)
A second question; is it possible to create a class so that I can use it in the value sets?
You can include all types that can be serialized. So any data type that has a default constructor that takes in 0 arguments and the fields inside them are also serializable or the ones that aren't serializable are DataAnotated as [JsonIgnore] are acceptable.
That being said, it's a safe bet to send in serialized data to the values.
To do so, you can use NewtonSoft nugget for Json serialization from the nugget package store and when you have the data that you need to send (if it's not a string) you serialize the object and then send it and when you receive it you'll get a serialized object that you can deserialize to get the data.

How to parse a collection of unknown JSON object types inside a known JSON structure using JSON.Net?

I am attempting to parse some JSON that has a known top level schema. However inside the schema is one JSON object that can contain various types of JSON objects.
Example
{
"knownfield1": data,
"knownfield2": data,
"knownfieldcollection":
{
"fieldofunknowntype1": "string data",
"fieldofunknowntype2":
{
"subunknownfield1": "string data",
"subunknownfield1": null
},
"fieldofunknowntype3": null
}
}
I would like to make an object that contains a mapping of the known fields, but can read the unknown fields in dynamically. I was trying with Json.Net JToken and JObject, but I could not get it to work. I kept getting recursive JToken exceptions.
Any pointers on this would be great. Thank you.
Exception I am getting:
Type 'Newtonsoft.Json.Linq.JToken' is a recursive collection data
contract which is not supported. Consider modifying the definition of
collection 'Newtonsoft.Json.Linq.JToken' to remove references to itself.
--edit--
Mistyped Collection for object, fixed that.
We have a winner. DBC hit the nail on the head. I had some left over WFC deserialization and it was causing problems. As soon I made sure all the DataContract code was completely cleared out and replaced everything with proper JSON.Net tags and calls, it worked wonderfully.
Thank you everyone for the support.

Is there a way to ignore javascript comments when deserializing BSON objects using the MongoDB C# Driver?

I have a POCO object that is serialized using myObject.ToJson() using the BsonExtensionMethod included in the MongoDB C# Driver. I am taking this string and appending some javascript comments with a textual description and some metadata before persisting it to disk as a .js file.
The object looks like this:
{
// MyObject created 2014-08-18
"name" : "MyObject",
"description" : "Super Cool Object"
}
When I try to deserialize the object using
var myObject = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<MyObject>(json);
I get the error
An unhandled exception of type 'System.IO.FileFormatException' occurred in MongoDB.Bson.dll
Additional information: JSON reader was expecting a name but found '//'.
Is there a way to ignore the javascript comments without manually removing them first? It seems like this should be the default behavior.
NOTE: When I serialize the object using ToJson(), I am also passing in a JsonWriterSettings that inserts line returns, specifies the indent, etc.

.NET deserialization of json fails if __type is not first in property list

I send json objects to DotNet Service in format
{"__type":"EntityItem#ru.test.com","name":"sample"}
And on Net service i got object EntityItem and all good.
But if __type will not first in list properties then it's get error parsing object. Next version JSON crashes
{"name":"sample","__type":"EntityItem#ru.test.com"}
Does exists solution how to fix it?
It's called "type hints". Here is link http://msdn.microsoft.com/en-us/library/bb412170.aspx
and qoute
Note that the type hint must appear first in the JSON representation. This is the only case where order of key/value pairs is important in JSON processing.
It's so sad.

Build a WCF with generic type

I want to build a service that will pass the data read from the database to the client in JSON format. I don't know the schema table and the types.
I thought about implementing the WCF over Dictionary but the JSON is very complicated and contains objects like "key = ...; value = ..." and i want just "key=value" and i need to return list of Dictionary objects. Sometimes from database i will receive a comma separated array, so i will insert in my Dictionary a key with a new Dictionary as value.
In PHP my boss said that it can be done through associative arrays. Please help me with some ideas or link because i don't know where to start to look.
If there is something that you didn't understood please comment and i will try another explanation.
Edits:
I need it to be a rest service, so JSON is mandatory.
How can i load data from the table ? What type can i use ?
Edit #2 : This is what i want to get : CorectJSON
Edit #3 : This is my current json :
stdClass Object
(
[areaGetStreetTypesResult] => stdClass Object
(
[responseMessage] => [{"name":"IMPASSE","street_type":"IMP"}{"name":"LOTISSEMENT","street_type":"LOT"}{"name":"ROUTE","street_type":"RTE"}{"name":"RUE","street_type":"RUE"}]
[response_status] => stdClass Object
(
[message] => Success : JSON created into the responseMessage variable !
[status] => 0
)
)
)
Is not containing some commas between so it cannot be decoded by php. What should i do ?
This is my method Code
I think that doing everything as a dictionary in webservice API is bad practice and I hate when I need to work with API's like this. If it is a WCF, it produces WSDL and WDSL describes the data is going in and out, so if everything is dictionary, WSDL can not provide anything meaningfull, so your datacontracts tell you nothing about the data.
If you need simply forward database data through webservice, WCF has DataServices http://msdn.microsoft.com/en-us/data/bb931106 although I think you should create API that fits your business needs and is not simple proxy between database and your client.
What is the reason why you need to pass JSON? If you want to create a WCF REST service, it is sufficient to tell WCF to create JSON messages as described here: http://www.codeproject.com/Articles/327420/WCF-REST-Service-with-JSON
If you access the service from a C# application, you don't need to care about how data is passed back and forth. Just take "normal" method parameters and use return values like you'd do locally and you're set.
Example:
string[] GetResultStrings(List<Rectangle> sourceRectangles);
If you really need to pass JSON strings, just pass strings and use the JSON serializer and deserializer to encode the reply and decode the parameters.
For example:
string GetJSONString(string jsonRequest);
The following information may help on using the JSON serializer and deserializer: http://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
EDIT
I'm using the following method to serialize serializable objects to JSON:
public static string SerializeJSON(this object obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
This works just fine for any DataContract class like:
[DataContract]
public class MyJSONReturnableClass
{
[DataMember]
public string ThisBecomesANamedString;
[DataMember]
public MyJSONReturnableClass[] AndWorksAlsoForNestedArrays;
}
Populate your dictionary, then serialize it using JSon.
Pass it to your client using WCF or RabbitMq...
JsonConvert.SerializeObject(yourDict);
Download the NewtonSoft.dll
Put using:
using Newtonsoft.Json;

Categories

Resources