2

I have a hangfire job that is losing data from a LinkedList contained inside the object passed as a parameter.

The user inputs a delimited file which is parsed out into an object storing each line in a LinkedList of another object. I then enque a hangfire job and pass the object in as a parameter. When the job executes, all the data inside the link list is null. The list still contains the correct number of elements, just each one is empty. Any Ideas?

Object definition here.

public class ExternalScanDTO : BaseDTO
{
    [Key]
    public int ScanHeaderID { get; set; }

    public int? ScannerID { get; set; }

    public string DeviceIdentifier { get; set; }

    public int? RFIDInputID { get; set; }

    //this is the list losing data
    [SuppressMessageAttribute("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public LinkedList<ScanLineDTO> ScanLineDTOs { get; set; }

    public DbGeography Location { get; set; }

    public Guid GlobalUID { get; set; }

    public int? UserID { get; set; }

    public int StatusCodeRecordTypeID { get; set; }
    public string StatusCodeRecordTypeName { get; set; }
}

I parse the file and enqueue the job here

 public ActionResult ParseCS4070CSVScanFile([DataSourceRequest] DataSourceRequest kendoRequest, ScanFileImportModel import)
    {
        try
        {
            int count = 0;
            import.ParsingErrors = new List<ParsingError>();
            var parser = new TextFieldParser(import.File.InputStream);
            parser.TextFieldType = FieldType.Delimited;
            parser.Delimiters = new string[] { "," };

            var result = new ExternalScanDTO()
            {
                ScannerID = import.ScannerID,
                StatusCodeRecordTypeID = (int)StatusCodeEnums.ScanHeaderRecordTypes.Barcode,
                ScanLineDTOs = new LinkedList<ScanLineDTO>(),
            };

            // Build parsed list of Scan Lines:
            while (!parser.EndOfData)
            {
                count++;
                var rowValues = parser.ReadFields();

                if (!isValidScanLine(import, rowValues, count))
                    continue;

                var addedLine = new ScanLineDTO
                {
                    StatusCodeID = (int)StatusCodeEnums.ScanLineStatusCodes.Valid,
                    StatusCodeScanTypeID = (int)StatusCodeEnums.ScanLineScanType.StandardOrder,
                    Barcode = rowValues[3],
                    ScanTimeStamp = DateTime.Parse(rowValues[0] + " " + rowValues[1], CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal),
                };
                addedLine.DateCreated = DateTime.UtcNow;
                result.ScanLineDTOs.AddLast(addedLine);
            }

            if (import.ParsingErrors.Count > 0)
                throw new MyException(import.ParsingErrorsToHtml);
            if(result.ScanLineDTOs.Count == 0)
                throw new MyException("The File does not contains any lines");
            // POST LINES TO DATABASE:

            var hfj = new HFJScans();
            BackgroundJob.Enqueue(() => hfj.ProcessScanValidation(result));

            return Content(""); 

        }
        catch (Exception ex) {return AjaxErrorMessage(ex);}
    }

The job executes this method contained inside the HfjScans object created in the previous method, which does some validation checks. By this point the Linked list contains empty elements

   public void ProcessScanValidation(ExternalScanDTO result)
    {
        using (var wfOpr = new WFScanUploadValidate())
        {
            var resultID = wfOpr.Run(result); 
        }
    }
JSON
  • 1,113
  • 10
  • 24
  • Test how Newtonsoft.Json serialization works with LinkedList and ScanLineDTO. http://docs.hangfire.io/en/latest/background-methods/passing-arguments.html – WithMetta Sep 05 '17 at 15:42
  • [LinkedList has known serialization problems.](https://stackoverflow.com/questions/2483268/linkedlist-cannot-be-serialised) – WithMetta Sep 05 '17 at 16:06
  • I think hangfire does the serialization/deserialization automatically. I have tried serializing the object prior passing the parameter to hangfire, then desiralizing at runtime like you have suggested. The serialized json string has empty objects stored in the list also. I think the data is being lost during serialization – JSON Sep 05 '17 at 16:06
  • So what you are saying is I need to use something besides a linked list. I am not sure why the original author used Linked Lists anyways. I see no benefit in our scenario – JSON Sep 05 '17 at 16:12
  • Most likely this will solve your problem. Your other option is to create a new type which is a copy of ExternalScanDTO but that uses List instead of LinkedList. You'll then need to convert ExternalScanDTO objects into this new type before serialization and to modify all the code which uses deserialized ExternalScanDTO objects into this new type. If you wanted to get really clever you could create a derived type of ExternalScanDTO with this new List property which rebuilds the LinkedList as the List is populated or created. – WithMetta Sep 05 '17 at 16:20
  • A bit of google searching shows Lists won't work either. Neither are serializable. I would need to use a serializable object – JSON Sep 05 '17 at 16:49
  • Keep in mind the serialization is done with Newtonsoft.Json. Lists are serializable / deserializable with this library. – WithMetta Sep 05 '17 at 17:00
  • Tried it, returns the same results – JSON Sep 05 '17 at 17:10

0 Answers0