I have a list which contains elements of class type which contains a property
[DataMember]
public DateTime? DateOfBirth { get; set; }
im serializing the whole list to a file like so:
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
serializer.NullValueHandling = NullValueHandling.Ignore;
using (StreamWriter sw = new StreamWriter(#"c:\json.txt"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, _myList);
}
and when i try to deserialize like so:
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
string text = System.IO.File.ReadAllText(#"c:\json.txt");
_myList = JsonConvert.DeserializeObject<List<UserInformation>>(text);
I'm getting the following error:
Error setting value to 'DateOfBirth' on 'Namespace'.
EDIT -
Json Looks like: "DateOfBirth":new Date(-1459735200000) (i couldn't find how it looks when DateOfBirth == null)
I'm a beginner using Json, and im having difficulty understanding it as it is, can someone explain to me what is the problem and how do i fix this?
Thanks in advance
if you use the newtonsoft library, then you could add a nice little generic method to Deserializeyour json:
public T Deserialize<T>(string json)
{
try
{
var value = Newtonsoft.Json.JsonConvert
.DeserializeObject<T>(json);
return value;
}
catch (Exception ex)
{
// examine the ex.Message here if required
}
return default(T);
}
This may take you a step closer
Since I didn't get an answer that helped me, I'll post what solution I've used to solve this. I didn't really want to do this but I had to change DateTime to long, and save the Ticks instead, and when i need the date i can convert like so
DateTime dt = new DateTime(long ticks);
Related
I have classes generated from xsd that i would like to use to create an xml to send over the wire. I just want to create the document in memory, convert it to string/byte[] and send it. I was under the impression that once the classes are populated, i could just do a tostring() and it would return the entire document out. That doesn't seem to be the case... What am i doing wrong here?
#event myEvent = new #event();
myEvent.name = "AddProgram";
myEvent.version = 8.0M;
DateTime myDateTime = new DateTime();
myDateTime = DateTime.Now;
myEvent.time = myDateTime;
detail myDetail = new detail();
myDetail.name = "Program1"
myEvent.detail = myDetail;
Controller controller = new Controller();
controller.actionSpecified = true;
controller.action = ControllerAction.Create;
myDetail.Controller = controller;
String xmlString = myEvent.ToString(); //this is where i would expect a string.
all i get out of this is: "event"
I am not sure where you got your information that ToString() would give you an xml representation of the class but that is not true. What you should do is refer to this article about XML serialization.
http://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx
If you have a class of Type event then you would need to do the following to serialize it to XML, Also as a small tidbit I would stay away from using Key words as class or variable definitions if at all possible, but if you're not in control of that then your hands are tied.
#event myEvent = new #event();
myEvent.name = "AddProgram";
myEvent.version = 8.0M;
string xmlIWant= "";
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(#event);
using (StringWriter writer = new StringWriter())
{
x.Serialize(writer, myEvent);
xmlIWant = writer.ToString();
}
I serialise my wcf requests and responses into XML but to save database space, I strip out all non-essential information, so the result is:
<someObject>
<someValue>10</someValue>
</someObject>
There are more complex nested properties, the above is just an example.
When I try to deserialise, I get an error saying expecting someObject, someNamespace but encountered someObject, ''
byte[] data = System.Text.Encoding.UTF8.GetBytes(xmlString);
stream.Write(data, 0, data.Length);
stream.Position = 0;
DataContractSerializer deserializer = new DataContractSerializer(typeof(T));
return deserializer.ReadObject(stream) as T;
Is there an easy way to solve this? Perhaps by not using a DataContractSerializer?
I know this post is almost a week old, but it may help someone if you've already found a solution.
If you know the structure beforehand, you could use the XmlSerializer class.
string xml = "<someObject>" +
" <someValue>10</someValue>" +
"</someObject>";
using (TextReader reader = new StringReader(xml))
{
XmlSerializer serializer = new XmlSerializer(typeof(someObject));
var obj = serializer.Deserialize(reader);
}
Here's the supporting class to deserialize it into:
[Serializable()]
public class someObject
{
[XmlElement("someValue")]
public string someValue { get; set; }
}
For more complex XML, you'd have to modify the class that you're using. You can nest classes as well as support arrays/lists.
I am using the following function to attempt to serialize an object to XML..
public static string SerializeObject<T>(T obj)
{
try
{
string xmlString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
xmlString = UTF8ByteArrayToString(memoryStream.ToArray()); return xmlString;
}
catch (Exception ex)
{
return string.Empty;
}
}
When attempting to serialize an object that has an IList property in it, I get the following exception..
Cannot serialize member 'ObjectModel.Order.LineItems' of type 'System.Collections.Generic.IList
Can someone help me change my function to accommodate for this scenario?
Is there anything I can do this existing code to look into the input object. If its of type Ilist change it to a List? Can somoeone help me with code for that if its at all possible??
There's no great solution for this, only the workaround of using a concrete type like List<T> in this case - you could either change the existing property to be List<T> or add an additional property used just for serialization of type List<T> (and XML-ignore your existing property).
XmlSerializer does not handle properties of type IList<T>. There are some workarounds, the most straightforward of which is to change the type of the property:
https://www.google.com/search?q=xmlserializer+ilist
How important is Xml output? binary format is more accomodating. you could convert the output to base64 string if needed.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.71).aspx
private static void WriteJson(string filepath,
string filename,
JsonSchema jsonschema)
{
using (TextWriter writer = File.CreateText(
#"C:\Users\ashutosh\Desktop\Output\" + filename + ".js"))
using (var jtw = new JsonTextWriter(writer))
{
jtw.Formatting = Formatting.Indented;
jsonschema.WriteTo(jtw);
}
//var json = JsonConvert.SerializeObject(
// jsonschema, Formatting.Indented,
// new JsonSerializerSettings {
// NullValueHandling = NullValueHandling.Ignore });
// File.WriteAllText(
// #"C:\Users\ashutosh\Desktop\Output\" + filename + ".js", json);
}
I am creating a JSONSchema from JSON.net , and then writing it out . I get a
Invalid Operation Exception Sequence contains no matching element
But when I use the commented code instead of the usual stuff. No such exception appears.
1) What is causing this exception?
2) I would have used the second method happily but it doesn't feel intuitive and it will print out the integer value of the JsonType for schema.Type instead of the (array,integer,bool etc..)
What can I do to get out of this situation?
UPDATE
The exception happens when the "Properties" property of the JsonSchema has count = 0 .
Properties is Dictionary<String,JsonSchema>. I have initialise it so it is not null. Eventually the code may or may not add elements to it . so , the count may remain 0.
By default, enums will be serialized to theirs corresponding integer value. You can change that easily by supplying StringEnumConverter in your serializer settings:
var json = JsonConvert.SerializeObject(jsonschema, Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Converters = new List<JsonConverter> { new StringEnumConverter() }
});
Edit:
I run this simple test code:
var schema = new JsonSchemaGenerator().Generate(typeof(CustomType));
Debug.Assert(schema.Properties.Count == 0);
using (TextWriter textWriter = File.CreateText(#"schema.json"))
using (var jsonTextWriter = new JsonTextWriter(textWriter))
{
jsonTextWriter.Formatting = Formatting.Indented;
schema.WriteTo(jsonTextWriter);
}
// CustomType is a class without any fields/properties
public class CustomType { }
Code above serializes schema correctly to:
{
"type": "object",
"properties": {}
}
Is the schema you are generating correct? It seems as if serializer was "thinking" it should deal with some properties when there are actually none. Can you show type you generate schema from? There might be a problem with type which causes invalid schema to generate - but still, I cannot reproduce it.
I'm attempting to use the following code to serialize an anonymous type to JSON:
var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray());
However, I get the following exception when this is executed:
Type
'<>f__AnonymousType1`3[System.Int32,System.Int32,System.Object[]]'
cannot be serialized. Consider marking
it with the DataContractAttribute
attribute, and marking all of its
members you want serialized with the
DataMemberAttribute attribute. See
the Microsoft .NET Framework
documentation for other supported
types.
I can't apply attributes to an anonymous type (as far as I know). Is there another way to do this serialization or am I missing something?
Try the JavaScriptSerializer instead of the DataContractJsonSerializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
As others have mentioned, Newtonsoft JSON.NET is a good option. Here is a specific example for simple JSON serialization:
return JsonConvert.SerializeObject(
new
{
DataElement1,
SomethingElse
});
I have found it to be a very flexible, versatile library.
You can try my ServiceStack JsonSerializer it's the fastest .NET JSON serializer at the moment. It supports serializing DataContract's, Any POCO Type, Interfaces, Late-bound objects including anonymous types, etc.
Basic Example
var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>();
Note: Only use Microsofts JavaScriptSerializer if performance is not important to you as I've had to leave it out of my benchmarks since its up to 40x-100x slower than the other JSON serializers.
For those checking this around the year 2020:
Microsoft's System.Text.Json namespace is the new king in town. In terms of performance, it is the best as far as I can tell:
var model = new Model
{
Name = "Test Name",
Age = 5
};
string json = JsonSerializer.Serialize(model);
As some others have mentioned, NewtonSoft.Json is a very nice library as well.
The fastest way I found was this:
var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);
Namespace: System.Web.Script.Serialization.JavaScriptSerializer
Please note this is from 2008. Today I would argue that the serializer should be built in and that you can probably use swagger + attributes to inform consumers about your endpoint and return data.
Iwould argue that you shouldn't be serializing an anonymous type. I know the temptation here; you want to quickly generate some throw-away types that are just going to be used in a loosely type environment aka Javascript in the browser. Still, I would create an actual type and decorate it as Serializable. Then you can strongly type your web methods. While this doesn't matter one iota for Javascript, it does add some self-documentation to the method. Any reasonably experienced programmer will be able to look at the function signature and say, "Oh, this is type Foo! I know how that should look in JSON."
Having said that, you might try JSON.Net to do the serialization. I have no idea if it will work
You could use Newtonsoft.Json.
var warningJSON = JsonConvert.SerializeObject(new {
warningMessage = "You have been warned..."
});
A faster alternative with Microsofts' new library on System.Text.Json
var warningJSON = JsonSerializer.Serialize(new {
warningMessage = "You have been warned..."
});
Assuming you are using this for a web service, you can just apply the following attribute to the class:
[System.Web.Script.Services.ScriptService]
Then the following attribute to each method that should return Json:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
And set the return type for the methods to be "object"
public static class JsonSerializer
{
public static string Serialize<T>(this T data)
{
try
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
var stream = new MemoryStream();
serializer.WriteObject(stream, data);
string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
stream.Close();
return jsonData;
}
catch
{
return "";
}
}
public static T Deserialize<T>(this string jsonData)
{
try
{
DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
T data = (T)slzr.ReadObject(stream);
stream.Close();
return data;
}
catch
{
return default(T);
}
}
}