Clean up - removing work arounds for bugs

1. Removed worked arounds that were previously applied for bugs as they are fixed now.
2. Sorted all using statements. Moved System.* to the top.
3. Fixed some of the code to follow engineering guidelines.
This commit is contained in:
Praburaj 2014-12-15 11:47:04 -08:00
parent c8323f4ef3
commit 50b756a776
31 changed files with 258 additions and 308 deletions

View File

@ -1,15 +1,15 @@
using Microsoft.AspNet.Mvc;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.Data.Entity;
using MusicStore.Models;
using System.Linq;
using MusicStore.Hubs;
using MusicStore.ViewModels;
using Microsoft.Framework.Cache.Memory;
using System;
using System.Threading.Tasks;
using MusicStore.Hubs;
using MusicStore.Models;
using MusicStore.ViewModels;
namespace MusicStore.Areas.Admin.Controllers
{
@ -17,45 +17,29 @@ namespace MusicStore.Areas.Admin.Controllers
[Microsoft.AspNet.Mvc.Authorize("ManageStore", "Allowed")]
public class StoreManagerController : Controller
{
private readonly MusicStoreContext db;
private IHubContext annoucementHub;
private readonly IMemoryCache cache;
private readonly MusicStoreContext _dbContext;
private readonly IMemoryCache _cache;
private IHubContext _announcementHub;
public StoreManagerController(MusicStoreContext context, IConnectionManager connectionManager, IMemoryCache memoryCache)
public StoreManagerController(
MusicStoreContext dbContext,
IConnectionManager connectionManager,
IMemoryCache memoryCache)
{
db = context;
annoucementHub = connectionManager.GetHubContext<AnnouncementHub>();
cache = memoryCache;
_dbContext = dbContext;
_announcementHub = connectionManager.GetHubContext<AnnouncementHub>();
_cache = memoryCache;
}
//
// GET: /StoreManager/
public IActionResult Index()
public async Task<IActionResult> Index()
{
// TODO [EF] Swap to native support for loading related data when available
var albums = from album in db.Albums
join genre in db.Genres on album.GenreId equals genre.GenreId
join artist in db.Artists on album.ArtistId equals artist.ArtistId
select new Album()
{
ArtistId = album.ArtistId,
AlbumArtUrl = album.AlbumArtUrl,
AlbumId = album.AlbumId,
GenreId = album.GenreId,
Price = album.Price,
Title = album.Title,
Artist = new Artist()
{
ArtistId = album.ArtistId,
Name = artist.Name
},
Genre = new Genre()
{
GenreId = album.GenreId,
Name = genre.Name
}
};
var albums = await _dbContext.Albums
.Include(a => a.Genre)
.Include(a => a.Artist)
.ToListAsync();
return View(albums);
}
@ -63,26 +47,29 @@ namespace MusicStore.Areas.Admin.Controllers
//
// GET: /StoreManager/Details/5
public IActionResult Details(int id)
public async Task<IActionResult> Details(int id)
{
string cacheId = string.Format("album_{0}", id);
var album = cache.GetOrSet(cacheId, context =>
var cacheKey = GetCacheKey(id);
var album = await _cache.GetOrSet(GetCacheKey(id), async context =>
{
//Remove it from cache if not retrieved in last 10 minutes
//Remove it from cache if not retrieved in last 10 minutes.
context.SetSlidingExpiration(TimeSpan.FromMinutes(10));
//If this returns null how do we prevent the cache to store this.
return db.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
//If this returns null how do we prevent the cache to store this.
return await _dbContext.Albums
.Where(a => a.AlbumId == id)
.Include(a => a.Artist)
.Include(a => a.Genre)
.FirstOrDefaultAsync();
});
if (album == null)
{
cache.Remove(cacheId);
_cache.Remove(cacheKey);
return View(album);
}
// TODO [EF] We don't query related data as yet. We have to populate this until we do automatically.
album.Genre = db.Genres.Single(g => g.GenreId == album.GenreId);
album.Artist = db.Artists.Single(a => a.ArtistId == album.ArtistId);
return View(album);
}
@ -90,8 +77,8 @@ namespace MusicStore.Areas.Admin.Controllers
// GET: /StoreManager/Create
public IActionResult Create()
{
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name");
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name");
ViewBag.GenreId = new SelectList(_dbContext.Genres, "GenreId", "Name");
ViewBag.ArtistId = new SelectList(_dbContext.Artists, "ArtistId", "Name");
return View();
}
@ -102,31 +89,40 @@ namespace MusicStore.Areas.Admin.Controllers
{
if (ModelState.IsValid)
{
await db.Albums.AddAsync(album, Context.RequestAborted);
await db.SaveChangesAsync(Context.RequestAborted);
annoucementHub.Clients.All.announcement(new AlbumData() { Title = album.Title, Url = Url.Action("Details", "Store", new { id = album.AlbumId }) });
cache.Remove("latestAlbum");
await _dbContext.Albums.AddAsync(album, Context.RequestAborted);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
var albumData = new AlbumData
{
Title = album.Title,
Url = Url.Action("Details", "Store", new { id = album.AlbumId })
};
_announcementHub.Clients.All.announcement(albumData);
_cache.Remove("latestAlbum");
return RedirectToAction("Index");
}
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
ViewBag.GenreId = new SelectList(_dbContext.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(_dbContext.Artists, "ArtistId", "Name", album.ArtistId);
return View(album);
}
//
// GET: /StoreManager/Edit/5
public IActionResult Edit(int id)
public async Task<IActionResult> Edit(int id)
{
Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
var album = await _dbContext.Albums.
Where(a => a.AlbumId == id).
FirstOrDefaultAsync();
if (album == null)
{
return View(album);
}
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
ViewBag.GenreId = new SelectList(_dbContext.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(_dbContext.Artists, "ArtistId", "Name", album.ArtistId);
return View(album);
}
@ -138,15 +134,15 @@ namespace MusicStore.Areas.Admin.Controllers
{
if (ModelState.IsValid)
{
db.Entry(album).SetState(EntityState.Modified);
await db.SaveChangesAsync(Context.RequestAborted);
_dbContext.Entry(album).SetState(EntityState.Modified);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
//Invalidate the cache entry as it is modified
cache.Remove(string.Format("album_{0}", album.AlbumId));
_cache.Remove(GetCacheKey(album.AlbumId));
return RedirectToAction("Index");
}
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
ViewBag.GenreId = new SelectList(_dbContext.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(_dbContext.Artists, "ArtistId", "Name", album.ArtistId);
return View(album);
}
@ -154,7 +150,7 @@ namespace MusicStore.Areas.Admin.Controllers
// GET: /StoreManager/RemoveAlbum/5
public IActionResult RemoveAlbum(int id)
{
Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
var album = _dbContext.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
return View(album);
}
@ -163,19 +159,24 @@ namespace MusicStore.Areas.Admin.Controllers
[HttpPost, ActionName("RemoveAlbum")]
public async Task<IActionResult> RemoveAlbumConfirmed(int id)
{
Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
var album = _dbContext.Albums.Where(a => a.AlbumId == id).FirstOrDefault();
if (album != null)
{
db.Albums.Remove(album);
await db.SaveChangesAsync(Context.RequestAborted);
_dbContext.Albums.Remove(album);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
//Remove the cache entry as it is removed
cache.Remove(string.Format("album_{0}", id));
_cache.Remove(GetCacheKey(id));
}
return RedirectToAction("Index");
}
private static string GetCacheKey(int id)
{
return string.Format("album_{0}", id);
}
#if TESTING
//
// GET: /StoreManager/GetAlbumIdFromName
@ -183,7 +184,7 @@ namespace MusicStore.Areas.Admin.Controllers
[HttpGet]
public IActionResult GetAlbumIdFromName(string albumName)
{
var album = db.Albums.Where(a => a.Title == albumName).FirstOrDefault();
var album = _dbContext.Albums.Where(a => a.Title == albumName).FirstOrDefault();
if (album == null)
{

View File

@ -2,26 +2,26 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using Microsoft.Framework.Cache.Memory;
using MusicStore.Models;
namespace MusicStore.Components
{
[ViewComponent(Name = "Announcement")]
public class AnnouncementComponent : ViewComponent
{
private readonly MusicStoreContext db;
private readonly IMemoryCache cache;
private readonly MusicStoreContext _dbContext;
private readonly IMemoryCache _cache;
public AnnouncementComponent(MusicStoreContext context, IMemoryCache memoryCache)
public AnnouncementComponent(MusicStoreContext dbContext, IMemoryCache memoryCache)
{
db = context;
cache = memoryCache;
_dbContext = dbContext;
_cache = memoryCache;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var latestAlbum = await cache.GetOrSet("latestAlbum", async context =>
var latestAlbum = await _cache.GetOrSet("latestAlbum", async context =>
{
context.SetAbsoluteExpiration(TimeSpan.FromMinutes(10));
return await GetLatestAlbum();
@ -32,15 +32,12 @@ namespace MusicStore.Components
private Task<Album> GetLatestAlbum()
{
var latestAlbum = db.Albums.OrderByDescending(a => a.Created).FirstOrDefault();
if ((latestAlbum.Created - DateTime.UtcNow).TotalDays <= 2)
{
return Task.FromResult(latestAlbum);
}
else
{
return Task.FromResult<Album>(null);
}
var latestAlbum = _dbContext.Albums
.OrderByDescending(a => a.Created)
.Where(a => (a.Created - DateTime.UtcNow).TotalDays <= 2)
.FirstOrDefaultAsync();
return latestAlbum;
}
}
}

View File

@ -1,18 +1,18 @@
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
namespace MusicStore.Components
{
[ViewComponent(Name = "CartSummary")]
public class CartSummaryComponent : ViewComponent
{
private readonly MusicStoreContext db;
private readonly MusicStoreContext _dbContext;
public CartSummaryComponent(MusicStoreContext context)
public CartSummaryComponent(MusicStoreContext dbContext)
{
db = context;
_dbContext = dbContext;
}
public async Task<IViewComponentResult> InvokeAsync()
@ -25,15 +25,13 @@ namespace MusicStore.Components
return View();
}
private Task<IOrderedEnumerable<string>> GetCartItems()
private async Task<IOrderedEnumerable<string>> GetCartItems()
{
var cart = ShoppingCart.GetCart(db, Context);
var cart = ShoppingCart.GetCart(_dbContext, Context);
var cartItems = cart.GetCartItems()
return (await cart.GetCartItems())
.Select(a => a.Album.Title)
.OrderBy(x => x);
return Task.FromResult(cartItems);
}
}
}

View File

@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System.Collections.Generic;
namespace MusicStore.Components
{
[ViewComponent(Name = "GenreMenu")]
public class GenreMenuComponent : ViewComponent
{
private readonly MusicStoreContext db;
private readonly MusicStoreContext _dbContext;
public GenreMenuComponent(MusicStoreContext context)
public GenreMenuComponent(MusicStoreContext dbContext)
{
db = context;
_dbContext = dbContext;
}
public async Task<IViewComponentResult> InvokeAsync()
@ -24,10 +23,10 @@ namespace MusicStore.Components
return View(genres);
}
private Task<List<Genre>> GetGenres()
private async Task<List<Genre>> GetGenres()
{
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
//var genres = db.Genres
//var genres = _dbContext.Genres
//.OrderByDescending(
// g => g.Albums.Sum(
// a => a.OrderDetails.Sum(
@ -35,8 +34,7 @@ namespace MusicStore.Components
//.Take(9)
//.ToList();
var genres = db.Genres.ToList();
return Task.FromResult(genres);
return await _dbContext.Genres.Take(9).ToListAsync();
}
}
}

View File

@ -1,11 +1,11 @@
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using MusicStore.Models;
using System.Security.Claims;
namespace MusicStore.Controllers
{
@ -338,8 +338,7 @@ namespace MusicStore.Controllers
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl = null)
{
//https://github.com/aspnet/Identity/issues/216
var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(cancellationToken: Context.RequestAborted);
if (loginInfo == null)
{
return RedirectToAction("Login");
@ -381,8 +380,7 @@ namespace MusicStore.Controllers
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
//https://github.com/aspnet/Identity/issues/216
var info = await SignInManager.GetExternalLoginInfoAsync();
var info = await SignInManager.GetExternalLoginInfoAsync(cancellationToken: Context.RequestAborted);
if (info == null)
{
return View("ExternalLoginFailure");

View File

@ -1,24 +1,23 @@
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System;
using System;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
namespace MusicStore.Controllers
{
[Authorize]
public class CheckoutController : Controller
{
private readonly MusicStoreContext db;
public CheckoutController(MusicStoreContext context)
private const string PromoCode = "FREE";
private readonly MusicStoreContext _dbContext;
public CheckoutController(MusicStoreContext dbContext)
{
db = context;
_dbContext = dbContext;
}
const string PromoCode = "FREE";
//
// GET: /Checkout/
@ -49,14 +48,14 @@ namespace MusicStore.Controllers
order.OrderDate = DateTime.Now;
//Add the Order
await db.Orders.AddAsync(order, Context.RequestAborted);
await _dbContext.Orders.AddAsync(order, Context.RequestAborted);
//Process the order
var cart = ShoppingCart.GetCart(db, Context);
cart.CreateOrder(order);
var cart = ShoppingCart.GetCart(_dbContext, Context);
await cart.CreateOrder(order);
// Save all changes
await db.SaveChangesAsync(Context.RequestAborted);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
return RedirectToAction("Complete",
new { id = order.OrderId });
@ -75,7 +74,7 @@ namespace MusicStore.Controllers
public IActionResult Complete(int id)
{
// Validate customer owns this order
bool isValid = db.Orders.Any(
bool isValid = _dbContext.Orders.Any(
o => o.OrderId == id &&
o.Username == Context.User.Identity.GetUserName());

View File

@ -1,34 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Framework.Cache.Memory;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.Cache.Memory;
using MusicStore.Models;
namespace MusicStore.Controllers
{
public class HomeController : Controller
{
private readonly MusicStoreContext db;
private readonly IMemoryCache cache;
private readonly MusicStoreContext _dbContext;
private readonly IMemoryCache _cache;
public HomeController(MusicStoreContext context, IMemoryCache memoryCache)
public HomeController(MusicStoreContext dbContext, IMemoryCache memoryCache)
{
db = context;
cache = memoryCache;
_dbContext = dbContext;
_cache = memoryCache;
}
//
// GET: /Home/
public IActionResult Index()
public async Task<IActionResult> Index()
{
// Get most popular albums
var albums = cache.GetOrSet("topselling", context =>
var albums = await _cache.GetOrSet("topselling", async 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 await GetTopSellingAlbums(6);
});
return View(albums);
@ -41,16 +42,16 @@ namespace MusicStore.Controllers
return View("~/Views/Shared/Error.cshtml");
}
private List<Album> GetTopSellingAlbums(int count)
private async Task<List<Album>> GetTopSellingAlbums(int count)
{
// Group the order details by album and return
// the albums with the highest count
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
return db.Albums
return await _dbContext.Albums
.OrderByDescending(a => a.OrderDetails.Count())
.Take(count)
.ToList();
.ToListAsync();
}
}
}

View File

@ -1,10 +1,9 @@
using System.Threading.Tasks;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System.Linq;
using Microsoft.AspNet.Http;
namespace MusicStore.Controllers
{
@ -89,8 +88,7 @@ namespace MusicStore.Controllers
}
var user = await GetCurrentUserAsync();
// Generate the token and send it
//https://github.com/aspnet/Identity/issues/217
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(user, model.Number);
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(user, model.Number, cancellationToken: Context.RequestAborted);
var message = new IdentityMessage
{
Destination = model.Number,
@ -139,8 +137,7 @@ namespace MusicStore.Controllers
// This code allows you exercise the flow without actually sending codes
// For production use please register a SMS provider in IdentityConfig and generate a code here.
#if DEMO
//https://github.com/aspnet/Identity/issues/217
ViewBag.Code = await UserManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
ViewBag.Code = await UserManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber, cancellationToken: Context.RequestAborted);
#endif
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
}
@ -318,16 +315,17 @@ namespace MusicStore.Controllers
public async Task<ActionResult> LinkLoginCallback()
{
var user = await GetCurrentUserAsync();
if(user == null)
if (user == null)
{
return View("Error");
}
//https://github.com/aspnet/Identity/issues/216
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(User.Identity.GetUserId());
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(User.Identity.GetUserId(), cancellationToken: Context.RequestAborted);
if (loginInfo == null)
{
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
var result = await UserManager.AddLoginAsync(user, loginInfo);
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
return RedirectToAction("ManageLogins", new { Message = message });
@ -343,17 +341,6 @@ namespace MusicStore.Controllers
}
}
//TODO: No caller - do we need this?
private async Task<bool> HasPhoneNumber()
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId(), cancellationToken: Context.RequestAborted);
if (user != null)
{
return user.PhoneNumber != null;
}
return false;
}
public enum ManageMessageId
{
AddPhoneSuccess,
@ -370,18 +357,7 @@ namespace MusicStore.Controllers
{
return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId(), cancellationToken: Context.RequestAborted);
}
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
#endregion
}
}

View File

@ -1,33 +1,33 @@
using Microsoft.AspNet.Mvc;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.DependencyInjection;
using MusicStore.Models;
using MusicStore.ViewModels;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection;
namespace MusicStore.Controllers
{
public class ShoppingCartController : Controller
{
private readonly MusicStoreContext db;
private readonly MusicStoreContext _dbContext;
public ShoppingCartController(MusicStoreContext context)
public ShoppingCartController(MusicStoreContext dbContext)
{
db = context;
_dbContext = dbContext;
}
//
// GET: /ShoppingCart/
public IActionResult Index()
public async Task<IActionResult> Index()
{
var cart = ShoppingCart.GetCart(db, Context);
var cart = ShoppingCart.GetCart(_dbContext, Context);
// Set up our ViewModel
var viewModel = new ShoppingCartViewModel
{
CartItems = cart.GetCartItems(),
CartTotal = cart.GetTotal()
CartItems = await cart.GetCartItems(),
CartTotal = await cart.GetTotal()
};
// Return the view
@ -40,15 +40,15 @@ namespace MusicStore.Controllers
public async Task<IActionResult> AddToCart(int id)
{
// Retrieve the album from the database
var addedAlbum = db.Albums
var addedAlbum = _dbContext.Albums
.Single(album => album.AlbumId == id);
// Add it to the shopping cart
var cart = ShoppingCart.GetCart(db, Context);
var cart = ShoppingCart.GetCart(_dbContext, Context);
cart.AddToCart(addedAlbum);
await db.SaveChangesAsync(Context.RequestAborted);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
// Go back to the main store page for more shopping
return RedirectToAction("Index");
@ -79,17 +79,18 @@ namespace MusicStore.Controllers
antiForgery.Validate(Context, new AntiForgeryTokenSet(formToken, cookieToken));
// Retrieve the current user's shopping cart
var cart = ShoppingCart.GetCart(db, Context);
var cart = ShoppingCart.GetCart(_dbContext, Context);
// Get the name of the album to display confirmation
// TODO [EF] Turn into one query once query of related data is enabled
int albumId = db.CartItems.Single(item => item.CartItemId == id).AlbumId;
string albumName = db.Albums.Single(a => a.AlbumId == albumId).Title;
var cartItem = await _dbContext.CartItems
.Where(item => item.CartItemId == id)
.Include(c => c.Album)
.SingleOrDefaultAsync();
// Remove from cart
int itemCount = cart.RemoveFromCart(id);
await db.SaveChangesAsync(Context.RequestAborted);
await _dbContext.SaveChangesAsync(Context.RequestAborted);
string removed = (itemCount > 0) ? " 1 copy of " : string.Empty;
@ -97,10 +98,10 @@ namespace MusicStore.Controllers
var results = new ShoppingCartRemoveViewModel
{
Message = removed + albumName +
Message = removed + cartItem.Album.Title +
" has been removed from your shopping cart.",
CartTotal = cart.GetTotal(),
CartCount = cart.GetCount(),
CartTotal = await cart.GetTotal(),
CartCount = await cart.GetCount(),
ItemCount = itemCount,
DeleteId = id
};

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.Cache.Memory;
using MusicStore.Models;
@ -8,21 +9,21 @@ namespace MusicStore.Controllers
{
public class StoreController : Controller
{
private readonly MusicStoreContext db;
private readonly IMemoryCache cache;
private readonly MusicStoreContext _dbContext;
private readonly IMemoryCache _cache;
public StoreController(MusicStoreContext context, IMemoryCache memoryCache)
{
db = context;
cache = memoryCache;
_dbContext = context;
_cache = memoryCache;
}
//
// GET: /Store/
public IActionResult Index()
public async Task<IActionResult> Index()
{
var genres = db.Genres.ToList();
var genres = await _dbContext.Genres.ToListAsync();
return View(genres);
}
@ -30,22 +31,29 @@ namespace MusicStore.Controllers
//
// GET: /Store/Browse?genre=Disco
public IActionResult Browse(string genre)
public async Task<IActionResult> Browse(string genre)
{
// Retrieve Genre genre and its Associated associated Albums albums from database
var genreModel = db.Genres.Include(g => g.Albums).Where(g => g.Name == genre).FirstOrDefault();
var genreModel = await _dbContext.Genres
.Include(g => g.Albums)
.Where(g => g.Name == genre)
.FirstOrDefaultAsync();
return View(genreModel);
}
public IActionResult Details(int id)
public async Task<IActionResult> Details(int id)
{
var album = cache.GetOrSet(string.Format("album_{0}", id), context =>
var album = await _cache.GetOrSet(string.Format("album_{0}", id), async context =>
{
//Remove it from cache if not retrieved in last 10 minutes
context.SetSlidingExpiration(TimeSpan.FromMinutes(10));
var albumData = db.Albums.Where(a => a.AlbumId == id).Include(a => a.Artist).Include(a => a.Genre).ToList().FirstOrDefault();
return albumData;
return await _dbContext.Albums
.Where(a => a.AlbumId == id)
.Include(a => a.Artist)
.Include(a => a.Genre)
.FirstOrDefaultAsync();
});
return View(album);

View File

@ -1,7 +1,6 @@
using Microsoft.AspNet.Identity;
using MusicStore.Models;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
namespace MusicStore
{

View File

@ -6,17 +6,17 @@ namespace MusicStore.Mocks.Common
{
public class CustomStateDataFormat : ISecureDataFormat<AuthenticationProperties>
{
private static string lastSavedAuthenticationProperties;
private static string _lastSavedAuthenticationProperties;
public string Protect(AuthenticationProperties data)
{
lastSavedAuthenticationProperties = Serialize(data);
_lastSavedAuthenticationProperties = Serialize(data);
return "ValidStateData";
}
public AuthenticationProperties Unprotect(string state)
{
return state == "ValidStateData" ? DeSerialize(lastSavedAuthenticationProperties) : null;
return state == "ValidStateData" ? DeSerialize(_lastSavedAuthenticationProperties) : null;
}
private string Serialize(AuthenticationProperties data)

View File

@ -1,8 +1,8 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MusicStore.Mocks.Common;
using Microsoft.AspNet.WebUtilities;
using MusicStore.Mocks.Common;
namespace MusicStore.Mocks.Facebook
{

View File

@ -1,11 +1,11 @@
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Facebook;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
using System;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Facebook;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
namespace MusicStore.Mocks.Facebook
{

View File

@ -1,7 +1,7 @@
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNet.WebUtilities;
namespace MusicStore.Mocks.Google

View File

@ -1,11 +1,11 @@
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Google;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
using System;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Google;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
namespace MusicStore.Mocks.Google
{

View File

@ -1,7 +1,7 @@
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNet.WebUtilities;
namespace MusicStore.Mocks.MicrosoftAccount

View File

@ -1,11 +1,11 @@
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.MicrosoftAccount;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
using System;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.MicrosoftAccount;
using Microsoft.AspNet.Security.OAuth;
using MusicStore.Mocks.Common;
namespace MusicStore.Mocks.MicrosoftAccount
{

View File

@ -9,18 +9,18 @@ namespace MusicStore.Mocks.Twitter
/// </summary>
public class CustomTwitterStateDataFormat : ISecureDataFormat<RequestToken>
{
private static string lastSavedRequestToken;
private static string _lastSavedRequestToken;
public string Protect(RequestToken data)
{
data.Token = "valid_oauth_token";
lastSavedRequestToken = Serialize(data);
_lastSavedRequestToken = Serialize(data);
return "valid_oauth_token";
}
public RequestToken Unprotect(string state)
{
return state == "valid_oauth_token" ? DeSerialize(lastSavedRequestToken) : null;
return state == "valid_oauth_token" ? DeSerialize(_lastSavedRequestToken) : null;
}
private string Serialize(RequestToken data)

View File

@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.WebUtilities;
using System.Collections.Generic;
using System.Net;
namespace MusicStore.Mocks.Twitter
{
@ -13,7 +13,7 @@ namespace MusicStore.Mocks.Twitter
/// </summary>
public class TwitterMockBackChannelHttpHandler : HttpMessageHandler
{
private static bool RequestTokenEndpointInvoked = false;
private static bool _requestTokenEndpointInvoked = false;
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
@ -25,7 +25,7 @@ namespace MusicStore.Mocks.Twitter
var formData = FormHelpers.ParseForm(await request.Content.ReadAsStringAsync());
if (formData["oauth_verifier"] == "valid_oauth_verifier")
{
if (RequestTokenEndpointInvoked)
if (_requestTokenEndpointInvoked)
{
var response_Form_data = new List<KeyValuePair<string, string>>()
{
@ -53,7 +53,7 @@ namespace MusicStore.Mocks.Twitter
new KeyValuePair<string, string>("oauth_token_secret", "valid_oauth_token_secret")
};
RequestTokenEndpointInvoked = true;
_requestTokenEndpointInvoked = true;
response.Content = new FormUrlEncodedContent(response_Form_data);
}

View File

@ -1,9 +1,9 @@
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Twitter;
using MusicStore.Mocks.Common;
using System.Linq;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Security.Twitter;
using MusicStore.Mocks.Common;
namespace MusicStore.Mocks.Twitter
{

View File

@ -1,6 +1,6 @@
using Microsoft.AspNet.Mvc.Rendering;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Mvc.Rendering;
namespace MusicStore.Models
{

View File

@ -1,7 +1,7 @@
using Microsoft.AspNet.Mvc.ModelBinding;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Mvc.ModelBinding;
namespace MusicStore.Models
{

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.Identity;

View File

@ -1,6 +1,6 @@
using Microsoft.AspNet.Mvc.ModelBinding;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Mvc.ModelBinding;
namespace MusicStore.Models
{

View File

@ -6,8 +6,8 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.SqlServer;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
namespace MusicStore.Models
{

View File

@ -1,18 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
namespace MusicStore.Models
{
public partial class ShoppingCart
public class ShoppingCart
{
MusicStoreContext _db;
string ShoppingCartId { get; set; }
private readonly MusicStoreContext _dbContext;
private string ShoppingCartId { get; set; }
public ShoppingCart(MusicStoreContext db)
public ShoppingCart(MusicStoreContext dbContext)
{
_db = db;
_dbContext = dbContext;
}
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
@ -25,7 +26,7 @@ namespace MusicStore.Models
public void AddToCart(Album album)
{
// Get the matching cart and album instances
var cartItem = _db.CartItems.SingleOrDefault(
var cartItem = _dbContext.CartItems.SingleOrDefault(
c => c.CartId == ShoppingCartId
&& c.AlbumId == album.AlbumId);
@ -40,7 +41,7 @@ namespace MusicStore.Models
DateCreated = DateTime.Now
};
_db.CartItems.Add(cartItem);
_dbContext.CartItems.Add(cartItem);
}
else
{
@ -52,7 +53,7 @@ namespace MusicStore.Models
public int RemoveFromCart(int id)
{
// Get the cart
var cartItem = _db.CartItems.Single(
var cartItem = _dbContext.CartItems.Single(
cart => cart.CartId == ShoppingCartId
&& cart.CartItemId == id);
@ -67,7 +68,7 @@ namespace MusicStore.Models
}
else
{
_db.CartItems.Remove(cartItem);
_dbContext.CartItems.Remove(cartItem);
}
}
@ -76,71 +77,50 @@ namespace MusicStore.Models
public void EmptyCart()
{
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToArray();
_db.CartItems.Remove(cartItems);
var cartItems = _dbContext.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToArray();
_dbContext.CartItems.Remove(cartItems);
}
public List<CartItem> GetCartItems()
public async Task<List<CartItem>> GetCartItems()
{
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToList();
//TODO: Auto population of the related album data not available until EF feature is lighted up.
foreach (var cartItem in cartItems)
{
cartItem.Album = _db.Albums.Single(a => a.AlbumId == cartItem.AlbumId);
}
return cartItems;
return await _dbContext.CartItems.
Where(cart => cart.CartId == ShoppingCartId).
Include(c => c.Album).
ToListAsync();
}
public int GetCount()
public async Task<int> GetCount()
{
int sum = 0;
//https://github.com/aspnet/EntityFramework/issues/557
// Get the count of each item in the cart and sum them up
var cartItemCounts = (from cartItems in _db.CartItems
where cartItems.CartId == ShoppingCartId
select (int?)cartItems.Count);
cartItemCounts.ForEachAsync(carItemCount =>
{
if (carItemCount.HasValue)
{
sum += carItemCount.Value;
}
});
// Return 0 if all entries are null
return sum;
return await (from cartItem in _dbContext.CartItems
where cartItem.CartId == ShoppingCartId
select cartItem.Count).SumAsync();
}
public decimal GetTotal()
public async Task<decimal> GetTotal()
{
// Multiply album price by count of that album to get
// the current price for each of those albums in the cart
// sum all album price totals to get the cart total
// TODO Collapse to a single query once EF supports querying related data
decimal total = 0;
foreach (var item in _db.CartItems.Where(c => c.CartId == ShoppingCartId))
{
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
total += item.Count * album.Price;
}
return total;
// TODO: Use nav prop traversal instead of joins (EF #https://github.com/aspnet/EntityFramework/issues/325)
return await (from cartItem in _dbContext.CartItems
join album in _dbContext.Albums on cartItem.AlbumId equals album.AlbumId
where cartItem.CartId == ShoppingCartId
select cartItem.Count * album.Price).SumAsync();
}
public int CreateOrder(Order order)
public async Task<int> CreateOrder(Order order)
{
decimal orderTotal = 0;
var cartItems = GetCartItems();
var cartItems = await GetCartItems();
// Iterate over the items in the cart, adding the order details for each
foreach (var item in cartItems)
{
//var album = _db.Albums.Find(item.AlbumId);
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
var album = _dbContext.Albums.Single(a => a.AlbumId == item.AlbumId);
var orderDetail = new OrderDetail
{
@ -153,7 +133,7 @@ namespace MusicStore.Models
// Set the order total of the shopping cart
orderTotal += (item.Count * album.Price);
_db.OrderDetails.Add(orderDetail);
_dbContext.OrderDetails.Add(orderDetail);
}
// Set the order's total to the orderTotal count

View File

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.Runtime;
namespace MusicStore
{

View File

@ -3,10 +3,10 @@ using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.Cache.Memory;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using MusicStore.Models;
using Microsoft.Framework.Cache.Memory;
namespace MusicStore
{

View File

@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace System.Net
namespace System.Net
{
public static class Extensions
{

View File

@ -43,7 +43,6 @@ namespace E2ETests
return true;
}
//if (serverType == ServerType.IISNativeModule &&
// Environment.GetEnvironmentVariable("IIS_NATIVE_MODULE_SETUP") != "true")
//{