so I have came across making few programs, that build specific XMLs with data from database.
Now i would like to make application, which I could just hang over structured class with values and it would be able to dynamically read it.
My idea of that class is something like this
public class Order
{
public string PO_NO { get; set; }
................
public List<OrderDetails> OrderDetails = new List<OrderDetails>();
}
and XML would go out as follows
<ORDER>
<PO_NO>18060001</PO_NO>
....
-<ORDER_DETAILS>
-<ORDER_DETAIL>
</ORDER_DETAIL>
-<ORDER_DETAIL>
</ORDER_DETAIL>
...
</ORDER_DETAILS>
-</ORDER>
I hope this covers the structure and the idea.
So far I am struggling on dynamically reading the class.
The last and I quess the closest attempt is this:
foreach (var refer in DatabaseData.getRefs()) //just gets reference numbers for me, for further reading
{
//THIS one returns the filled class. Eg. the Order class explained higher.
var MyClass = DatabaseData.read(refer);
var fiel = DatabaseData.read(refer).GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fiel)
{
var fieldName = field.Name.Replace('<', ' ').Replace('>', ' ').Replace("__", null).Replace("kBackingField", null);
if (field.FieldType.ToString().Contains("List"))
Debug.WriteLine("its a list");
else
Debug.WriteLine((string)DatabaseData.read(refer).GetType().GetField(fieldName).GetValue(Activator.CreateInstance(DatabaseData.read(refer).GetType())));
}
}
This is the part that troubles me. I have tried many variations of this I found on forums, but I am still getting the. Object reference not set to instance of an object.
(string)DatabaseData.read(refer).GetType().GetField(fieldName).GetValue(Activator.CreateInstance(DatabaseData.read(refer).GetType()))
Any ideas please? Or point me the right way.
Thanks in advance.
There is no need to do anything yourself here; just use XmlSerializer
.
You might need to add some attributes to get the XML you want:
[XmlRoot("ORDER")]
public class Order
{
[XmlElement("PO_NO")] // note this one is implicit and not strictly needed
public string PO_NO { get; set; }
[XmlArray("ORDER_DETAILS")]
[XmlArrayItem("ORDER_DETAIL")]
public List<OrderDetails> OrderDetails {get;} = new List<OrderDetails>();
}
then:
var serializer = new XmlSerializer(typeof(Order));
Not that it matters once you've done this, but there's also need to use Roslyn backing field info in this case - just look at both GetProperties()
and GetFields()
, and using PropertyInfo.SetValue(...)
instead of FieldInfo.SetValue(...)
when appropriate; meaning: use the property, not the backing field.