Serializing a class as one of its properties - c#

When I serialize an object using JsonConvert using the following code:
JsonConvert.SerializeObject(new Foo())
The result is:
{"count":{"Value":3},"name":{"Value":"Tom"}}
I would like the result to look like this. So without the embedded { "Value": * } structure.
{"count":3,"name":Tom}
I need use JObject.FromObject and JsonConvert.SerializeObject.
The code for the Foo class:
public class Foo
{
public DeltaProperty<int> count = new DeltaProperty<int>(3);
public DeltaProperty<string> name = new DeltaProperty<string>("Tom");
}
public class DeltaProperty<T>
{
public T Value
{
get
{
m_isDirty = false;
return m_value;
}
set
{
if (!m_value.Equals(value))
{
m_isDirty = true;
m_value = value;
}
}
}
private bool m_isDirty = default;
private T m_value = default;
public DeltaProperty(T val)
{
Value = val;
}
public bool ShouldSerializeValue()
{
return m_isDirty;
}
public override string ToString()
{
return m_value.ToString();
}
}

Related

How can I serialize this xml array to a property in my class?

[Serializable]
public class CampoAuxiliar
{
private string descripcionAuxiliar;
private DateTime fechaAuxiliar;
private ArrayList opcion;
public CampoAuxiliar() { }
[XmlElement(ElementName = "descripcionAuxiliar", Type = typeof(string))]
public string DescripcionAuxiliar
{
get { return descripcionAuxiliar; }
set { descripcionAuxiliar = value; }
}
[XmlElement(ElementName = "fechaHabilitacion", Type = typeof(DateTime))]
public DateTime FechaAuxiliar
{
get { return fechaAuxiliar; }
set { fechaAuxiliar = value; }
}
[XmlArrayItem(ElementName = "opcion", Type = typeof(Opcion))]
[XmlArray(ElementName = "AuxiliarA")]
public ArrayList Opcion
{
get { return opcion; }
set { opcion = value; }
}
}
And this is my xml
- <auxiliarA>
<descripcionAuxiliar>Campo A</descripcionAuxiliar>
<fechaHabilitacion>2017-04-19</fechaHabilitacion>
+ <opcion>
<codigoOpcion>01</codigoOpcion>
<descripcionOpcion>1</descripcionOpcion>
</opcion>
+ <opcion>
<codigoOpcion>02</codigoOpcion>
<descripcionOpcion>2</descripcionOpcion>
</opcion>
+ <opcion>
<codigoOpcion>03</codigoOpcion>
<descripcionOpcion>3</descripcionOpcion>
</opcion>
</auxiliarA>
My problem is I can't figure out how to serialize the "opcion" array into the ArrayList opcion of the class.
With this case it does work and assigns the other nodes properly except for the ArrayList one which returns me count = 0.
You can modify your CampoAuxiliar class as follows:
[XmlRoot("auxiliarA")]
[XmlType("auxiliarA")]
public class CampoAuxiliar
{
private string descripcionAuxiliar;
private DateTime fechaAuxiliar;
public CampoAuxiliar() { }
[XmlElement(ElementName = "descripcionAuxiliar", Type = typeof(string))]
public string DescripcionAuxiliar
{
get { return descripcionAuxiliar; }
set { descripcionAuxiliar = value; }
}
[XmlElement(ElementName = "fechaHabilitacion", Type = typeof(DateTime))]
public DateTime FechaAuxiliar
{
get { return fechaAuxiliar; }
set { fechaAuxiliar = value; }
}
private ArrayList opcion;
[XmlElement("opcion", Type = typeof(Opcion))]
public ArrayList Opcion
{
get { return opcion; }
set { opcion = value; }
}
}
In addition, you should replace the ArrayList with a List<Opcion>:
private List<Opcion> opcion;
[XmlElement("opcion")]
public List<Opcion> Opcion
{
get { return opcion; }
set { opcion = value; }
}
Notes:
[XmlRoot("auxiliarA")] indicates that the root element name is <auxiliarA> not <CampoAuxiliar>.
[XmlElement("opcion")] indicates that the collection is to be serialized without an outer container element.
See ArrayList vs List<> in C# and c# When should I use List and when should I use arraylist? for some discussion of why to prefer List<T> over ArrayList.
Sample fiddle.

Convert two classes in VB.net to C# but get object reference error

I have converted the following two classes to c# from vb.net, but get a reference error. Can someone please help or explain why it does not work in c# but does in vb.net?
Member class:
public class Member
{
#region "Fields"
private string fPiecemark;
private string fMemberType;
private string fSize;
private string fTotalWeight;
private int fSheetKey;
private string fDescription;
private string fStructType;
#endregion
private string fMemberSheetIndex;
#region "Constructors"
//Default class Constructor
public Member()
{
fPiecemark = string.Empty;
fMemberType = string.Empty;
fSize = string.Empty;
fTotalWeight = string.Empty;
fSheetKey = 0;
fStructType = string.Empty;
}
public Member(string Piecemark, string MemberType, string Description, string Size, string TotalWeight, string StructType, string MemberSheetIndex, int SheetID)
{
this.Piecemark = Piecemark;
this.MemberType = MemberType;
this.Description = Description;
this.Size = Size;
this.TotalWeight = TotalWeight;
this.StructType = StructType;
this.MemberSheetIndex = MemberSheetIndex;
this.SheetKey = SheetID;
if (!MbrSheet.mSheet.ContainsKey(SheetID))
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID));
}
MbrSheet.mSheets[SheetID].Members.Add(this);
}
#endregion
#region "Properties"
public string Piecemark
{
get { return fPiecemark; }
set { fPiecemark = value; }
}
public string MemberType
{
get { return fMemberType; }
set { fMemberType = value; }
}
public string TotalWeight
{
get { return fTotalWeight; }
set { fTotalWeight = value; }
}
public string Size
{
get { return fSize; }
set { fSize = value; }
}
public int SheetKey
{
get { return fSheetKey; }
set { fSheetKey = value; }
}
public string Description
{
get { return fDescription; }
set { fDescription = value; }
}
public string StructType
{
get { return fStructType; }
set { fStructType = value; }
}
public string MemberSheetIndex
{
get { return fMemberSheetIndex; }
set { fMemberSheetIndex = value; }
}
#endregion
}
MbrSheet class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
public class MbrSheet
{
public static Dictionary<int, MbrSheet> mSheets = new Dictionary<int, MbrSheet>();
public int mSheet { get; set; }
public List<Member> Members { get; set; }
public MbrSheet(int MbrSheet)
{
Members = new List<Member>();
this.mSheet = MbrSheet;
}
public static decimal WeightByType(string MemberType)
{
var subset = mSheets.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0);
decimal wbt = 0;
wbt += mSheets
.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0)
.Sum(kvp => kvp.Value.Members.Sum(m => Convert.ToDecimal(m.TotalWeight, CultureInfo.InvariantCulture)));
return wbt;
}
}
I get error but don't know why
An object reference is required for the non-static field, method, or property for MbrSheet.mSheet, but both worked in VB.net
if (!MbrSheet.mSheet.ContainsKey(SheetID)) // Error on !MbrSheet.mSheet
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID)); // Error on MbrSheet.mSheet
}
I think you should use this:
if (!MbrSheet.mSheets.ContainsKey(SheetID))
{
MbrSheet.mSheets.Add(SheetID, new MbrSheet(SheetID));
}
Pay attention to mSheets you are using mSheet.
You can also use tools to convert codes:
http://www.developerfusion.com/tools/convert/csharp-to-vb/
http://codeconverter.sharpdevelop.net/SnippetConverter.aspx

Null error when assigning value to property

Trying to create a custom object that will allow me to pickup errors in the records.
public class gridIntegerField
{
private int value;
private bool isValid;
private string message;
public int Value
{
get { return this.value; }
set { this.value = value; }
}
public bool IsValid
{
get { return isValid; }
set { isValid = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
}
public class gridRecord
{
private gridIntegerField printRun;
public gridIntegerField PrintRun
{
get { return printRun; }
set { printRun = value; }
}
}
when creating object and trying to set the values i get the folowing error...
An unhandled exception of type 'System.NullReferenceException' occurred in XML- Console.exe
Code for creating object...
gridRecord spr = new gridRecord();
spr.PrintRun.Value = 200;
spr.PrintRun.IsValid = true;
spr.PrintRun.Message = "No Errors";
Console.WriteLine(spr.PrintRun.Value.ToString());
Console.WriteLine(spr.PrintRun.IsValid.ToString());
Console.WriteLine(spr.PrintRun.Message.ToString());
Console.ReadKey();
the error happens at this line of code
spr.PrintRun.Value = 200;
Because you do not instantiate the printRun field after gridRecord instantiating.
You can do it in the constructor method.
public class gridRecord
{
private gridIntegerField printRun;
public gridIntegerField PrintRun
{
get { return printRun; }
set { printRun = value; }
}
//Add a constructor method
public gridRecord()
{
//and instantiate the printRun.
printRun = new gridIntegerField();
}
}

JsonConvert.SerializeObject() fails in serializing class with DateTime fields

I'm having a class with only private fields and their public getter-setters. I need to convert class object into JSON String hence I'm using JSON.Net.
Following is a simple snippet to convert class object into a JSON string.
MyClass obj = new MyClass();
string json = JsonConvert.SerializeObject(obj);
Console.WriteLine(json);
But the method SerializeObject throws StackOverflowException at field in MyClass of type DateTime. What's happening here?
Update
Following is how MyClass looks like (as it is, I don't mind sharing the actual class)
class MyClass
{
private int _Model;
public int Model
{
get
{
return _Model;
}
set
{
_Model = value;
}
}
private long _ProductionControlNumber;
public long ProductionControlNumber
{
get
{
return _ProductionControlNumber;
}
set
{
_ProductionControlNumber = value;
}
}
private DateTime _ProductionDate;
public DateTime ProductionDate
{
get
{
return _ProductionDate;
}
set
{
_ProductionDate = value;
}
}
private DateTime _TestDate;
public DateTime TestDate
{
get
{
return _TestDate;
}
set
{
_TestDate = value;
}
}
private DateTime _TestStartTime;
public DateTime TestStartTime
{
get
{
return _TestStartTime;
}
set
{
_TestStartTime = value;
}
}
private TimeSpan _TestDuration;
public TimeSpan TestDuration
{
get
{
return _TestDuration;
}
set
{
_TestDuration = value;
}
}
public DateTime TestEndTime
{
get
{
//TODO Perform start end time computing logic.
return TestEndTime;
}
}
private int _TestBed;
public int TestBed
{
get
{
return _TestBed;
}
set
{
_TestBed = value;
}
}
private long _EngineSerial;
public long EngineSerial
{
get
{
return _EngineSerial;
}
set
{
_EngineSerial = value;
}
}
private Single _FuelSpecificGravity;
public Single FuelSpecificGravity
{
get
{
return _FuelSpecificGravity;
}
set
{
_FuelSpecificGravity = value;
}
}
private long _FuelConsume100;
public long FuelConsume100
{
get
{
return _FuelConsume100;
}
set
{
_FuelConsume100 = value;
}
}
private long _FuelConsume110;
public long FuelConsume110
{
get
{
return _FuelConsume100;
}
set
{
_FuelConsume100 = value;
}
}
private int _TemporaryRPM;
public int TemporaryRPM
{
get
{
return _TemporaryRPM;
}
set
{
_TemporaryRPM = value;
}
}
private int _PermanentRPM;
public int PermanentRPM
{
get
{
return _PermanentRPM;
}
set
{
_PermanentRPM = value;
}
}
private Single _RatedPower;
public Single RatedPower
{
get
{
return _RatedPower;
}
set
{
_RatedPower = value;
}
}
private int _RatedSpeed;
public int RatedSpeed
{
get
{
return _RatedSpeed;
}
set
{
_RatedSpeed = value;
}
}
private double _PulleyDiameter;
public double PulleyDiameter
{
get
{
return _PulleyDiameter;
}
set
{
_PulleyDiameter = value;
}
}
private double _RopeDiameter;
public double RopeDiameter
{
get
{
return _RopeDiameter;
}
set
{
_RopeDiameter = value;
}
}
private Single _FullLoad;
public Single FullLoad
{
get
{
return _FullLoad;
}
set
{
_FullLoad = value;
}
}
}
Also, I'll have another class which will have MyClass type field (along with its own similar set of fields), which is going to be converted into JSON string too, and that shouldn't be a problem since JSON.Net is said to support that situation too.
Note: I'm new to C# but I've previously worked with JSON in Java, where I get to play with JSONObject and JSONArray, and they were pretty straight forward.
It looks like your TestEndTime property's getter references itself. Therefore when Json.NET tries to serialize it, it recursively accesses itself and causes the StackOverflowException.
Hope that helps!

Serialize two nodes with the same name but different child nodes

I need to be able to define two nodes with the same name but completely different subnode structures. I didn't design this XML schema but for the time being I'm forced to use it as is. I realize it's a terrible abuse of everything that is XML but there you have it.
What I need it to look like:
<order>
<ItemType type="Clubs">
<Club num="1">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription></GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType
</order>
Of course it's far more complicated than but you get the gist.
I'm using XmlSerializer and would really like to avoid using XDocument but if that's what I need to do then so be it.
If your order contains properties and not a list you can tell the serializer to name the elements like this:
[XmlRoot("order")]
public class Order
{
private Whatever whateverInstance;
[XmlElement("ItemType")]
public Whatever WhateverInstance
{
get { return whateverInstance; }
set { whateverInstance = value; }
}
private Something somethingInstance;
[XmlElement("ItemType")]
public Something SomethingInstance
{
get { return somethingInstance; }
set { somethingInstance = value; }
}
}
If it's a list of things you could get to have a identical element name as well but you will get a redundant xsi:Type attribute:
[XmlRoot("order")]
public class Order
{
private ItemType[] itemTypes;
[XmlElement("ItemType")]
public ItemType[] ItemTypes
{
get { return itemTypes; }
set { itemTypes = value; }
}
}
[XmlInclude(typeof(Clubs))]
[XmlInclude(typeof(Gift))]
public abstract class ItemType
{
private string type = "None";
[XmlAttribute]
public string Type
{
get { return type; }
set { type = value; }
}
}
public class Clubs : ItemType
{
public Clubs()
{
Type = "Clubs";
}
private Club[] clubsArray;
[XmlElement("Club")]
public Club[] ClubsArray
{
get { return clubsArray; }
set { clubsArray = value; }
}
}
public class Club
{
private int num = 0;
[XmlAttribute("num")]
public int Num
{
get { return num; }
set { num = value; }
}
private string clubName = "";
public string ClubName
{
get { return clubName; }
set { clubName = value; }
}
private string clubChoice = "";
public string ClubChoice
{
get { return clubChoice; }
set { clubChoice = value; }
}
}
public class Gift : ItemType
{
public Gift()
{
Type = "Gift";
}
private string val = "";
[XmlAttribute("val")]
public string Val
{
get { return val; }
set { val = value; }
}
private string giftName = "";
public string GiftName
{
get { return giftName; }
set { giftName = value; }
}
private string giftDescription = "";
public string GiftDescription
{
get { return giftDescription; }
set { giftDescription = value; }
}
private int giftQuanity = 0;
public int GiftQuanity
{
get { return giftQuanity; }
set { giftQuanity = value; }
}
}
Test:
List<ItemType> list = new List<ItemType>();
list.Add(new Clubs() { ClubsArray = new Club[] { new Club() { Num = 0, ClubName = "Some Name", ClubChoice = "Something Else" } } });
list.Add(new Gift() { Val = "MailGreeting", GiftName = "MailGreeting", GiftDescription = "GiftDescription", GiftQuanity = 1});
Order order = new Order();
rder.ItemTypes = list.ToArray();
XmlSerializer serializer = new XmlSerializer(typeof(Order));
StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Stuff.xml");
serializer.Serialize(sw, order);
sw.Close();
Output:
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ItemType xsi:type="Clubs" Type="Clubs">
<Club num="0">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType xsi:type="Gift" Type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription>GiftDescription</GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType>
</order>

Categories

Resources