First segment of a SegmentGroup is always null (tested with different configs, workaround proposal inside TryCreateContainer)
- Dominant language
- C#
- Stars
- 490
- Forks
- 173
- PR merge metrics
- No merged PRs in 30d
Description
Hello,
While working with EDIFACT ORDERS messages, I've run into an issue with indice.Edi:
the first segment of a SegmentGroup is always null when deserializing, regardless of how the attributes are configured.
```
[EdiMessage]
public class Orders {
public UNH UNH { get; set; }
public Orders_Header Header { get; set; }
}
[EdiElement, EdiSegmentGroup("BGM", SequenceEnd = "LIN", Mandatory = true)]
public class Orders_Header {
[EdiElement] // <- with this attribut, only first part is valorized (BGM[0][0]) in BGM object
public BGM BGM { get; set; } // <- always null without modification (tried every possible attribute configuration on class, property, with or without initialization [ = new BGM();] etc.)
public List DTM { get; set; } = new List();
public List NAD { get; set; } = new List();
public List RFF { get; set; } = new List();
public List CUX { get; set; } = new List();
}
[EdiSegment, EdiPath("UNH")]
public class UNH {}
[EdiSegment, EdiPath("BGM")]
public class BGM {}
etc...
```
**Tests performed**
I tried different configurations to see how Edi.Net handled the group. Here are four simplified cases:
(with declared order always, UNH, BGM, DTM etc...)
1) UNH and BGM declared at root:
[EdiElement, EdiSegmentGroup("**DTM**"_[, SequenceEnd = "LIN", Mandatory = true]_)] // <- many test on that
public class Orders_Header { }
> UNH is filled correctly
> BGM at root is filled correctly
> But DTM in the header remains empty
2) UNH at root, BGM declared inside Header group:
[EdiElement, EdiSegmentGroup("**BGM**"_[, SequenceEnd = "LIN", Mandatory = true]_)] // <- many test on that, BGM, UNH, UNA etc....
public class Orders_Header { }
> UNH filled correctly
> DTM in header filled correctly
> But BGM is always null
3) UNH at root, BGM declared inside Header group:
[EdiElement, EdiSegmentGroup("**UNH**"_[, SequenceEnd = "LIN", Mandatory = true]_)]
public class Orders_Header { }
> UNH filled correctly
> DTM filled correctly
> But BGM is null
4) Both UNH and BGM declared inside Header group:
[EdiElement, EdiSegmentGroup("**UNH**"_[, SequenceEnd = "LIN", Mandatory = true]_)]
public class Orders_Header { }
> BGM filled correctly
> DTM filled correctly
> But UNH is now null
In all these scenarios, the first segment of the group (BGM) is never deserialized.
**Current behavior**
> UNH is deserialized correctly at root.
> BGM inside Orders_Header is always null.
> Other segments like DTM / NAD / RFF work fine.
**Investigation**
Looking into EdiSerializer.cs, method TryCreateContainer, I suspect the issue is related to the fact that when the reader is at EdiToken.ElementStart, the stack top remains an EdiElement, so the first segment in the group is never promoted to EdiSegment.
**Attempted workaround**
I experimented by inserting this block around line ~391 of TryCreateContainer (simplified here):
```
if (reader.TokenType == EdiToken.ElementStart && stack.Count > 0) {
EdiStructure currentStack = stack.Peek();
if (currentStack.StructureType == EdiStructureType.Element
&& currentStack.Index == 0
&& currentStack.Descriptor.Attributes.OfType().Any())
{
EdiStructure nStack = new EdiStructure(
EdiStructureType.Segment,
currentStack.Container,
null,
currentStack.Instance,
currentStack.Index + 1,
currentStack.CachedReads
);
stack.Pop();
stack.Push(nStack);
}
}
```
in else statement, before
```
// strict hierarchy
while (stack.Peek().StructureType >= newContainer) {
var previous = stack.Pop(); // close this level
if (previous.StructureType == newContainer)
index = previous.Index + 1; // seed collection index
}
```
This appears to allow [EdiElement] to bind correctly to the first segment of the group (BGM in this case).
**Important note**
⚠️ I am not sure if this is the right place for the fix, or whether my added condition is safe in all scenarios.
I also haven’t tested it with serialization yet — only deserialization.
**Request**
Could you please confirm:
> if this is indeed the root cause of the bug,
> and whether the above modification (or a cleaner variation) is a valid fix?
> maybe I'm using attributes wrong, but honestly I've tried a lot of things, EdiGroup, EdiSegmentGroup etc... combinations of several, on classes, properties (I spent more than 4 hours on it)
Thank you very much for the library, it was very useful to me anyway, I will continue like this, try to fix the serialization and I will continue my little business in the meantime! ^^
edi sample:
```
UNA:+.? '
UNB+UNOA:3+SENDER+RECEIVER+250101:1200+1'
UNH+1+ORDERS:D:96A:UN'
BGM+220+PO12345+9'
DTM+137:20250101:102'
UNT+4+1'
UNZ+1+1'
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in EdiSerializer.cs at TryCreateContainer and reproduce the issue with the EDIFACT sample and Orders/Orders_Header mapping shown here. Trace the EdiToken.ElementStart stack transition and verify that BGM binds as the first segment without breaking DTM or the other group mappings; then test both deserialization and serialization before considering the issue done.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100