diff --git a/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs b/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs index be77e9c2de..284da30797 100644 --- a/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs +++ b/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs @@ -7,7 +7,8 @@ using MusicStore.Models; using System.Linq; using MusicStore.Hubs; using MusicStore.ViewModels; -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; +using System; namespace MusicStore.Areas.Admin.Controllers { @@ -66,14 +67,16 @@ namespace MusicStore.Areas.Admin.Controllers string cacheId = string.Format("album_{0}", id); var album = cache.GetOrAdd(cacheId, context => { + //Remove it from cache if not retrieved in last 10 minutes + context.SetSlidingExpiraiton(TimeSpan.FromMinutes(10)); //If this returns null how do we prevent the cache to store this. - return db.Albums.Single(a => a.AlbumId == id); + return db.Albums.Where(a => a.AlbumId == id).FirstOrDefault(); }); if (album == null) { cache.Remove(cacheId); - return HttpNotFound(); + return View(album); } // TODO [EF] We don't query related data as yet. We have to populate this until we do automatically. @@ -101,6 +104,7 @@ namespace MusicStore.Areas.Admin.Controllers db.Albums.Add(album); db.SaveChanges(); annoucementHub.Clients.All.announcement(new AlbumData() { Title = album.Title, Url = Url.Action("Details", "Store", new { id = album.AlbumId }) }); + cache.Remove("latestAlbum"); return RedirectToAction("Index"); } @@ -113,11 +117,11 @@ namespace MusicStore.Areas.Admin.Controllers // GET: /StoreManager/Edit/5 public IActionResult Edit(int id) { - Album album = db.Albums.Single(a => a.AlbumId == id); + Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault(); if (album == null) { - return HttpNotFound(); + return View(album); } ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId); @@ -149,11 +153,7 @@ namespace MusicStore.Areas.Admin.Controllers // GET: /StoreManager/RemoveAlbum/5 public IActionResult RemoveAlbum(int id) { - Album album = db.Albums.Single(a => a.AlbumId == id); - if (album == null) - { - return HttpNotFound(); - } + Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault(); return View(album); } @@ -162,11 +162,16 @@ namespace MusicStore.Areas.Admin.Controllers [HttpPost, ActionName("RemoveAlbum")] public IActionResult RemoveAlbumConfirmed(int id) { - Album album = db.Albums.Single(a => a.AlbumId == id); - db.Albums.Remove(album); - db.SaveChanges(); - //Remove the cache entry as it is removed - cache.Remove(string.Format("album_{0}", id)); + Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault(); + + if (album != null) + { + db.Albums.Remove(album); + db.SaveChanges(); + //Remove the cache entry as it is removed + cache.Remove(string.Format("album_{0}", id)); + } + return RedirectToAction("Index"); } diff --git a/src/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml b/src/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml index 3e65c71cc6..bd342e5327 100644 --- a/src/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml +++ b/src/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml @@ -4,54 +4,61 @@ ViewBag.Title = "Details"; } -

Details

+@if (Model != null) +{ +

Details

-
-

Album

-
-
-
- @Html.DisplayNameFor(model => model.Artist.Name) -
+
+

Album

+
+
+
+ @Html.DisplayNameFor(model => model.Artist.Name) +
-
- @Html.DisplayFor(model => model.Artist.Name) -
+
+ @Html.DisplayFor(model => model.Artist.Name) +
-
- @Html.DisplayNameFor(model => model.Genre.Name) -
+
+ @Html.DisplayNameFor(model => model.Genre.Name) +
-
- @Html.DisplayFor(model => model.Genre.Name) -
+
+ @Html.DisplayFor(model => model.Genre.Name) +
-
- @Html.DisplayNameFor(model => model.Title) -
+
+ @Html.DisplayNameFor(model => model.Title) +
-
- @Html.DisplayFor(model => model.Title) -
+
+ @Html.DisplayFor(model => model.Title) +
-
- @Html.DisplayNameFor(model => model.Price) -
+
+ @Html.DisplayNameFor(model => model.Price) +
-
- @Html.DisplayFor(model => model.Price) -
+
+ @Html.DisplayFor(model => model.Price) +
-
- @Html.DisplayNameFor(model => model.AlbumArtUrl) -
+
+ @Html.DisplayNameFor(model => model.AlbumArtUrl) +
-
- @Html.DisplayFor(model => model.AlbumArtUrl) -
+
+ @Html.DisplayFor(model => model.AlbumArtUrl) +
-
-
+
+
+} +else +{ + @Html.Label(null, "Unable to locate the album") +}

@Html.ActionLink("Edit", "Edit", new { id = Model.AlbumId }) | @Html.ActionLink("Back to List", "Index") diff --git a/src/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml b/src/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml index 3e9def0bfb..63d6b61430 100644 --- a/src/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml +++ b/src/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml @@ -6,62 +6,69 @@

Edit

-@using (Html.BeginForm()) +@if (Model != null) { - @Html.AntiForgeryToken() + @using (Html.BeginForm()) + { + @Html.AntiForgeryToken() -
-

Album

-
- @Html.ValidationSummary(true) - @Html.HiddenFor(model => model.AlbumId) +
+

Album

+
+ @Html.ValidationSummary(true) + @Html.HiddenFor(model => model.AlbumId) -
- @Html.LabelFor(model => model.GenreId, "GenreId", new { @class = "control-label col-md-2" }) -
- @Html.DropDownList("GenreId", String.Empty) - @Html.ValidationMessageFor(model => model.GenreId) +
+ @Html.LabelFor(model => model.GenreId, "GenreId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("GenreId", String.Empty) + @Html.ValidationMessageFor(model => model.GenreId) +
+
+ +
+ @Html.LabelFor(model => model.ArtistId, "ArtistId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("ArtistId", String.Empty) + @Html.ValidationMessageFor(model => model.ArtistId) +
+
+ +
+ @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Title) + @Html.ValidationMessageFor(model => model.Title) +
+
+ +
+ @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Price) + @Html.ValidationMessageFor(model => model.Price) +
+
+ +
+ @Html.LabelFor(model => model.AlbumArtUrl, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.AlbumArtUrl) + @Html.ValidationMessageFor(model => model.AlbumArtUrl) +
+
+ +
+
+ +
- -
- @Html.LabelFor(model => model.ArtistId, "ArtistId", new { @class = "control-label col-md-2" }) -
- @Html.DropDownList("ArtistId", String.Empty) - @Html.ValidationMessageFor(model => model.ArtistId) -
-
- -
- @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) -
- @Html.EditorFor(model => model.Title) - @Html.ValidationMessageFor(model => model.Title) -
-
- -
- @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" }) -
- @Html.EditorFor(model => model.Price) - @Html.ValidationMessageFor(model => model.Price) -
-
- -
- @Html.LabelFor(model => model.AlbumArtUrl, new { @class = "control-label col-md-2" }) -
- @Html.EditorFor(model => model.AlbumArtUrl) - @Html.ValidationMessageFor(model => model.AlbumArtUrl) -
-
- -
-
- -
-
-
+ } +} +else +{ + @Html.Label(null, "Unable to locate the album") }
diff --git a/src/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml b/src/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml index 0e0b4bcccf..49cdeaa13c 100644 --- a/src/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml +++ b/src/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml @@ -4,20 +4,26 @@ ViewBag.Title = "Delete"; } -

Delete Confirmation

- -

- Are you sure you want to delete the album titled - @Model.Title? -

- -@using (Html.BeginForm()) +@if (Model != null) { +

Delete Confirmation

+

- -

-

- @Html.ActionLink("Back to List", "Index") + Are you sure you want to delete the album titled + @Model.Title?

+ @using (Html.BeginForm()) + { +

+ +

+

+ @Html.ActionLink("Back to List", "Index") +

+ } +} +else +{ + @Html.Label(null, "Unable to locate the album") } \ No newline at end of file diff --git a/src/MusicStore/Components/AnnouncementComponent.cs b/src/MusicStore/Components/AnnouncementComponent.cs index 17bef7f3c9..17ce94f357 100644 --- a/src/MusicStore/Components/AnnouncementComponent.cs +++ b/src/MusicStore/Components/AnnouncementComponent.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.Mvc; using MusicStore.Models; -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; namespace MusicStore.Components { @@ -23,6 +23,7 @@ namespace MusicStore.Components { var latestAlbum = await cache.GetOrAdd("latestAlbum", async context => { + context.SetAbsoluteExpiration(TimeSpan.FromMinutes(10)); return await GetLatestAlbum(); }); diff --git a/src/MusicStore/Controllers/HomeController.cs b/src/MusicStore/Controllers/HomeController.cs index 0740ef5793..e66e9a7add 100644 --- a/src/MusicStore/Controllers/HomeController.cs +++ b/src/MusicStore/Controllers/HomeController.cs @@ -1,6 +1,7 @@ -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; using Microsoft.AspNet.Mvc; using MusicStore.Models; +using System; using System.Collections.Generic; using System.Linq; @@ -22,7 +23,13 @@ namespace MusicStore.Controllers public IActionResult Index() { // Get most popular albums - var albums = cache.GetOrAdd("topselling", (context => GetTopSellingAlbums(6))); + var albums = cache.GetOrAdd("topselling", context => + { + //Refresh it every 10 minutes. Let this be the last item to be removed by cache if cache GC kicks in. + context.SetAbsoluteExpiration(TimeSpan.FromMinutes(10)); + context.SetPriority(CachePreservationPriority.High); + return GetTopSellingAlbums(6); + }); return View(albums); } diff --git a/src/MusicStore/Controllers/StoreController.cs b/src/MusicStore/Controllers/StoreController.cs index db7fc0c108..282c0fd4c6 100644 --- a/src/MusicStore/Controllers/StoreController.cs +++ b/src/MusicStore/Controllers/StoreController.cs @@ -1,6 +1,7 @@ -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; using Microsoft.AspNet.Mvc; using MusicStore.Models; +using System; using System.Linq; namespace MusicStore.Controllers @@ -44,6 +45,9 @@ namespace MusicStore.Controllers { var album = cache.GetOrAdd(string.Format("album_{0}", id), context => { + //Remove it from cache if not retrieved in last 10 minutes + context.SetSlidingExpiraiton(TimeSpan.FromMinutes(10)); + var albumData = db.Albums.Single(a => a.AlbumId == id); // TODO [EF] We don't query related data as yet. We have to populate this until we do automatically. diff --git a/src/MusicStore/Mocks/StartupSocialTesting.cs b/src/MusicStore/Mocks/StartupSocialTesting.cs index 20974508ad..01763a0d18 100644 --- a/src/MusicStore/Mocks/StartupSocialTesting.cs +++ b/src/MusicStore/Mocks/StartupSocialTesting.cs @@ -14,7 +14,7 @@ using Microsoft.AspNet.Security.Google; using Microsoft.AspNet.Security.Twitter; using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.Security; -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; using MusicStore.Mocks.Common; using MusicStore.Mocks.Facebook; using MusicStore.Mocks.Twitter; diff --git a/src/MusicStore/Startup.cs b/src/MusicStore/Startup.cs index e12ca0b5ca..27c688b0dc 100644 --- a/src/MusicStore/Startup.cs +++ b/src/MusicStore/Startup.cs @@ -14,7 +14,7 @@ using Microsoft.AspNet.Security.Google; using Microsoft.AspNet.Security.Twitter; using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.Security; -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; namespace MusicStore { diff --git a/src/MusicStore/StartupNtlmAuthentication.cs b/src/MusicStore/StartupNtlmAuthentication.cs index cc44a7ef2d..5fa10aaa86 100644 --- a/src/MusicStore/StartupNtlmAuthentication.cs +++ b/src/MusicStore/StartupNtlmAuthentication.cs @@ -10,22 +10,22 @@ using Microsoft.Net.Http.Server; using Microsoft.AspNet.Server.WebListener; using System.Security.Claims; using System.Security.Principal; -using Microsoft.AspNet.MemoryCache; +using Microsoft.Framework.Cache.Memory; namespace MusicStore { /// /// To make runtime to load an environment based startup class, specify the environment by the following ways: /// 1. Drop a Microsoft.AspNet.Hosting.ini file in the application folder - /// 2. Add a setting in the ini file named 'env' with value of the format 'Startup[EnvironmentName]'. For example: To load a Startup class named - /// 'StartupNtlmAuthentication' the value of the env should be 'NtlmAuthentication' (eg. env=NtlmAuthentication). Runtime adds a 'Startup' prefix to this and loads 'StartupNtlmAuthentication'. + /// 2. Add a setting in the ini file named 'KRE_ENV' with value of the format 'Startup[EnvironmentName]'. For example: To load a Startup class named + /// 'StartupNtlmAuthentication' the value of the env should be 'NtlmAuthentication' (eg. KRE_ENV=NtlmAuthentication). Runtime adds a 'Startup' prefix to this and loads 'StartupNtlmAuthentication'. /// If no environment name is specified the default startup class loaded is 'Startup'. /// https://github.com/aspnet/Helios/issues/53 - Environment based startup class loading is not available on Helios. /// Alternative ways to specify environment are: - /// 1. Set the environment variable named SET env=NtlmAuthentication + /// 1. Set the environment variable named SET KRE_ENV=NtlmAuthentication /// 2. For selfhost based servers pass in a command line variable named --env with this value. Eg: /// "commands": { - /// "WebListener": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002 --env NtlmAuthentication", + /// "WebListener": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002 --KRE_ENV NtlmAuthentication", /// }, /// public class StartupNtlmAuthentication @@ -47,6 +47,7 @@ namespace MusicStore var identity = (ClaimsIdentity)context.User.Identity; #if ASPNET50 + //no WindowsIdentity yet on CoreCLR if (identity.GetUserName() == Environment.UserDomainName + "\\" + Environment.UserName) { identity.AddClaim(new Claim("ManageStore", "Allowed")); diff --git a/src/MusicStore/Views/Shared/_LoginPartial.cshtml b/src/MusicStore/Views/Shared/_LoginPartial.cshtml index a00b4df312..fbf9acb6dc 100644 --- a/src/MusicStore/Views/Shared/_LoginPartial.cshtml +++ b/src/MusicStore/Views/Shared/_LoginPartial.cshtml @@ -22,7 +22,7 @@ //This code block necessary only for NTLM authentication } diff --git a/src/MusicStore/project.json b/src/MusicStore/project.json index fcea7dc457..8a1d5c566c 100644 --- a/src/MusicStore/project.json +++ b/src/MusicStore/project.json @@ -25,7 +25,7 @@ "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", "Microsoft.AspNet.SignalR.Server": "3.0.0-*", - "Microsoft.AspNet.MemoryCache": "1.0.0-*" + "Microsoft.Framework.Cache.Memory": "1.0.0-*" }, "commands": { "WebListener": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5002",