I have a ASP.Net MVC application which returns a page called Customer as home page. But I need show an app not available page when the user tries to access the application on a holiday(holiday list is stored in a table)instead of the Customer page. In the startup I have like below
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Customers}/{action=Index}/{id?}");
});
Now I created a new page called AppNotAvialable.cshmtl and trying to return to this page if today is stored as a holiday in the HolidayWeeks table
public async Task<IActionResult> Index(string sortOrder, string searchString,
int? pageNumber, string currentFilter)
{
var timeUtc = DateTime.UtcNow;
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var todayDt = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
var holidaycheck = (from hc in _context.HolidayWeeks
where hc.HolidateDate.Date == todayDt.Date
select hc).Count();
if (holidaycheck != 0)
{
return View("/Views/Customers/AppNotAvailable.cshtml");
}
else
{
// Show customer page
My concern is everytime the users tried to access the homepage the query is made to the database to check if today is holiday or not. So I wanted to check if there is any better way of checking, should I be storing the data in the session/cache so everytime they access the homepage the query is not made. Can anyone please suggests me how can I do it
CodePudding user response:
Add the MemoryCache
service to the service collection (This service caches the data on the server):
services.AddMemoryCache();
Then can be injected by DI using the interface IMemoryCache
.
//Check if there is a cached holiday vm
if (!memoryCache.TryGetValue("HolidayModelVM", out HolidayModelVM HM))//"HolidayModelVM" is the cache key for the vm
{
//Not present in the cache, we create a new one using the database
HM = new HolidayModelVM
{
//Fetch the actual entity that contains the holiday dates
}
//Cache the VM
_ = memoryCache.Set<HolidayModelVM>("HolidayModelVM", HM, new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(4),//Expiration time, when expired, the database will be used to fetch and cache a new version of the data.
SlidingExpiration = TimeSpan.FromHours(2)
});
}
//Do your holiday check using the HolidayModelVM
if (HM.TodayIsHoliday())
{
return View("/Views/Customers/AppNotAvailable.cshtml");
}
else {
// Show customer page
}
When updating the holiday data clear the VM from the cache in order for the new data to be fetched next time someone visits the page:
memoryCache.Remove("HolidayModelVM");
CodePudding user response:
If your holiday has fixed days, such as Saturdays and Sundays, you can do this. Here is just a demo written without caching, you can refer to it.
Model:
public static class CacheKeys
{
public static string Saturday => "Saturday";
public static string Sunday => "Sunday";
}
Controller:
public async Task<IActionResult> Index(string sortOrder, string searchString,
int? pageNumber, string currentFilter)
{
DayOfWeek wk = DateTime.Today.DayOfWeek;
if (CacheKeys.Saturday == wk.ToString()|| CacheKeys.Sunday == wk.ToString())
{
return View("/Views/Customers/AppNotAvailable.cshtml");
}
else
{
return View("/Views/Customers/WorkDay.cshtml");
}
}
Just judge the current day of the week and combine your fixed holiday time.
Of course you can store the data in the session/cache, you can refer to the documentation to add it.
https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-6.0