Custom Flat File - Type String must have a static Validate method
I am exploring the validation of custom flat files and I am seeing the error message "Type String must have a static Validate method. Please refer to the documentation." upon the execution of EdiMessage.IsValid(). The result received over the addition of a DataElementAttribute of a field was unexpected, as the attribute was applied to other fields in the template without issue.
Observed results are from version 10.7.5. We are working with a pipe-delimited file with a single record format. A DataElementAttribute was added to several fields to specify an id with the intention of populating that id to the DataElementErrorContext.Name property. The DataElementAttribute was added to six fields in our record template without issue, however when adding to an additional field in the file the indicated exception is received.
We have a template for the record, configured to a pipe delimited format without a record identifier field.
[Serializable()]
[Segment("", '|')]
public class ExampleRecord
In working state, we have a DataElementAttribute applied to two required fields and to four fields representing two pairs of RequiredAny().
[Required]
[StringLength(1, 1)]
[DataElement("ETHNICITY_CODE", typeof(string))]
[Pos(35)]
public string ETHNICITY_CODE { get; set; }
[RequiredAny(40, 41)]
[StringLength(1, 9)]
[DataElement("PRODUCT_ID", typeof(string))]
[Pos(40)]
public string PRODUCT_ID { get; set; }
[RequiredAny(40, 41)]
[StringLength(1, 20)]
[DataElement("CLIENT_PROGRAM_CODE", typeof(string))]
[Pos(41)]
public string CLIENT_PROGRAM_CODE { get; set; }
[RequiredAny(44, 45)]
[StringLength(1, 9)]
[DataElement("PREMIUM_GROUP_ID", typeof(string))]
[Pos(44)]
public string PREMIUM_GROUP_ID { get; set; }
[RequiredAny(44, 45)]
[StringLength(1, 80)]
[DataElement("CLIENT_EMPLOYER_GROUP_CODE", typeof(string))]
[Pos(45)]
public string CLIENT_EMPLOYER_GROUP_CODE { get; set; }
[Required]
[StringLength(1, 1)]
[DataElement("LATE_ENROLEE_FLAG", typeof(string))]
[Pos(54)]
public string LATE_ENROLEE_FLAG { get; set; }
Using the below reporting code, we are getting the following results. At this point a DataElementAttribute is not applied to the field in position 5. We have intended results, with the required field messages using the specified id to indicate the name of the invalidated field. (No data in fields 5, 35, 40/41, 44/45 & 54)
private string GenerateReportForError(MessageErrorContext errorContext)
{
StringBuilder sbResults = new StringBuilder();
foreach (var recordError in errorContext.Errors)
{
sbResults.AppendLine($"Record Errors at Position {recordError.Position}");
foreach (var fieldError in recordError.Errors)
{
sbResults.AppendLine($"\tField Error at Position {fieldError.Position} ({fieldError.Code}): {fieldError.Message}");
}
sbResults.AppendLine();
}
return sbResults.ToString();
}
Record Errors at Position 1
Field Error at Position 5 (RequiredDataElementMissing): Mandatory data element in position 5 is missing.
Field Error at Position 35 (RequiredDataElementMissing): Mandatory data element ETHNICITY_CODE in position 35 is missing.
Field Error at Position 40 (ConditionalRequiredDataElementMissing):
Field Error at Position 41 (ConditionalRequiredDataElementMissing):
Field Error at Position 44 (ConditionalRequiredDataElementMissing):
Field Error at Position 45 (ConditionalRequiredDataElementMissing):
Field Error at Position 54 (RequiredDataElementMissing): Mandatory data element LATE_ENROLEE_FLAG in position 54 is missing.
When the above working state is updated to apply the DataElementAttribute to the filed in position 5, the "Type String must have a static Validate method" is thrown when executing EdiMessage.IsValid(). Nothing significant seems to differ as far as the attributes between the example below and the above examples using the Required attribute. Attempts to locate further information in documentation as suggested by the exception message were not successful.
[Required]
[StringLength(2, 60)]
[DataElement("LAST_NAME", typeof(string))]
[Pos(5)]
public string LAST_NAME { get; set; }
System.Exception
HResult=0x80131500
Message=Type String must have a static Validate method. Please refer to the documentation.
Source=EdiFabric
StackTrace:
at EdiFabric.Core.Annotations.Validation.DataElementAttribute.(String )
at EdiFabric.Core.Annotations.Validation.DataElementAttribute.(String , ValidationContext )
at EdiFabric.Core.Annotations.Validation.DataElementAttribute.ValidateEdi(ValidationContext validationContext)
at EdiFabric.Core.Model.Edi.InstanceContext.Validate(Int32 segmentIndex, Int32 inSegmentIndex, Int32 inComponentIndex, ValidationSettings validationSettings)
at EdiFabric.Core.Model.Edi.EdiMessage.(Int32& , ValidationSettings )
at EdiFabric.Core.Model.Edi.EdiMessage.IsValid(MessageErrorContext& result, ValidationSettings validationSettings)
Comments
3 comments
Hello,
You can learn more about the flat file component here. To learn how to create templates for flat files go here. Example solutions with custom flat file templates in GitHub are here.
Regarding your question - for data elements in flat files, you can only use the [Required] attribute, and [StringLength] attributes for positional segments. The [DataElement] attribute is only supported for certain types, such as X12_AN or EDIFACT_AN, and must not be used for flat files or with types, which are not supported for the particular standard.
If you remove the [DataElement] attribute from your template, and follow the instructions in the linked articles, you will be able to implement EdiFabric templates for your flat files.
Thank You, I am familiar with those articles & the associated example files references in the articles and source control.
Thank you for the clarification that DataElementAttribute is not applicable to flat files. I had that suspicion, but the framework returning the exact result I was looking for led me to continue attempting that approach. (DataElementErrorContext.Name populated). Would I be correct to assume that we would need to implement our own ValidationAttribute to allow for DataElementErrorContext.Name to be populated?
Clarification on the indication that only [Required] and [StringLength] attributes are allowed. I see indication of a positional segment, while we are working with a delimited file format. Does that apply to delimited files as well? We have observed that the [RequiredAny(40, 41)] works as intended, only generating an error if both fields are not provided. Is there an article that is very explicit on which attributes apply to flat files and which ones are not allowed? The provided article is not clear, with a potential implicit indication concerning positional formats.
Understanding the options and differences between EDI and Proprietary template validations is helpful in evaluating the suitability of this framework beyond EDI, with this particular file format representing the least complex side of the proprietary file spectrum.
Hello Christopher,
On a second read, you can use ALL EdiFabric attributes in the templates for flat files too, there is no difference. I'm a bit rusty on the flat file component, so discard the bit I said you can't use attributes with it.
So, to reply to the original question:
1. You can use the [StringLength] attribute with delimited segments as well as positional segments (for which it is mandatory), no problem.
2. You can use The [DataElement] attribute but only with the supported data types, e.g., the second parameter can't be typeof(string). It must be any of the supported types, here is the list for X12 and here for EDIFACT.
Hope it helps.
Please sign in to leave a comment.