I have a JSON Schema, and a class library.
I am able to serialize this class, then convert back successfully to object.
To test it, I create a random object, serialize it.
Then convert to object and check its validity.
And deserialize it just to be sure about the values.
The code below works perfectly - but
I want to be absolutely sure that the class library represents the Json Schema.
Is there a way to achieve this? I found some online tools tries to create the class library from given schema, but none of them were so useful.
// Create random object.
MyObject myObject = new MyObject().CreateRandomMyObject();
// Serialize it.
string JSONObjectText = JsonConvert.SerializeObject(myObject);
// Check if schema is valid.
JSchema schema = JSchema.Parse(txtSchema.Value);
// Check if the serialized object is valid for schema.
JObject jsonObject = JObject.Parse(JSONObjectText);
IList<string> errorMessages;
bool valid = jsonObject.IsValid(schema, out errorMessages);
// Check if the serialized object can be deserialized.
MyObject myObjectReDeserialized = (MyObject)JsonConvert.DeserializeObject(JSONObjectText, typeof(MyObject), new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error });
A way to do test-oriented assertion of your mapping is to use FsCheck to generate plenty of random objects and then assert what you want to hold from them: in this case, that
their serialization is valid given the schema,
they can be deserialized back to the same object. (You should make sure you are using structural equality there.)
To be precise, such approach only checks that everything described by your objects is representable by the schema. You might want to do the other way also -- that every JSON that conforms to the schema is representable by your objects. Again, you can generate many possible JSONs conforming to the schema and check that
they can be deserialized to your objects,
reserialization of those objects gives you the same JSON you started with.
Beware though, this might not be practical: FsCheck probably don't have some nice, first-class support for JSON schema based generation out-of-the-box.
If the schema you have is going to change in the future, it would be really great to have a way to generate corresponding objects to have strong types even at the boundary of your application. Have you tried Swagger Codegen? Swagger describes it's endpoints using subset of JSON Schema. The corresponding tooling might help you.
Related
I am working on a project that communicates a lot of data with a server. This data is in a json format. We end up creating a lot of dummy objects to parse the json data. This leads to having a lot of classes that just contain class members. Is there a better way of doing things?
thanks
Assuming that you are using NewtonSoft's JSON parser or something similar, you have a couple of choices here. The usual use case here is to deserialize to a named type, thus:
var parsedMessage = JsonConvert.DeserializeObject<Message>(content.AsString());
If you have many types for each differnet JSON message type you wish to receive and wish to avoid to, you can do the following:
var parsedMessage = JsonConvert.DeserializeObject<dynamic>(content.AsString());
This will give you a dynamic object that you can inspect and should also work given other Json libraries. Alternatively, NetwtonSoft also provides the following method:
public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject);
This will allow you to deserialize to an anonymously typed object rather than a dynamic object.
I have defined a class and i need to store some objects of that class for future reference. Can i store these objects into an azure database i've created ?
In order to save an object (instance of a Class) to whatever medium (SQL Server, Azure SQL Database, Azure Table Storage, Blob Storage, local File System, whatever you come up with), you will need to serialize it. Then store the result of serialization to the medium of your choice. Next, when you want to use the persisted state of the object, you will have to deserialize it.
There are different serialization formatters, like XML, JSON, Binary, etc. Which one to use, depends on the where and how you are going to store the object. The most important however, is that, in order one object to be serialized, the defining Class should be marked with SerializableAttribute. And the drama begins when you want to serialize object which is part of 3rd partys API.
If it is your type - just mark it as Serializbale, serialize and store it. Pretty stright-forward process.
If you don't have access to the source code to explicitly mark class as Serializable, you could possibly use the Serialization Surrogate to serialize your object. But, you might have issues when deserializing. For example, if the API Class you use does not have a public contructor. Or if it does not provide setters for some of the properties, etc., etc. At the end, if a Type is not designed to be serializable, and is part of 3rd party API, there might be a ton of reasons serialization/deserialization might fail.
At the end, you could try using the Json.NET serializer (install via NuGet):
var someObj = new DummyClass
{
ID = Guid.NewGuid(),
IntID = 102934,
Name = "My Super Hero Name"
};
string json = JsonConvert.SerializeObject(someObj);
Console.WriteLine(json);
var otherObj = JsonConvert.DeserializeObject<DummyClass>(json);
Console.WriteLine(otherObj.ID);
Console.ReadKey();
and check if it correctly serializes/deserializes your object. If everything is fine - use the json string to save it into Database of your choice.
I have some JSON data :-
{
"mail":"mitch#domain.com",
"givenName":"User",
"sn":"Name",
"uid":"mitch",
"gecos":"User Name"
}
What I'm trying to do is de-serialize this into a List<KeyValuePair<string,string>>
I would normally do a dictionary, however some key's may be duplicated - this is the representation that is automatically generated by .NET when I pass a List<KeyValuePair<string,string>> object into the System.Web.Script.Serialization.JavaScriptSerializer class.
When I just plug the serialized object into the System.Web.Script.Serialization.JavaScriptDeserializer I get a empty response back.
From what I can see it should not be possible using the JavaScriptSerializer. The only way for customizing its behavior is by means of a JavaScriptConverter class, that will allow you to customize the serialization/deserialization process. Unfortunately both methods will pass an IDictionary for the properties, therefore the duplicated names are already merged. You might want to look into either a different format for your JSON or a different serialization library such as JSON.net which is way more customizable.
I'm looking for a JSON parser and encoder for .NET that can parse JSON into its own data structure which I can then navigate, as opposed to directly deserializing it into a class. In Java, I use Jettison's JSONObject and JSONArray which is dead easy to use.
There are a number of reasons why I don't want to (de)serialize:
Serializers tend to add metadata to the JSON and require that metadata for deserialization (e.g. fastJSON and JSON.NET add type info).
I don't want the hassle of having to create a bunch of classes to handle all the different types of data. Also, I want to be able to ignore fields I'm not interested in rather than have to add properties to them.
Is there anything available or do I have to port a subset of Jettison?
The disadvantages of serialization that you point out aren't really there, at least in the case of JSON.NET:
JSON.NET doesn't add any metadata by default. You can tell it to add the metadata if you need it (for example, when one property can hold values of different types), but it's optional.
You replace the hassle of creating classes with the hassle of working with strings and casts and I think that's much worse. Also, you can ignore fields you're not interested in, just don't add them to your types.
But, if you really want to do that, you can. The equivalent types are JObject and JArray, so, if you want to deserialize some object, use:
JObject obj = JsonConvert.DeserializeObject<JObject>(json);
As another option, you don't have to specify the type you want at all, ant it will return either JObject or JArray:
object objectOrArray = JsonConvert.DeserializeObject(json);
I have some very similar XML structures which are in fact quite distinct, but it appears that XmlSerializer.Deserialize is very "forgiving" and will go out of its way to take XML and deserialize out into a strongly typed object I created from the source XSDs. Is there any way to make it more strict or do some type of deeper validation?
// Locals
var serializer = new XmlSerializer(typeof(SomeCustomType));
// Set
var someInstance = serializer.Deserialize(new StringReader(xmlString.ToString()))
#Jeff Because the root nodes are similar it will deserialize into completely different objects. Imagine that you have a house, car and boat and they all share a base root node called item with a few attributes. Even though sub-nodes are invalid and unshared it seems to overlook and forgive that.
#Will I don't want to validate against the XSD. I want to somehow cause the Deserializer to see that the data it has shouldn't be shoe-horned into the wrong Object type.
The problem was that the XML input was incorrect.
I once used validating reader to validate XML against schema as I read it into the deserializer.