Giter Site home page Giter Site logo

yaxlib / yaxlib Goto Github PK

View Code? Open in Web Editor NEW
168.0 15.0 36.0 3.23 MB

Yet Another XML Serialization Library for the .NET Framework and .NET Core

License: MIT License

C# 100.00%
xml-serialization deserialization serialization serialization-library dot-net dot-net-core

yaxlib's Introduction

YAXLib Logo

YAXLib: Yet Another XML Serialization Library

AppVeyor build status windows AppVeyor build status linux Maintainability Rating Coverage NuGet

Project Status: Looking for contributors and maintainers

We need your help with this project. If you like it, and you are familiar with XML or are willing to help and learn, you can take on different tasks and open pull requests.

We will continue to provide support for current users and publish bug fix releases as far as time allows.

About YAXLib

YAXLib is a flexible XML serialization library that lets developers design freely the XML file structure, choose among private and public fields to be serialized, and serialize all known collection classes and arrays (single-dimensional, multi-dimensional, and jagged arrays) in the .NET Framework.

YAXLib can be used as a powerful XML parser or generator, that exploits the object to XML mapping in the class definitions themselves.

The exception handling policies and its missing data recovery capabilities makes YAXLib a reliable tool for XML configuration storage and retrieval.

Features

  • Allowing the programmer to format the XML result as desired
  • Support for specifying path-like serialization addresses, e.g., elem1/elem2/elem3, and ../elem1, and ./elem1
  • Support for XML namespaces
  • Serialization and deserialization of all known generic and non-generic collection classes in System.Collections, and System.Collections.Generic
  • Support for serialization of single-dimensional, multi-dimensional, and jagged arrays
  • Support for recursive serialization of collections (i.e., collection of collections)
  • Support for specifying aliases for enum members
  • Support for defining user-defined custom serializer for specific types or specific fields
  • Allowing the programmer to choose the fields to serialize (public, or non-public properties, or member variables)
  • Support for serialization and deserialization of objects through a reference to their base-class or interface (also known as polymorphic serialization)
  • Support for multi-stage deserialization
  • Allowing the programmer to add comments for the elements in the XML result
  • and more ...

See the accompanied demo application for an example of each functionality.

Documentation

In the first place please have a look at the YAXLib Wiki. It is a good source to start. The next best documentation for YAXLib is its various samples and unit-tests in this repo.

To play with sample classes, open one of the solution files in Visual Studio, go to YAXLibTests project, SampleClasses folder. If you want a sample class to appear in the demo application simply put a [ShowInDemoApplication] attribute on top of the class definition. In the demo application you can see the serialization result, modify it, and test its deserialization.

Nuget

To install YAXLib, run the following command in the Package Manager Console:

PM> Install-Package YAXLib

A Quick Introduction

Imagine that we have a simple Warehouse class with the following definition:

public class Warehouse
{
    public class Person
    {
        public string SSN { get; set; }
        public string Name { get; set; }
        public string Family { get; set; }
        public int Age { get; set; }
    }

    public string Name { get; set; }
    public string Address { get; set; }
    public double Area { get; set; }
    public List<string> Items { get; set; }
    public Dictionary<string, int> ItemQuantitiesDic { get; set; }
    public Person Owner { get; set; }
}

Without adding any attributes, YAXLib is perfectly capable of serializing objects of the above class. The following is an XML serialization of a sample instantiation of our Warehouse class:

<Warehouse>
  <Name>Foo Warehousing Ltd.</Name>
  <Address>No. 10, Some Ave., Some City, Some Country</Address>
  <Area>120000.5</Area>
  <Items>
    <String>Bicycle</String>
    <String>Football</String>
    <String>Shoe</String>
    <String>Treadmill</String>
  </Items>
  <ItemQuantitiesDic>
    <KeyValuePairOfStringInt32>
      <Key>Bicycle</Key>
      <Value>10</Value>
    </KeyValuePairOfStringInt32>
    <KeyValuePairOfStringInt32>
      <Key>Football</Key>
      <Value>120</Value>
    </KeyValuePairOfStringInt32>
    <KeyValuePairOfStringInt32>
      <Key>Shoe</Key>
      <Value>600</Value>
    </KeyValuePairOfStringInt32>
    <KeyValuePairOfStringInt32>
      <Key>treadmill</Key>
      <Value>25</Value>
    </KeyValuePairOfStringInt32>
  </ItemQuantitiesDic>
  <Owner>
    <SSN>123456789</SSN>
    <Name>John</Name>
    <Family>Doe</Family>
    <Age>50</Age>
  </Owner>
</Warehouse>

It's good to have it serialized this simple, but YAXLib can do more than that. Let's do some house-keeping on the XML side. Let's move the XML-elements and attributes around, so that we will have a nicer and more human readable XML file. Let's decorate our Warehouse class with the following YAXLib attributes and see the XML result.

[YAXComment("Watch it closely. It's awesome, isn't it!")]
public class Warehouse
{
    public class Person
    {
        [YAXAttributeFor("..")]
        [YAXSerializeAs("OwnerSSN")]
        public string SSN { get; set; }

        [YAXAttributeFor("Identification")]
        public string Name { get; set; }

        [YAXAttributeFor("Identification")]
        public string Family { get; set; }

        public int Age { get; set; }
    }

    [YAXAttributeForClass]
    public string Name { get; set; }

    [YAXSerializeAs("address")]
    [YAXAttributeFor("SiteInfo")]
    public string Address { get; set; }

    [YAXSerializeAs("SurfaceArea")]
    [YAXElementFor("SiteInfo")]
    public double Area { get; set; }

    [YAXCollection(YAXCollectionSerializationTypes.Serially, SeparateBy = ", ")]
    [YAXSerializeAs("AvailableItems")]
    public List<string> Items { get; set; }

    [YAXDictionary(EachPairName = "ItemInfo", KeyName = "Item", ValueName = "Count",
                    SerializeKeyAs = YAXNodeTypes.Attribute,
                    SerializeValueAs = YAXNodeTypes.Attribute)]
    [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement)]
    [YAXSerializeAs("ItemQuantities")]
    public Dictionary<string, int> ItemQuantitiesDic { get; set; }

    public Person Owner { get; set; }
}

And this is the result of XML serialization:

<!-- Watch it closely. It's awesome, isn't it! -->
<Warehouse Name="Foo Warehousing Ltd." OwnerSSN="123456789">
  <SiteInfo address="No. 10, Some Ave., Some City, Some Country">
    <SurfaceArea>120000.5</SurfaceArea>
  </SiteInfo>
  <AvailableItems>Bicycle, Football, Shoe, Treadmill</AvailableItems>
  <ItemInfo Item="Bicycle" Count="10" />
  <ItemInfo Item="Football" Count="120" />
  <ItemInfo Item="Shoe" Count="600" />
  <ItemInfo Item="treadmill" Count="25" />
  <Owner>
    <Identification Name="John" Family="Doe" />
    <Age>50</Age>
  </Owner>
</Warehouse>

And even more: You can deserialize this XML back to an instance of the Warehouse class.

Contributors

Logo

Logo designed by axuno gGmbH

License

Copyright (c) 2009 - 2021 Sina Iravanian, Julian Verdurmen, axuno gGmbH and other contributors - Licenced under MIT

yaxlib's People

Contributors

304notmodified avatar asbjornu avatar axunonb avatar bobduncan avatar nknusperer avatar notheotherben avatar orbintsoft avatar prettyv avatar richardsinden avatar sinairv avatar yazgoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yaxlib's Issues

proposal: remove old solution files

Proposal to remove the old solution files and only keep YAXLib.2013.sln. I don't see any benefit (or am I missing somthing?). You can open YAXLib.2013.sln also in VS2012.

The downside of multiple solution files is to keep them all in-sync.

to be removed:

  • YAXLib.2008.sln
  • YAXLib.2010.sln
  • YAXLib.2012.sln

Boolean serialisation

It appears boolean values are being serialised to "True" and "False"

according to the xml spec this is not valid

3.2.2.1 Lexical representation

An instance of a datatype that is defined as ·boolean· can have the following legal literals {true, false, 1, 0}.

I think this probably stems from an object.ToString() call (which for a boolean calls Boolean.ToString() which returns the invalid value).

The default .net serialiser does not support the "True", "False" values so it would be good to maintain compatibility with this.

http://stackoverflow.com/questions/491334/why-does-boolean-tostring-output-true-and-not-true

Serialize characters excluded in XML specs

For example serializing the following values raises an exception from within LINQ to XML:

TestString = "ab\u0003c",
TestCharArray = new [] { 'a', 'b', '\u0003', 'c'}

This issue has been reported by Robert Baron through email.

Check whether collection is constructible throws exception

Depending on .net framework or some other issue method
public static bool IsInstantiableCollection(Type colType)
within ReflectionUtils.cs fails somewhere deep in .net guts.

In order to check whether type has default constructor it is sufficient to check for
return colType.GetConstructor(Type.EmptyTypes) != null;
which works nicely without try/catch block.

Polymorphic with RecursiveWithNoContainingElement causes StackOverflowException

Class definitions

 public class BaseContainer
 {
     [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement)]
     public BaseItem[] Items { get; set; }
 }
 public class DerivedContainer : BaseContainer
 {
 }
 public class BaseItem
 {
     [YAXAttributeForClass]
     public string Data { get; set; }
 }
 public class DerivedItem : BaseItem
 {
 }
  • Deserialise derived element with property with RecursiveWithNoContainingElement
var ser = new YAXSerializer(typeof(BaseContainer));
var container = new DerivedContainer
            {
                Items = new BaseItem[]
                {
                    new BaseItem { Data = "Some Data" }
                }
            };
string result = ser.Serialize(container); // This works correct
var deserialzedInstance = ser.Deserialize(result) as BaseContainer; //StackOverflowException here
  • deserialise correctly Items property if they contains only derived items
var ser = new YAXSerializer(typeof(BaseContainer));
var container = new BaseContainer
            {
                Items = new BaseItem[]
                {
                    new DerivedItem { Data = "Some Data" }
                }
            };
string result = ser.Serialize(container); // This works correct
var deserialzedInstance = ser.Deserialize(result) as BaseContainer; //Items property is null

Serializing types with object members has unreliable behaviour

Suppose I have this class which captures audit information:

public class InterceptedData
{
    public InterceptedData()
    {
        Children = new List<InterceptedData>();
        Parameters = new List<Parameter>();
    }
    /// <summary>
    /// Method (operation) name that was invoked.
    /// </summary>
    public string MethodName { get; set; }
    
    /// <summary>
    /// Parameters that were passed to the operation.
    /// </summary>
    public List<Parameter> Parameters { get; set; }

    /// <summary>
    /// Gets or sets the return value.
    /// </summary>
    public object ReturnValue { get; set; }
    /// <summary>
    /// Additional audits that were triggered by this operation.
    /// </summary>
    public List<InterceptedData> Children { get; set; }
    /// <summary>
    /// Exception object, if an exception was thrown by the operation.
    /// </summary>
    public ExceptionDetails Exception { get; set; }
}

My ReturnValue needs to be object because it can contain the return value of anything. At runtime, in one instance I am getting a List<> object back from one of my intercepted methods, and Yaxlib is serializing it like this:

<Value yaxlib:realtype="System.Collections.Generic.List`1[[ApplicationProcessingService.Entities.ExternalSystemMappingElement, ApplicationProcessingService.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" />

This isn't very useful at all.

However, within my Parameter class which is used for the Parameters property, which is defined like this:

public class Parameter
{
    public string Name { get; set; }
    public string Type { get; set; }
    public object Value { get; set; }
}

The values in the Value property of this class are serialized properly:

<Parameters>
    <Parameter>
      <Name>eform</Name>
      <Type>ApplicationProcessingService.Entities.Eform</Type>
      <Value yaxlib:realtype="ApplicationProcessingService.Entities.Eform">
           ...
      </Value>
    </Parameter>
</Parameters>

Why does using object in my Parameter class result in the serialization of the entire object, while the ReturnValue property doesn't work at all?

I don't need to deserialize any of this data, it is intended to be human readable only.

ICustomSerializer with more context info

In our case ICustomSerializer is too limited to write good custom serializers. We are missing some context info.

Would a PR accepted with a new interface so we could get more context info? I will make sure that ICustomSerializer still works (just with with a wrapper) and that it will be 100% backwards-compatible :)

Move to VS2019

I think project.json is legacy now and I recommend to upgrade to VS2017

@sinairv will a PR accepted for this?

Support for .Net Core

Have you ever considered adding support for .Net Core? With the current version of .Net Core XML serialization is quite bulky and having YAXLib at hand would be a relief. I already gave it a try and there would of course be some code adjustments necessary, mainly for conditional compilation in terms of reflection. But by making use of a modified version of the extension methods from https://github.com/StefH/ReflectionBridge it should be feasible. Interested?

Deserialization throws stack empty exception

Hey, I've started using YAXLib to serialize/deserialize my classes.

I have an issue where the deserialization process throws a weird exception
{System.InvalidOperationException: Stack empty. at System.Collections.Generic.Stack`1.ThrowForEmptyStack() at System.Collections.Generic.Stack`1.Pop() at YAXLib.YAXSerializer.FinalizeNewSerializer(YAXSerializer serializer, Boolean importNamespaces, Boolean popFromSerializationStack) at YAXLib.YAXSerializer.DeserializeCollectionValue(Type colType, XElement xelemValue, XName memberAlias, YAXCollectionAttribute colAttrInstance) at YAXLib.YAXSerializer.DeserializeCollectionMember(Object o, MemberWrapper member, Type colType, String elemValue, XElement xelemValue) at YAXLib.YAXSerializer.RetreiveElementValue(Object o, MemberWrapper member, String elemValue, XElement xelemValue) at YAXLib.YAXSerializer.DeserializeBase(XElement baseElement) at YAXLib.YAXSerializer.Deserialize(String input) at Hermes.Hermes.XmlToNcp() in C:\Users\George\documents\visual studio 2017\Projects\Hermes\Hermes\Hermes.cs:line 119}
The funny thing is that if I run it through deserilization a second time, it works.
Here's the XML it's trying to deserialize: https://pastebin.com/nKyhAnDe (in readable mode)

EDIT: forgot to mention it only happens in large strings. this one is about 19k chars long.

Thanks in advance,
George

Crash when serialize a dictionary with a null value

I find the following bug in the YAXLib source code:

If I try to serialize a dictionary that contains a null value I got a unhandled nullReference exception.

Dictionary<string, object> Dict= new Dictionary<string, object>();
Dict.Add("foo", null);
YAXSerializer serializer = new YAXSerializer(typeof (Dictionary<string, object>));
_serializer.SerializeToFile(Dict, "path"); // << CRASH

Running deep in YAXSerializer.cs I found the following code:

foreach (object obj in dicInst) //dicInst is the Dict variable defined above
{
  ...
  // valueObj is null
  XElement addedElem = AddObjectToElement(elemChild, valueAlias, valueObj);
  ...
}

private XElement AddObjectToElement(XElement elem, XName alias, object obj)
{
  //obj is null and so obj.GetType() crash
  UdtWrapper udt = TypeWrappersPool.Pool.GetTypeWrapper(obj.GetType(), this);
  ...
}

Am I missing something?
How to handle this problem?
Thanks! :)

RecursiveWithNoContainingElement does not works well

Example1 works well

C# code

public class Root
{
	[YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement)]	
	public Node[] Nodes { get; set; }
}

public class Node
{
	[YAXAttributeForClass]
	public string Name { get; set;}

	[YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement)]	
	public Node[] Nodes { get; set; }

}

xml

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Root>
	<Node Name="1">
		<Node Name="1a"></Node>
		<Node Name="1b"></Node>
	</Node>
	<Node Name="2">
		<Node Name="2a"></Node>
		<Node Name="2b"></Node>
	</Node>
</Root>

Deserialize
2

Example2 dost not works well

3

4
Deserialize
5

Add option to serialize private members from base types

If you serialize a class B that derives from A then the private fields of A are not serialized even if you apply the correct type attributes. The reason is in the GetFieldsToBeSerialized(...) method. GetMembers() does not deliver private fields of base types.

foreach (var member in typeWrapper.UnderlyingType.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))

To solve this issue I iterate through the base types as well and I introduced a member wrapper cache which improves the serialization/deserialisation performance.
You find the modified serializer source code attached.
YAXSerializer.cs.txt

Thanks in advance,
Bernhard

Dictionary with GenericClass value serialized as an Attribute: deserializes value as Null

I have tried to serialize a dictionary with generic class as values. I want to serialize the values as attributes of each element of the dictionary.
The serialization seems working in the correct way, this is my serialization file:

<DictionaryValueGenericClassAsAttribute>
 <!-- Values are serialized as attributes of dictionary item. -->
  <Values>
    <Entry key="0" Value="10" DefaultValue="100" />
    <Entry key="1" Value="11" DefaultValue="101" />
    <Entry key="2" Value="12" DefaultValue="102" />
    <Entry key="3" Value="13" DefaultValue="103" />
    <Entry key="4" Value="14" DefaultValue="104" />
  </Values>
</DictionaryValueGenericClassAsAttribute>

The problem is the deserialization because it's impossible to deserialize the values of the dictionary (I obtain null values).

Is it a my wrong management or is it impossible to manage this 'configuration' ?

This is the class used in the DemoApplication:

using System;
using System.Collections.Generic;
using YAXLib;
namespace YAXLibTests.SampleClasses
{
    [ShowInDemoApplication]
    public class DictionaryValueGenericClassAsAttribute
    {
        [YAXComment("Values are serialized as attributes of dictionary item.")]
        [YAXErrorIfMissed(YAXExceptionTypes.Ignore)]
        [YAXDictionary(EachPairName = "Entry", KeyName = "key", SerializeKeyAs = YAXNodeTypes.Attribute, SerializeValueAs = YAXNodeTypes.Attribute)]
        public Dictionary<int, GenericValue<int>> Values { get; set; }


    public DictionaryValueGenericClassAsAttribute()
    {
        Values = new Dictionary<int, GenericValue<int>>();
    }

    public override string ToString()
    {
        return GeneralToStringProvider.GeneralToString(this);
    }

    public static DictionaryValueGenericClassAsAttribute GetSampleInstance()
    {
        var test = new DictionaryValueGenericClassAsAttribute();

        for (int i = 0; i < 5; i++)
        {
            test.Values.Add(i, new GenericValue<int> { Value = 10 + i, DefaultValue = 100 + i });
        }

        return test;
    }
}
public class GenericValue<T> where T : IComparable<T>
{
    [YAXAttributeFor("..")]
    [YAXErrorIfMissed(YAXExceptionTypes.Error)]
    public T Value { get; set; }

    [YAXAttributeFor("..")]
    [YAXErrorIfMissed(YAXExceptionTypes.Ignore)]
    public T DefaultValue { get; set; }
}

Attributes should have no namespace by default

According to http://www.xmlplease.com/attributexmlns and http://www.w3.org/TR/REC-xml-names/#defaulting attributes without a namespace prefix are not in a namespace. To me it seems, that YAXLib assumes that attributes without a namespace prefix are in the same namespace as the containing element. This makes it impossible to serialize elements which contain attributes that are in the same namespace in the way they should be serialized, with the namespace prefix.
The WordProcessingML specification for example requires this.
This is how attributes are serialized when they are in the same namespace as the containing element:

<w:font name="Arial">

This is how it should look like:

<w:font w:name="Arial">

Right now it is impossible to create this serialization with YAXLib, because the namespace is stripped from the attributes.

Wrong deserialization while using object as type (returns null)

This is my savegame class which i want to serialize to xml and send it over the network.

public class Speicherstand
{
  private double cookies;
  public string Username { get; set; }
  public int Granny { get; set; }
  public int Factory { get; set; }
  public int Farm { get; set; }
  public int Mine { get; set; }
  public int Cursor { get; set; }
  public double GrannyCosts { get; set; }
  public double FactoryCosts { get; set; }
  public double FarmCosts { get; set; }
  public double MineCosts { get; set; }
  public double CursorCosts { get; set; }
  public double Cookies
  {
    get { return cookies; }
    set {cookies = value; }
  }
}

To get a string i can send over the network ill just call the following function:

string str = new YAXSerializer(typeof (object)).Serialize(savegame);

Where the variable savegame is a instance from the "Speicherstand" class. There is no error, all works perfectly.

Also when i now send it over the network, it will be sent correctly.

Then on the other side i deserialize the string again:

object o = new YAXSerializer(typeof (object)).Deserialize(str);

Now when i want to cast o to Spielstand it will become null (using the "as" operator) and it throws an error using a cast.

Edit: i want to use object as type because ill wrote a api (for myself) so that i can easily send objects via your api over the network.

Edit2: The same thing (with the same api and so on) strangely works with the following "dataclass":

class Test
{
  public int T { get; set; }
  public override string ToString()
  {
    return string.Format("Test: {0}", T);
  }
}

Edit 3: Thats the xml file which gets null from your deserialization function:

<Object yaxlib:realtype=\"WpfApplication2.Speicherstand\" xmlns:yaxlib=\"http://www.sinairv.com/yaxlib/\">\r\n
  <Username>Julian</Username>\r\n
  <Granny>0</Granny>\r\n
  <Factory>0</Factory>\r\n
  <Farm>0</Farm>\r\n
  <Mine>0</Mine>\r\n
  <Cursor>1</Cursor>\r\n
  <GrannyCosts>300</GrannyCosts>\r\n
  <FactoryCosts>10000</FactoryCosts>\r\n
  <FarmCosts>7000</FarmCosts>\r\n
  <MineCosts>2000</MineCosts>\r\n
  <CursorCosts>150</CursorCosts>\r\n
  <Cookies>28</Cookies>\r\n
</Object>

Deserialize help

<ERROR code=\"8001\">IP未授权</ERROR>

how to Deserialize to :

public class Error
{
[YAXAttributeForClass]
public string Code { get; set; }

    [YAXElementFor("Error")]
    public string Msg { get; set; }
}

Reduce Cyclomatic Complexity

  • The source code is rather structured than object oriented. Many if branches can be prevented with a better object oriented design and polymorphism.
  • Some methods (esp in YAXSerializer) class are excessively long
  • Some naming conventions are Hungarian. Casing for static and private objects and methods do not seem proper. ReSharper default conventions seem to be OK.

Error by desiralize DateTime on german system

Hello,
by deserialize a DateTime object on a german windows the new DateTime is wrong (see example).

DateTime date = new DateTime(2015, 7, 20);
YAXLib.YAXSerializer s = new YAXLib.YAXSerializer(typeof(DateTime));
string xml = s.Serialize(date);
Console.WriteLine(xml); // <DateTime>07/20/2015 00:00:00</DateTime>
object obj = s.Deserialize(xml);
Console.WriteLine(obj); // 01.01.0001 00:00:00

This is because the ParseDateTimeTimeZoneSafe method in the StringUtils.cs class does not use the IFormatProvider parameter. Instead of using:

if (!DateTimeOffset.TryParse(str, out dto))

you must use:

if (!DateTimeOffset.TryParse(str, formatProvider, System.Globalization.DateTimeStyles.None, out dto))

Thank you for fixing this issue.
Gordon

Master broken!

Latest build from master:

https://ci.appveyor.com/project/SinaIravanian/yaxlib/build/2.13.32

Errors and Failures
1) Failed : YAXLibTests.DeserializationTest.DesNonGenericCollectionsSampleTest
  String lengths are both 1061. Strings differ at index 254.
  Expected: "...      Key:\r\n      [\r\n         02/01/2009 00:00:00\r\n      ]..."
  But was:  "...      Key:\r\n      [\r\n         1\r\n      ]\r\n      Value:\r\n  ..."
  ------------------------------------------------^
at YAXLibTests.DeserializationTest.PerformTestAndReturn(Object obj) in C:\xaxlib\YAXLibTests\DeserializationTest.cs:line 61
at YAXLibTests.DeserializationTest.PerformTest(Object obj) in C:\xaxlib\YAXLibTests\DeserializationTest.cs:line 40
at YAXLibTests.DeserializationTest.DesNonGenericCollectionsSampleTest() in C:\xaxlib\YAXLibTests\DeserializationTest.cs:line 328
Test Run Summary
  Overall result: Failed
  Test Count: 211, Passed: 210, Failed: 1, Inconclusive: 0, Skipped: 0
    Failed Tests - Failures: 1, Errors: 0, Invalid: 0
  Start time: 2017-02-18 09:45:47Z
    End time: 2017-02-18 09:45:49Z
    Duration: 2.329 seconds
Results saved as C:\xaxlib\TestResult.xml
SUMMARY: Total: 1 targets, Passed: 0, Failed: 1.
Command exited with code 1

[Question] Does YAX support object graph serialization

Hello.
I am interested in a question above. I need to serialize an object graph class with children and parent and I want to know is your lib could do that? Does it has preserve reference loop handling mechanism or something for that?

NHibernate + YaxLib = realtype = proxy

Hi
I have an NH app with YaxLib to export some data. However, when my data is exported, the data has the attribute realType="MyDataProxy". I know that I can configure this in NH so it uses the real class (which I have not tested though I presume it would fix it), but I dont want to use that because I want to still keep lazy loading.

My current fix is to have class ExportMyData and fill it using AutoMapper, however, I dont want to start duplicating all definitions and I would like this to be much simpler (to just put Yax attributes in my model classes).

Thanks

Add Bin/*.dll.mdb to .gitignore

When including YAXLib source tree into a project of mine and building it, the file Bin/YAXLib.dll.mdb is generated which is not ignored by git. It would make sense to ignore the Bin/*.dll.mdb pattern in .gitignore.

Serializing an Exception Crashes the application (no exception thrown)

Make a project and run this:

void Main()
{
try
{
int zero = 0;
int result = 100 / zero;
}
catch (DivideByZeroException ex)
{
LogSaveException(ex);
}
}

public void LogSaveException(object value)
{
try
{
YAXSerializer serializer = new YAXSerializer(value.GetType());
string loggedString = serializer.Serialize(value);
Console.WriteLine(loggedString);
}
catch (Exception)
{
Console.WriteLine("Log Error", "Could Not Log object of type " + value.GetType().ToString());
}
}

It will crash the app. (Even though you are catching all exceptions.)

How to display dynamic YAXSerializeAs value

Hi
I want to display XML like below. i dont know how to display child0 and child1 using YAXLib. kindly guide me
<child0 name="Unit1" key="" ...... </child0
Class

[YAXCollection(YAXCollectionSerializationTypes.Recursive,
EachElementName = "{Child}count")]
public CustomList Child { get; set; }

"Porting" to .NET Standard

Hi,
since you have upgraded your project to .NET Core, why you don't do a "definitive" step and create a .NET Standard library ?
Thanks in advance

Remove YAX prefix from classes and namespace

  • remove the redundant YAX prefix from every part of API.
  • Introduce generic methods wherever possible, instead of passing around System.Type objects.
  • The namespaces and other names could be renamed from YAX... to Yax...

Feature request: Attribute to skip some properties of an object

I have checked the class but I don't have found an attribute that allow to skip the serialization of some properties in a class.
I try to explain my problem.
I need to serialize a property of type System.Drawing.Size, and the lib works perfectly, but in the serialized file I have also the property IsEmpty that is not necessary.
Could be possible to skip this serialization?
Could be interesting to have an attribute that allow to define a list of properties to ignore during the serialization (necessary for classes/structures standard or from external assemblies)
For example (example to skip IsEmpty and Height properties)
[YAXSkipProperties("IsEmpty;Height")]

I don't know if this is possible without make a custom serializer
Thanks for any answer

SerializeAs using YAXSerializeAs attribute replace ":" by "_"

Hi,

Maybe it is me who's not using the library properly. But I was wondering why the ":" was replaced by "_" while doing the serialization?

Example

        [YAXCollection(YAXCollectionSerializationTypes.Recursive, EachElementName = "zone:name")]
        [YAXSerializeAs("zone:list")]
        public List<string> Zones { get; set; }

I will see the XML output as "zone_list" and "zone_name".

Thank you

New Release?

Hi, this is probably not strictly an issue, but I was wondering if you were planning another release at any point? Specifically, it would be useful for me if the line number changes I did a while ago could make it into a version on Nuget.
Thanks,
Richard

Dictionaries with null values crash serializer

Assuming you have a Dictionary, with the valid form:

{
"Key": null
}

An attempt to serialize this throws a null-pointer exception.

Stacktrace:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Object.GetType()
   at YAXLib.YAXSerializer.AddObjectToElement(XElement elem, XName alias, Object obj) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 1328
   at YAXLib.YAXSerializer.MakeDictionaryElement(XElement insertionLocation, XName elementName, Object elementValue, YAXDictionaryAttribute dicAttrInst, YAXCollectionAttribute collectionAttrInst) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 1297
   at YAXLib.YAXSerializer.AddObjectToElement(XElement elem, XName alias, Object obj) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 1337
   at YAXLib.YAXSerializer.MakeCollectionElement(XElement insertionLocation, XName elementName, Object elementValue, YAXCollectionAttribute collectionAttrInst, String format) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 1469
   at YAXLib.YAXSerializer.MakeElement(XElement insertionLocation, MemberWrapper member, Object elementValue, Boolean& moveDescOnly, Boolean& alreadyAdded) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 1112
   at YAXLib.YAXSerializer.SerializeBase(Object obj, XName className) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 907
   at YAXLib.YAXSerializer.SerializeBase(Object obj) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 609
   at YAXLib.YAXSerializer.SerializeXDocument(Object obj) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 539
   at YAXLib.YAXSerializer.Serialize(Object obj, XmlWriter xmlWriter) in d:\Codes\GitHub\YAXLib\YAXLib\YAXSerializer.cs:line 380
// snip

The value of null should be allowed/supported as a value in a dictionary.

Custom Root element

Is there a way to set a custom root element for deserialization?
Use Case: I don't have control over the XML I receive and I just want some data deeper down the hierarchy.

Feature request: Allow specifying custom serializers at runtime

Right now it seems I have to use a [YAXCustomSerializer] attribute on types that I need custom serialization for. However, this doesn't suit my use case and I haven't found any other XML serializer that can do what YAXLib does.

We are using YAXLib in a CQRS application to keep an audit of what commands and queries are run. The auditing is done via interception. Basically this means that at compile time, I don't know exactly what objects I'm going to be serializing, as commands and queries can take any number of parameters and could return anything as well. When the interception ocurrs, the auditing layer wraps whatever it serializes into an object that looks like this:

/// <summary>
/// Contains information about an operation that has taken place in the system.
/// </summary>
public class InterceptedData
{
    public InterceptedData()
    {
        Children = new List<InterceptedData>();
        Parameters = new List<Parameter>();
    }
    /// <summary>
    /// Method (operation) name that was invoked.
    /// </summary>
    public string MethodName { get; set; }

    /// <summary>
    /// Parameters that were passed to the operation.
    /// </summary>
    public List<Parameter> Parameters { get; set; }

    /// <summary>
    /// Gets or sets the return value.
    /// </summary>
    public ReturnValue ReturnValue { get; set; }

    /// <summary>
    /// Additional audits that were triggered by this operation.
    /// </summary>
    public List<InterceptedData> Children { get; set; }

    /// <summary>
    /// Exception object, if an exception was thrown by the operation.
    /// </summary>
    public ExceptionDetails Exception { get; set; }
}

Where Parameter looks like this:

public class Parameter
{
    public string Name { get; set; }

    public string Type { get; set; }

    public object Value { get; set; }
}

And ReturnValue looks like this:

public class ReturnValue
{
    private readonly object value;

    public ReturnValue(object value)
    {
        this.value = value;
    }

    public object Value
    {
        get
        {
            if(this.value is byte[])
            {
                return Convert.ToBase64String(this.value as byte[]);
            }
            return this.value;
        }
    }

    public object[] Items
    {
        get
        {
            if(value is string || value is byte[])
            {
                return null;
            }
            if (value.GetType().GetInterface(typeof(IEnumerable).FullName) != null)
            {
                return (object[])value.GetType().GetMethod("ToArray").Invoke(value, new object[] { });
            }

            return null;
        }
    }
}

So as you can see, anything can be put into these Parameter and ReturnValue objects. YAX has done very well with this, where other serializers have either thrown errors at runtime about unknown types, or just skipped those members when encountering them.

My biggest issue is with byte arrays, because YAX serializes those with a single element per byte, like so:

<Document>
      <Byte>80</Byte>
      <Byte>75</Byte>
      <Byte>3</Byte>
      <Byte>4</Byte>
      ....
</Document>

This takes up a lot of space, so we want to base64 encode any byte arrays the serializer encounters. I did some reading up and I see that YAX does supply an interface to provide custom serialization, so I wrote this quick and dirty custom serializer:

public class ByteArraySerialzer : ICustomSerializer<byte[]>
{
    public byte[] DeserializeFromAttribute(XAttribute attrib)
    {
        return Convert.FromBase64String(attrib.Value);
    }

    public byte[] DeserializeFromElement(XElement element)
    {
        return Convert.FromBase64String(element.Value);
    }

    public byte[] DeserializeFromValue(string value)
    {
        return Convert.FromBase64String(value);
    }

    public void SerializeToAttribute(byte[] objectToSerialize, XAttribute attrToFill)
    {
        attrToFill.Value = Convert.ToBase64String(objectToSerialize);
    }

    public void SerializeToElement(byte[] objectToSerialize, XElement elemToFill)
    {
        elemToFill.Value = Convert.ToBase64String(objectToSerialize);
    }

    public string SerializeToValue(byte[] objectToSerialize)
    {
        return Convert.ToBase64String(objectToSerialize);
    }
}

Now my problem is telling the serializer to use it. I can't go and stick it on my Parameter and ReturnValue members. YAX also doesn't expose any way that I can see to hook into the serialization process. Basically I'd like to be able to say "while serializing if T is encountered and there is a ICustomSerializer<T> registered, use that instead of base serialization".

I'm able to specify what custom serializers I want to be registered at the initialization stage and I should never need to change those serializers at any point in the lifetime of the serializer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.