indice-co / EDI.Net

EDI Serializer/Deserializer. Supports EDIFact, X12 and TRADACOMS formats
MIT License
453 stars 169 forks source link

Serializing Deserializing Message without Interchange #137

Closed Gerric-vog closed 5 years ago

Gerric-vog commented 5 years ago

Hello, I've created a Edifact D96A Pricat message with Interchange - this works really well both serializing and deserializing. Now I'm in a situation where I need to create the D96A message without the Interchange, and then add the Interchange in a later step. Serializing just the message results in an Interchange field being added by the serializer (UNA), and after removing this manually from the outfile and trying to deserialize it (starting with with UNH) the execution fails with an "System.InvalidOperationException" "Stack empty".

I'm not sure if this is the right approach or if there's something I'm missing. Any help or advice would be much appreciated.

cleftheris commented 5 years ago

Hi @Gerric-vog and thanks for your interest to the library. As I understand you situation your need to deserialize partially a transmission. Theoretically speaking one could omit all structural elements and should work fine. I have not tried to keep the message container though.

I will check it out. In the meantime if you can make a failing test to showcase the issue that would be great.

Gerric-vog commented 5 years ago

Yes, the workflow, if you will, would be 1) Create the the D96A pricat message (just the message, no interchange) and serialize it (at a common "point" for all pricats and data consumers) 2) Deserialize this message and inject it into a Interchange (at a distribution point with specific data consumer details) and serialize the complete interchange + message.

I'll see if I can manage to showcase a failing test.

Gerric-vog commented 5 years ago

A simple class with header and trailer.

<EdiMessage(Description:="Price/sales catalogue message")>
Public Class D96APricatMessage

    <EdiValue("X(14)", Path:="UNH/0/0")>
    Public Property MessageReferenceNumberHeader As String
    <EdiValue("X(6)", Mandatory:=True, Path:="UNH/1/0")>
    Public Property MessageType As String
    <EdiValue("X(1)", Mandatory:=True, Path:="UNH/1/1")>
    Public Property MessageVersionNumber As String
    <EdiValue("X(3)", Mandatory:=True, Path:="UNH/1/2")>
    Public Property MessageReleaseNumber As String
    <EdiValue("X(3)", Mandatory:=True, Path:="UNH/1/3")>
    Public Property ControllingAgencyCoded As String
    <EdiValue("X(6)", Path:="UNH/1/4")>
    Public Property AssociationAssignedCode As String
    <EdiValue("X(6)", Path:="UNH/1/5")>
    Public Property CodeListDirectoryVersionNumber As String
    <EdiValue("X(6)", Path:="UNH/1/6")>
    Public Property MessageTypeSubFunctionIdentification As String

    <EdiValue("X(35)", Path:="UNH/2")>
    Public Property CommonAcessReference As String
    <EdiValue("9(3)", Path:="UNT/0")>
    Public Property NumberOfSegmentsInAMessage As String
    <EdiValue("X(14)", Path:="UNT/1")>
    Public Property MessageReferenceNumberTrailer As String

End Class

A simple module for testing.

Module Module1

    Sub Main()
        Dim grammar As IEdiGrammar = EdiGrammar.NewEdiFact

        Dim D96APricat As D96APricatMessage = New D96APricatMessage

        Dim EdiSer As EdiSerializer = New EdiSerializer()

        Dim Path As String = "C:\pricat.edi"

        Using textWriter As New StreamWriter(File.Open(Path, FileMode.Create), Text.Encoding.Default)
            With D96APricat
                .MessageReferenceNumberHeader = "260178"
                .MessageType = "PRICAT"
                .MessageVersionNumber = "D"
                .MessageReleaseNumber = "96A"
                .ControllingAgencyCoded = "UN"
                .AssociationAssignedCode = "EAN006"
            End With

            With D96APricat
                .MessageReferenceNumberTrailer = "260178"
            End With

            Using EdiWriter As New EdiTextWriter(textWriter, grammar)
                EdiWriter.Formatting = Formatting.LinePerSegment
                EdiSer.Serialize(EdiWriter, D96APricat)
            End Using

        End Using

        Using Text As TextReader = New StreamReader(Path)
            D96APricat = EdiSer.Deserialize(Of D96APricatMessage)(Text, grammar)
        End Using

    End Sub

End Module
cleftheris commented 5 years ago

Hi @Gerric-vog,

you where right about this. I pushed a minor release at nugget that tackles this issue. I am not 100% sure I should be doing this but it makes sense for debug usecases. As of v1.9.2 a transmission can be deserialized without the interchange segments being present in the data file.

Please check-it out and send feedback

Gerric-vog commented 5 years ago

Hello @cleftheris ,

The message deserialized fine with this update. The serializer still outputs "UNA:+.? ", however this does not seem to matter when deserializing.

Thanks. 👍