2024.2.6 - GetReportBytes(SysRptLst.SysRowID)

Hi everyone,

I’ve encountered a bug after upgrading Kinetics. The production environment is currently on version 2023.2.9, and I’ve installed version 2024.2.6 in another environment.

While running my code—which worked in the previous version—the GetReportBytes function now always returns an empty byte array. I haven’t been able to determine the cause yet.

Here is the code I’m working with (located in Data.SysTask.Standard):

var ttUpdated = ttSysTask.Where(r => 
    r.TaskDescription == "BAQ Report-GN_JobTravCS_2 (GN_JobTravCS)" &&  
    r.TaskStatus == "COMPLETE"
);

foreach (var ttSysTaskRow in ttUpdated)
{
    if (ttSysTaskRow == null || string.IsNullOrEmpty(ttSysTaskRow.Company) || ttSysTaskRow.SysTaskNum == null)
    {
        continue;
    }

    int i = 0;
    while (!Db.SysRptLst.Any(row => row.Company == ttSysTaskRow.Company && row.SysTaskNum == ttSysTaskRow.SysTaskNum))
    {
        System.Threading.Thread.Sleep(50);
        if (i > 25)
        {
            return;
        }
        i++;
    }

    var SysRptLstRow = Db.SysRptLst.FirstOrDefault(row => 
        row.Company == ttSysTaskRow.Company && row.SysTaskNum == ttSysTaskRow.SysTaskNum
    );

    if (SysRptLstRow == null || SysRptLstRow.SysRowID == null)
    {
        continue;
    }

    var Character01Row = Db.SysTaskParam.FirstOrDefault(row => 
        row.SysTaskNum == ttSysTaskRow.SysTaskNum && row.ParamName == "Character01"
    );
    System.Threading.Thread.Sleep(10000);
    var hMonitor = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.ReportMonitorSvcContract>(Db);
    byte[] bytes = hMonitor.GetReportBytes(SysRptLstRow.SysRowID);

    DocumentType documentType = DocumentTypeDeterminer.DetermineType(SysRptLstRow.SSRSRenderFormat);
    string str = FileExtensionDeterminer.DetermineFileExtension(documentType, bytes);

    string str1 = string.Empty;
    if (Character01Row != null && !string.IsNullOrEmpty(Character01Row.ParamCharacter))
    {
        str1 = Character01Row.ParamCharacter;
    }
    else if (!string.IsNullOrEmpty(ttSysTaskRow.TaskNote))
    {
        str1 = serverPath + ttSysTaskRow.TaskNote;
    }
    else
    {
        str1 = serverPath + DateTime.Now.ToString("yyyyMMddhhmm_")+Session.UserID;
    }
    var tempPath = Path.GetDirectoryName(str1);
    if (string.IsNullOrEmpty(tempPath))
    {
        continue;
    }

    if (!Directory.Exists(tempPath))
    {
        Directory.CreateDirectory(tempPath);
    }
    if (bytes == null) throw new BLException("Bytes for PDF is empty.");
    File.WriteAllBytes(str1, bytes);
}

I’m wondering if anyone else has encountered this issue and could share their solution.

Alternatively, if you have a different approach to saving the file generated by SSRS, I’d greatly appreciate your input.

Thank you in advance!

It now checks if it is the same user who owns this row retrieves it from there

5 Likes

Is there a Security Manager exception like previously?

Thanks!

2 Likes

I do, but please tell us exactly how and why you are using this so I can suggest something appropriate.

Also keep in mind, I see you are writing this report to the file system, and all that is changing soon.

2 Likes

We are using this method to perform PDF management tasks with PDFSharp afterward. This includes operations like rotating specific pages within the file and scaling the drawings to perfectly fit the sheet size.

Regarding the file system changes, I am aware of them, but I still hope there will be a way to handle file management programmatically moving forward.

1 Like

No I don’t have any Security Manager Exception

That would be the next step, as the UserID is currently only used for the folder path. I think you’re right—it now seems to be the user from the task agent.

No @Mark_Wonsil was asking about a bypass for security managers.
They have one for territory security now.

1 Like

I added the Security Manager role for the Task Agent User, and it’s now working. However, I don’t believe this is the ideal solution. Do you think the issue could be related to the territory rights?

1 Like

I wouldn’t think so. If I’m understanding @olga correctly, you can only retrieve your own reports now unless you are a security manager.

You can retrieve the bytes yourself using the Db context.

It’s in Db.SysRptLst field → RptData

Still may have some recommendations on the approach you have though.

Let me think on it.

1 Like

Ok, I’ve thought lol.

Pop a data directive on SysRptList and grab the data there and write it.

No more need for waiting until it finishes. The Db write will be your trigger.

The report is now working by accessing it directly through the DB object.
The issue occurred because placing the BPM on this table caused it to trigger multiple times. By waiting for the task to complete, the data should have been generated. However, for reasons I don’t fully understand yet, it wasn’t working as expected in some cases.

1 Like

Which table?

If I recall correctly, the SysRptLst table triggers the update statement multiple times. It’s been over 5 years since I implemented this BPM, so my memory might be a bit fuzzy.

1 Like

Interesting, I will have to experiment.