Activities of "IanW"

Hello Baslessi75,

You cannot use any functions which use the localtime of the machine, because when deploying to the cloud this could be different. I have personally witnessed this issue with my own projects too.

In general the guideline is that you manage everything in UTC until it is displayed to the user. This means using Javascript to detect the users timezone in the browser https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset

There is a Blazor library that can also take care of this for you. https://github.com/dustout/BlazorTime

Answer

Could you show your code please?

For better performance I can answer.

There is a concept of access patterns and it is especially important for any kind of lists of data you are displaying. Lists of data, for the large use case, should have the data itself clustered together on the database disk. This means having the clustered index (usually the primary key, but it can be changed) of one that is (TenantId, Id) which will force all data to be togethered on disk.

However, the other issue will be joins. If any of the data you are retrieving in the list requires data from other tables, it will be retrieving the data for each item in the list in the other tables one by one. So Ideally all of the data in the other tables that may be joined, is also physically close together - which means clustered on something related to the top level entity you are trying to list. TenantId may be enough is most cases, but if it is not an aggregate root, then perhaps something based on the FK to the top level entitiy.

I recommend you instead do this in a normal API controller instead of an App service as you want to return a file rather than some wrapped ajax/json response - which is what the dynamic API part of ABP will do with the AppServices.

Here is an example returning and ICS file.

[HttpGet]
[AllowAnonymous]
public FileResult ICS(Guid id)
{
    var appointment = _attendanceRepo.GetAllIncluding(c => c.CalendarEvent, d => d.CalendarEvent.OwnerCalendar.Owner).First(d => d.Id == id);

    string output = $"BEGIN:VCALENDAR" + rt +
        $"VERSION:2.0" + rt +
        $"BEGIN:VEVENT" + rt +
        $"UID: calendr-" + appointment.Id + rt +
        $"DTSTART:" + string.Format("{0:yyyyMMddTHHmmssZ}", appointment.CalendarEvent.Start) + rt +
        $"DTEND:" + string.Format("{0:yyyyMMddTHHmmssZ}", appointment.CalendarEvent.End) + rt +
        $"SUMMARY:" + appointment.CalendarEvent.EventName + " with " + appointment.CalendarEvent.OwnerCalendar.Owner.FullName + rt +
        $"LOCATION:" + appointment.CalendarEvent.Location + rt +
        $"END:VEVENT" + rt +
        $"END:VCALENDAR" + rt
        ;


    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(output ?? ""));
    result.Content = new StreamContent(stream);
    return File(stream, "text/ics", fileDownloadName: appointment.CalendarEvent.EventName + ".ics");

}

@sraman, I think what you mean is to customize the "features" availablef or a tenant and then have only the features that are enabled to be displayed on the menu. Is this correct?

Showing 21 to 25 of 25 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on December 15, 2025, 06:08
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.