'Trying to create maintainable custom XML C# Class Serialization (Will be used in AWS Lambda project)

We are trying to develop a class library to interface with a service that provides each function as a web service endpoint (we will be using about 200-300 of these, perhaps more). We will be using AWS Lambda as a proxy between this and other services.

While WSDL are available, the amount of code that is generated through "Add Service Reference" is massive (will generate 250,000+ lines of code, could be more), and the element names can be cryptic and are all caps. These classes will also have several subclasses and enums due to XML enumerations (each class added will have an enum that is 1700 items)

I want to avoid this bloat, so I was looking at custom classes and custom serialization. I wanted to come up with a generalized serialization methodology to avoid what seems like an obvious pit fall of individual class serializers.

I've looked at custom attributes, and this could work, but there are some complexities.

First, there are choice elements in the XSD that need to be addressed, as well as nested elements, as an example

<xs:element name="CODEDESCFIELD">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="CODEVALUE"/>
      <xs:element ref="DESCRIPTION" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

and, with attributes

<xs:element name="ENTITYCODEFIELD">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="CODEVALUE"/>
      <xs:element ref="DESCRIPTION" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="entity" type="xs:string"/>
  </xs:complexType>
</xs:element>

as well as stuff like

<xs:complexType name="DATETIME">
  <xs:sequence>
    <xs:element ref="of:YEAR"/>
    <xs:element ref="of:MONTH"/>
    <xs:element ref="of:DAY"/>
    <xs:element ref="of:HOUR"/>
    <xs:element ref="of:MINUTE"/>
    <xs:element ref="of:SECOND"/>
    <xs:element ref="of:SUBSECOND"/>
    <xs:element ref="of:TIMEZONE"/>
  </xs:sequence>
  <xs:attribute name="qualifier" type="DATETIMEqual" use="required"/>
</xs:complexType>
<xs:simpleType name="DATETIMEqual">
  <xs:restriction base="xs:string">
    <xs:enumeration value="ACCOUNTING"/>
    <xs:enumeration value="ACTEND"/>
    <xs:enumeration value="ACTSTART"/>
    <xs:enumeration value="APPREQ"/>
    <xs:enumeration value="APPROVAL"/>
    <xs:enumeration value="AVAILABLE"/>
    <xs:enumeration value="BKTEND"/>
    <xs:enumeration value="BKTSTART"/>
    <xs:enumeration value="CANCEL"/>
    <xs:enumeration value="CHANGEDATE"/>
    <xs:enumeration value="COMPDATE"/>
    <xs:enumeration value="CONSUME"/>           
    <xs:enumeration value="CREATION"/>
    <xs:enumeration value="CUMULATIVE"/>
    <xs:enumeration value="DELIVACT"/>
    <xs:enumeration value="DELIVSCHED"/>
    <xs:enumeration value="DISCNT"/>
    <xs:enumeration value="DOCUMENT"/>
    <xs:enumeration value="DUE"/>
    <xs:enumeration value="EARLSTEFF"/>
    <xs:enumeration value="EARLSTSHIP"/>
    <xs:enumeration value="EFFECTIVE"/>
    <xs:enumeration value="ENGCHG"/>
    <xs:enumeration value="EXECFINISH"/>
    <xs:enumeration value="EXECSTART"/>
    <xs:enumeration value="EXPIRATION"/>
    <xs:enumeration value="FAILDATE"/>
    <xs:enumeration value="FORECASTF"/>
    <xs:enumeration value="FORECASTS"/>
    <xs:enumeration value="FROM"/>
    <xs:enumeration value="GENERATION"/>
    <xs:enumeration value="JOBDUE"/>
    <xs:enumeration value="IMPL"/>
    <xs:enumeration value="INVOICE"/>
    <xs:enumeration value="LABORFINSH"/>
    <xs:enumeration value="LABORSTART"/>
    <xs:enumeration value="LASTUSED"/>
    <xs:enumeration value="LOADING"/>
    <xs:enumeration value="MATCHING"/>
    <xs:enumeration value="MSMENTDATE"/>
    <xs:enumeration value="NEEDDELV"/>
    <xs:enumeration value="OPFINISH"/>
    <xs:enumeration value="OPSTART"/>
    <xs:enumeration value="PAYEND"/>
    <xs:enumeration value="PLANEND"/>
    <xs:enumeration value="PLANSTART"/>
    <xs:enumeration value="PO"/>
    <xs:enumeration value="PROMDELV"/>
    <xs:enumeration value="PROMSHIP"/>
    <xs:enumeration value="PYMTTERM"/>
    <xs:enumeration value="RECEIVED"/>
    <xs:enumeration value="REPORTDATE"/>
    <xs:enumeration value="REPORTNGFN"/>
    <xs:enumeration value="REPORTNGST"/>
    <xs:enumeration value="REQUIRED"/>
    <xs:enumeration value="RESORCDWNF"/>
    <xs:enumeration value="RESORCDWNS"/>
    <xs:enumeration value="RSPDDATE"/>
    <xs:enumeration value="RSPDOCGEN"/>
    <xs:enumeration value="SCHEND"/>
    <xs:enumeration value="SCHSTART"/>
    <xs:enumeration value="SETUPFINSH"/>
    <xs:enumeration value="SETUPSTART"/>
    <xs:enumeration value="SHIP"/>
    <xs:enumeration value="SHIPSCHED"/>
    <xs:enumeration value="STATUSDATE"/>
    <xs:enumeration value="TEARDOWNF"/>
    <xs:enumeration value="TEARDOWNS"/>
    <xs:enumeration value="TO"/>
    <xs:enumeration value="OTHER"/>
  </xs:restriction>
</xs:simpleType>

where DATETIME should serialize to System.DateTime and the DATETIMEqual is not needed at all (the service suggests defaulting to "Other").

I had a thought of possibly using a dictionary for passing around serialization information, but this seems like it would complicate maintenance and extension, though would be better (possibly) then individualized serializers.

So, my question. Is there a relatively maintainable way of accomplishing custom serialization of custom classes, or is it better to use built in serializers? While I know the response will generally be "premature optimization" but is there performance cost that can be avoided using custom serialization? While my bigger bottleneck will be API calls, if we can shave off a reasonable amount of time in serialization, that would reduce cost (using AWS Lambda).

Any thoughts would be welcome.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source