Json not serializing all object in Azure - c#

I have POCO which is as simple as
public partial class Member
{
public int ID { get; set; }
[Required]
[StringLength(100)]
public string MemberId { get; set; }
public DateTime CreatedOn { get; set; }
[Required]
[StringLength(100)]
public string FirstName { get; set; }}
and a Add command which looks like this
public class AddMemberCommand : ICommand
{
public AddMemberCommand(Member member )
{
ID = Guid.NewGuid();
MemberData = member;
}
public Member MemberData { get; private set; }
public Guid ID { get; }
public string CommandName
{
get { return "AddMemberCommand"; }
}
}
which inherits from
public interface ICommand
{
/// <summary>
/// Gets the command identifier.
/// </summary>
Guid ID { get; }
string CommandName { get; }
}
Now I send this code to a method which initializes Newton Json's serializing setting class with some parameters to return an object. The serializer looks like this
public class JsonTextSerializer
{
private readonly JsonSerializer _serializer;
public JsonTextSerializer()
{
_serializer = JsonSerializer.Create(new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
});
}
public void Serialize(TextWriter writer, object graph)
{
var jsonWriter = new JsonTextWriter(writer);
jsonWriter.Formatting = Formatting.Indented;
_serializer.Serialize(jsonWriter, graph);
writer.Flush();
}
public object Deserialize(TextReader reader)
{
var jsonReader = new JsonTextReader(reader);
try
{
return this._serializer.Deserialize(jsonReader);
}
catch (JsonSerializationException e)
{
// Wrap in a standard .NET exception.
throw new SerializationException(e.Message, e);
}
}
}
The serializer is used to convert the command into a payload for the brokered message as shown below
private BrokeredMessage CreateMessage(POCOS.Member member)
{
var serializer = new JsonTextSerializer();
var command = new AddMemberCommand(member);
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
serializer.Serialize(writer, command);
stream.Position = 0;
BrokeredMessage message = new BrokeredMessage(stream, true);
return message;
}
and there is a another method which receives the method
private POCOS.Member GetPocoFromMessage(BrokeredMessage message)
{
ITextSerializer serializer = new JsonTextSerializer();
AddMemberCommand command;
using (var stream = message.GetBody<Stream>())
{
using (var reader = new StreamReader(stream))
{
var payload = serializer.Deserialize(reader);
command = payload as AddMemberCommand;
}
}
return command.MemberData;
}
The issue is on deserializing some properties ( ID, CommandName) are filled with value except for MemberData which is null.
I can read the stream (by doing a reader.ReadToEnd()) and see it was transferred over the wire but Json can't deserialize all its object
At one time I also thought it perhaps picks only fields in the Interface but that's not the case

Your MemberData property has a private setter. Since the serializer needs access to the property externally, this setter should be public.

Related

How to deserialize a list inside of a list with list type Interface?

While deserializing, I get this error:
Error getting value from 'tasksToDo' on 'StudentHousingFramework.Modules.Room'.
System.NullReferenceException: Object reference not set to an instance of an object.
I'm trying to deserialize a list of interfaces that have a list of type interface (different ones) inside.
tasksToDo is a List<Interface> on the class and it's, to my understanding, what's causing the issue.
The way I deserialize is via this classes:
public void Serealise<T>(string nameList, List<T> list)
{
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, nameList);
string jsonString = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto
}); ;
File.WriteAllText(path, jsonString);
}
public List<IAccount>? DeserealiseRoom(string list)
{
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, list);
if (File.Exists(path))
{
var file = File.ReadAllText(path);
return JsonConvert.DeserializeObject<List<IAccount>>(file, new JsonSerializerSettings
{
ReferenceLoopHandling= ReferenceLoopHandling.Ignore,
TypeNameHandling= TypeNameHandling.Auto,
});
}
return null;
}
This is the class room that inherits from the interface that characterises the list:
public class Room : IAccount
{
public Room()
{
}
[JsonIgnore]
public List<ITask> tasksToDo
{
get
{
return factory.manager.tasks.FindAll(w => w.claimer == this);
}
}
public Login login { get; set; }
public bool isOccupied { get; private set; } = true;
public int id { get; set; }
public string name
{
get
{
return "Room " + id;
}
}
public Json json { get; set; } = new Json();
private Factory factory { get; set; }
public Room(Factory factory, int id)
{
this.factory = factory;
this.id = id;
login = new Login();
}
}
What can I do to solve this issue?

JIL json serializer does not serialize properties from derived class

JIL json serializer does not serialize properties from derived class
Below are the code snippet:
public async Task WriteAsync(OutputFormatterWriteContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var response = context.HttpContext.Response; response.ContentType = "application/json";
using (var writer = context.WriterFactory(response.Body, Encoding.UTF8))
{
Jil.JSON.Serialize(context.Object, writer);
await writer.FlushAsync();
}
}
1) Model Type:
public class BaseBOResponse
{
public string pk { get; set; }
}
public class PaymentTypeBOResponse : BaseBOResponse
{
public string description { get; set; }
public bool isSystem { get; set; }
public bool isActive { get; set; }
}
Here when i set something to BaseBOResponse's response property "pk", then JIL serializer eliminate this property.
Please suggest if you have any solution.
You have to tell Jil to include inherited properties as well:
Jil.JSON.Serialize(context.Object, writer, Jil.Options.IncludeInherited);

UWP XmlSerializer - Deserialization of an object from a derived to base class

So I have 2 classes. The first class is Message and the second one is MessageText class that derives from the Message class.
This is the Message class:
public class Message
{
public Message(Guid from, Guid to, MessageType type, DateTime sentAt)
{
From = from;
To = to;
Type = type;
SentAt = sentAt;
}
public Message()
{
}
public Guid From { get; set; }
public Guid To { get; set; }
public MessageType Type { get; set; }
public DateTime SentAt { get; set; }
}
This is the MessageText class:
public class MessageText : Message
{
public MessageText(Guid from, Guid to, MessageType type, DateTime sentAt, string text)
: base(from, to, type, sentAt)
{
this.Text = text;
}
public MessageText()
{
}
public string Text { get; set; }
}
This is how I do the serialization and deserialization:
public static byte[] ConvertToStream(object obj)
{
try
{
XmlSerializer bf = new XmlSerializer(obj.GetType());
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
catch { return new byte[0]; }
}
public static object ConvertFromStream<T>(byte[] data)
{
try
{
XmlSerializer bf = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(data))
{
return bf.Deserialize(ms);
}
}
catch { return null; }
}
How I use the methods:
Byte[] buffer = XMLHelper.ConvertToStream(message);
// Now send the message
// ...
/// When I receive the message
Message msg = (Message)XMLHelper.ConvertFromStream<Message>(data);
switch (msg.Type)
{
case EMessageType.Text:
if (OnMessageTextReceivedEvent != null)
{
MessageText msgT = (MessageText)XMLHelper.ConvertFromStream(data);
OnMessageTextReceivedEvent(msgT, EventArgs.Empty);
}
break;
//...
}
So when I receive the message I firstly want to deserialize it to the base class, so that I can see what type of message it is, and then to deserialize it to the correct type.
Note: I can use this approach without a problem if I want to deserialize to the correct type, for example if I deserialize a MessageText object to a MessageText object, but if I try to deserialize a MessageText object to its base class I get the following error: "There is an error in XML document (2, 2)."
Since the XmlSerializer expects the root element to be and the root element of the MessageText class is I just use the following code to change the root element of the MessageText class and now I can deserialize the object into a Message and/or MessageText class.
[XmlRoot("Message")]
public class MessageText : Message
{
public MessageText(Guid from, Guid to, MessageType type, DateTime sentAt, string text)
: base(from, to, type, sentAt)
{
this.Text = text;
}
public MessageText()
{
}
public string Text { get; set; }
}

Why does not XmlSerializer recognize this attribute?

I have a simple class with two properties:
[XmlRoot("response")]
public class Response
{
[XmlAttribute("code")]
string Code { get; set; }
[XmlAttribute("message")]
string Message { get; set; }
}
I try to deserialize an XML string with XmlSerializer:
static void Main(string[] args)
{
string xml = "<response code=\"a\" message=\"b\" />";
using(var ms = new MemoryStream())
using(var sw = new StreamWriter(ms))
{
sw.Write(xml);
sw.Flush();
ms.Position = 0;
XmlSerializer ser = new XmlSerializer(typeof(Response));
ser.UnknownAttribute += new XmlAttributeEventHandler(ser_UnknownAttribute);
var obj = ser.Deserialize(ms);
}
}
static void ser_UnknownAttribute(object sender, XmlAttributeEventArgs e)
{
throw new NotImplementedException();
}
The UnknownAttribute event gets fired at the code attribute, it does not get deserialized.
What is the reason for this? Am I using the XmlAttributeAttribute wrong?
This is because the attributes are not public in your class:
[XmlRoot("response")]
public class Response
{
[XmlAttribute("code")]
public string Code { get; set; }
[XmlAttribute("message")]
public string Message { get; set; }
}
From the documentation of XmlAttributeAttribute (emphasis is mine):
You can assign the XmlAttributeAttribute only to public fields or public properties that return a value (or array of values) that can be mapped to one of the XML Schema definition language (XSD) simple types (including all built-in datatypes derived from the XSD anySimpleType type).

Issue serializing / deserializing a custom object with double values

Trying to deserialize an instance of this class
[Serializable]
public class InstalledMeter : ISerializable
{
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Description", Description);
info.AddValue("Latitude", Latitude);
info.AddValue("Longitude", Longitude);
}
}
The instance:
new InstalledMeter {Description = "Something", Latitude = 0.0, Longitude = 0.0};
My Serialization methods
public static class SerializeString
{
public static string SerializeObject<T>(this T toSerialize)
{
var xmlSerializer = new XmlSerializer(toSerialize.GetType());
var textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
public static T XmlDeserializeFromString<T>(this string objectData)
{
return (T)XmlDeserializeFromString(objectData, typeof(T));
}
public static object XmlDeserializeFromString(string objectData, Type type)
{
var serializer = new XmlSerializer(type);
object result;
using (TextReader reader = new StringReader(objectData))
{
result = serializer.Deserialize(reader);
}
return result;
}
}
But when I serialize the object it has these values
(guessing an answer based on your previous question - Error passing parameters to mvvmcross viewmodels)
If you are doing this in MvvmCross, then I would avoid this xml problem altogether and just use JSON serialization
var jsonText = JSONConvert.SerializeObject(installedMeter);
and
var installedMeter = JSONConvert.DeserializeObject<InstalledMeter>(jsonText);
using just:
public class InstalledMeter
{
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}

Categories