I’m having an issue with a piece of code that handles data parsing from a DataRow
into a custom model AssetItemImport
. The specific problem occurs when I try to set the ECNs
field in DataRow
to a non-empty string, like ‘test’. When ECNs
is empty, everything works perfectly, but with any non-empty string, an error occurs even though ECNs
should simply receive a value from the Asset
field.
Here’s a shortened version of the parsing code:
namespace Entegri.EMD.Models.ImportModels
{
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using Entegri.Base.Attributes;
using Entegri.Base.Data;
using Entegri.Base.Extensions;
using Entegri.EMD.Models.AttributeExtensions;
using Entegri.ExcelLibrary;
/// <summary>
/// AssetItemImport.
/// </summary>
/// <seealso cref="Entegri.ExcelLibrary.BaseExcelModel" />
[Table("AssetItemImport")]
[TrackTable(AuditLogTableNameConstants.AssetItemImport)]
public class AssetItemImport : IEntityUpdate
{
/// <summary>
/// Gets or sets the asset item import identifier.
/// </summary>
/// <value>
/// The asset item import identifier.
/// </value>
[Key]
public int AssetItemImportID { get; set; }
/// <summary>
/// Gets or sets the asset.
/// </summary>
/// <value>
/// The asset.
/// </value>
[StringLength(50, ErrorMessage = "Asset must not exceed 50 characters.")]
[ExcelImport]
public string Asset { get; set; }
/// <summary>
/// Gets or sets the prefix.
/// </summary>
/// <value>
/// The prefix.
/// </value>
[StringLength(10, ErrorMessage = "Prefix must not exceed 10 characters.")]
[ExcelImport]
public string Prefix { get; set; }
/// <summary>
/// Gets or sets the description.
/// </summary>
/// <value>
/// The description.
/// </value>
[ExcelImport]
public string Description { get; set; }
/// <summary>
/// Gets or sets the type of the asset sub.
/// </summary>
/// <value>
/// The type of the asset sub.
/// </value>
[StringLength(50, ErrorMessage = "AssetSubType must not exceed 50 characters.")]
[ExcelImport]
public string AssetSubType { get; set; }
/// <summary>
/// Gets or sets the current user identifier.
/// </summary>
/// <value>
/// The current user identifier.
/// </value>
public int CurrentUserID { get; set; }
/// <summary>
/// Gets or sets the location.
/// </summary>
/// <value>
/// The location.
/// </value>
[StringLength(50, ErrorMessage = "Location must not exceed 50 characters.")]
[ExcelImport]
public string Location { get; set; }
/// <summary>
/// Gets or sets the sub type product.
/// </summary>
/// <value>
/// The sub type product.
/// </value>
[StringLength(20, ErrorMessage = "PartNo must not exceed 20 characters.")]
[ExcelImport]
public string SubTypeProduct { get; set; }
/// <summary>
/// Gets or sets the owner.
/// </summary>
/// <value>
/// The owner.
/// </value>
[StringLength(20, ErrorMessage = "Owner must not exceed 20 characters.")]
[ExcelImport]
public string Owner { get; set; }
/// <summary>
/// Gets or sets the source.
/// </summary>
/// <value>
/// The source.
/// </value>
[StringLength(100, ErrorMessage = "Source must not exceed 100 characters.")]
[ExcelImport]
public string Source { get; set; }
/// <summary>
/// Gets or sets the cs drawing reference.
/// </summary>
/// <value>
/// The cs drawing reference.
/// </value>
[StringLength(255, ErrorMessage = "CS Drawing Ref must not exceed 255 characters.")]
[ExcelImport]
public string CSDrawingRef { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [not for purchase].
/// </summary>
/// <value>
/// <c>true</c> if [not for purchase]; otherwise, <c>false</c>.
/// </value>
[ExcelImport]
public bool NotForPurchase { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [free issue].
/// </summary>
/// <value>
/// <c>true</c> if [free issue]; otherwise, <c>false</c>.
/// </value>
[ExcelImport]
public bool FreeIssue { get; set; }
/// <summary>
/// Gets or sets the serial no.
/// </summary>
/// <value>
/// The serial no.
/// </value>
[StringLength(100, ErrorMessage = "Serial No must not exceed 100 characters.")]
[ExcelImport]
public string SerialNo { get; set; }
/// <summary>
/// Gets or sets the WBS assembly.
/// </summary>
/// <value>
/// The WBS assembly.
/// </value>
[StringLength(20, ErrorMessage = "WBSAssembly must not exceed 20 characters.")]
[ExcelImport]
public string WBSAssembly { get; set; }
/// <summary>
/// Gets or sets the omcsid.
/// </summary>
/// <value>
/// The omcsid.
/// </value>
[StringLength(50, ErrorMessage = "OMCS ID must not exceed 50 characters.")]
[ExcelImport]
public string OMCSID { get; set; }
/// <summary>
/// Gets or sets the asset WBS.
/// </summary>
/// <value>
/// The asset WBS.
/// </value>
[StringLength(100, ErrorMessage = "WBS must not exceed 100 characters.")]
[ExcelImport]
public string AssetWBS { get; set; }
/// <summary>
/// Gets or sets the project control line.
/// </summary>
/// <value>
/// The project control line.
/// </value>
[ExcelImport]
public string ProjectControlLine { get; set; }
/// <summary>
/// Gets or sets the chainage.
/// </summary>
/// <value>
/// The chainage.
/// </value>
[ExcelImport]
public decimal Chainage { get; set; }
/// <summary>
/// Gets or sets the offset.
/// </summary>
/// <value>
/// The offset.
/// </value>
[ExcelImport]
public int Offset { get; set; }
/// <summary>
/// Gets or sets the r l.
/// </summary>
/// <value>
/// The r l.
/// </value>
[ExcelImport]
public int R_L { get; set; }
/// <summary>
/// Gets or sets the northings.
/// </summary>
/// <value>
/// The northings.
/// </value>
[ExcelImport]
public decimal Northings { get; set; }
/// <summary>
/// Gets or sets the eastings.
/// </summary>
/// <value>
/// The eastings.
/// </value>
[ExcelImport]
public decimal Eastings { get; set; }
/// <summary>
/// Gets or sets the latitude.
/// </summary>
/// <value>
/// The latitude.
/// </value>
[ExcelImport]
public decimal Latitude { get; set; }
/// <summary>
/// Gets or sets the longtitude.
/// </summary>
/// <value>
/// The longtitude.
/// </value>
[ExcelImport]
public decimal Longtitude { get; set; }
/// <summary>
/// Gets or sets the package.
/// </summary>
/// <value>
/// The package.
/// </value>
[StringLength(50, ErrorMessage = "Package must not exceed 50 characters.")]
[ExcelImport]
public string Package { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [ECN].
/// </summary>
/// <value>
/// <c>true</c> if [ECN]; otherwise, <c>false</c>.
/// </value>
[ExcelImport]
public bool ECN { get; set; }
/// <summary>
/// Gets or sets the ECNs.
/// </summary>
/// <value>
/// The ECNs.
/// </value>
[StringLength(255, ErrorMessage = "ECNs must not exceed 255 characters.")]
[ExcelImport]
public string ECNs { get; set; }
/// <summary>
/// Gets or sets the status.
/// </summary>
/// <value>
/// The status.
/// </value>
public string Status { get; set; }
/// <summary>
/// Gets or sets the errors.
/// </summary>
/// <value>
/// The errors.
/// </value>
[NotMapped]
public string Errors { get; set; }
/// <summary>
/// Validates the excel data.
/// </summary>
/// <param name="action">The action.</param>
public static void ValidateExcelData((DataRow dr, DataColumnCollection dc, BaseExcelModel be) action)
{
// Method intentionally left empty.
}
/// <summary>
/// Parses from data row.
/// </summary>
/// <param name="row">The row.</param>
/// <returns>dto.</returns>
public static AssetItemImport ParseFromDataRow(DataRow row)
{
AssetItemImport dto = new AssetItemImport();
dto.Asset = row.GetValue<string>(nameof(Asset));
dto.Prefix = row.GetValue<string>(nameof(Prefix));
dto.Description = row.GetValue<string>(nameof(Description));
dto.AssetSubType = row.GetValue<string>(nameof(AssetSubType));
dto.Location = row.GetValue<string>(nameof(Location));
dto.SubTypeProduct = row.GetValue<string>(nameof(SubTypeProduct));
dto.Owner = row.GetValue<string>(nameof(Owner));
dto.Source = row.GetValue<string>(nameof(Source));
dto.CSDrawingRef = row.GetValue<string>(nameof(CSDrawingRef));
dto.NotForPurchase = BooleanFromString(row.GetValue<string>(nameof(NotForPurchase)));
dto.FreeIssue = BooleanFromString(row.GetValue<string>(nameof(FreeIssue)));
dto.SerialNo = row.GetValue<string>(nameof(SerialNo));
dto.WBSAssembly = row.GetValue<string>(nameof(WBSAssembly));
dto.OMCSID = row.GetValue<string>(nameof(OMCSID));
dto.AssetWBS = row.GetValue<string>(nameof(AssetWBS));
dto.ProjectControlLine = row.GetValue<string>(nameof(ProjectControlLine));
dto.Chainage = !string.IsNullOrEmpty(row[nameof(Chainage)].ToString()) ? Convert.ToDecimal(row.GetValue<string>(nameof(Chainage))) : 0;
dto.Offset = row[nameof(Offset)] != null ? Convert.ToInt32(row.GetValue<string>(nameof(Offset))) : 0;
dto.R_L = row[nameof(R_L)] != null ? Convert.ToInt32(row.GetValue<string>(nameof(R_L))) : 0;
dto.Northings = !string.IsNullOrEmpty(row[nameof(Northings)].ToString()) ? Convert.ToDecimal(row.GetValue<string>(nameof(Northings))) : 0;
dto.Eastings = !string.IsNullOrEmpty(row[nameof(Eastings)].ToString()) ? Convert.ToDecimal(row.GetValue<string>(nameof(Eastings))) : 0;
dto.Latitude = !string.IsNullOrEmpty(row[nameof(Latitude)].ToString()) ? Convert.ToDecimal(row.GetValue<string>(nameof(Latitude))) : 0;
dto.Longtitude = !string.IsNullOrEmpty(row[nameof(Longtitude)].ToString()) ? Convert.ToDecimal(row.GetValue<string>(nameof(Longtitude))) : 0;
dto.Package = row.GetValue<string>(nameof(Package));
dto.ECN = !string.IsNullOrEmpty(row[nameof(ECN)].ToString()) && (row.GetValue<string>(nameof(ECN)) == "1" || row.GetValue<string>(nameof(ECN)).ToLower() == "true");
dto.ECNs = row.GetValue<string>(nameof(Asset));
dto.Errors = row.GetValue<string>(nameof(Errors));
return dto;
}
private static bool BooleanFromString(string value)
{
return !string.IsNullOrEmpty(value) && (value == "1" || value.Equals("true", StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// Updates the specified object.
/// Used for updating the record in DB for generic repository.
/// never update unique key in this method.
/// </summary>
/// <param name="obj">The object.</param>
public void Update(object obj)
{
this.AssetItemImportID = ((AssetItemImport)obj).AssetItemImportID;
this.Asset = ((AssetItemImport)obj).Asset;
this.Prefix = ((AssetItemImport)obj).Prefix;
this.Description = ((AssetItemImport)obj).Description;
this.AssetSubType = ((AssetItemImport)obj).AssetSubType;
this.Location = ((AssetItemImport)obj).Location;
this.SubTypeProduct = ((AssetItemImport)obj).SubTypeProduct;
this.Owner = ((AssetItemImport)obj).Owner;
this.Source = ((AssetItemImport)obj).Source;
this.CSDrawingRef = ((AssetItemImport)obj).CSDrawingRef;
this.NotForPurchase = ((AssetItemImport)obj).NotForPurchase;
this.FreeIssue = ((AssetItemImport)obj).FreeIssue;
this.SerialNo = ((AssetItemImport)obj).SerialNo;
this.WBSAssembly = ((AssetItemImport)obj).WBSAssembly;
this.OMCSID = ((AssetItemImport)obj).OMCSID;
this.AssetWBS = ((AssetItemImport)obj).AssetWBS;
this.ProjectControlLine = ((AssetItemImport)obj).ProjectControlLine;
this.Chainage = ((AssetItemImport)obj).Chainage;
this.Northings = ((AssetItemImport)obj).Northings;
this.Eastings = ((AssetItemImport)obj).Eastings;
this.Latitude = ((AssetItemImport)obj).Latitude;
this.Longtitude = ((AssetItemImport)obj).Longtitude;
this.Package = ((AssetItemImport)obj).Package;
this.ECN = ((AssetItemImport)obj).ECN;
this.ECNs = ((AssetItemImport)obj).ECNs;
this.Status = ((AssetItemImport)obj).Status;
this.CurrentUserID = ((AssetItemImport)obj).CurrentUserID;
}
}
}
DataTable dt; List<AssetItemImport> assetItemImportList = ExportImportServiceHelpers.MapModel(dt, AssetItemImport.ParseFromDataRow);
public static List<T> MapModel<T>(DataTable dt, Func<DataRow, T> generator) {
return dt.GetEnumeratorDataTable(generator).ToList();
}
public static IEnumerable<T> GetEnumeratorDataTable<T>(this DataTable dt, Func<DataRow, T> generator) {
foreach (DataRow row in dt.Rows) {
yield return generator(row);
}
}```