A few changes with this checkin:

1. Removing copyright text from all files per a code review feedback
2. Adding a cookie based session to the application to retrieve the cart Id.
3. Enabled the Accounts controller as we now have the necessary Http abstractions for User, SignIn, SignOut etc.
4. Changing self hosting scripts to run on coreclr by default.
5. Enabling the layout page on all required views.
6. Adding a favico.ico
7. Renaming the Cart property in the EF context to CartItems as it returns a CartItems list.
8. Uncommenting some code which was previously accessing unavailable APIs. They are available now (but yet to validate them).
This commit is contained in:
Praburaj 2014-04-02 18:40:25 -07:00
parent dabb68cc6d
commit 4709bca281
41 changed files with 595 additions and 659 deletions

View File

@ -11,5 +11,3 @@ rmdir /S /Q %APP_PATH%\Properties
del %APP_PATH%\*.csproj
del %APP_PATH%\*.v12.suo
del %APP_PATH%\*.csproj.user
del src\PlaceHolder\*.csproj
rmdir /S /Q src\PlaceHolder\bin

View File

@ -2,10 +2,9 @@
### Run the application:
1. Run build.cmd to restore all the necessary packages and generate project files
2. Open a command prompt and cd \src\MusicStore\
2. Open a command prompt and cd \src\<AppFolder>\
3. [Helios]:
4. Execute CopyAspNetLoader.cmd to copy the AspNet.Loader.dll to the bin directory
5. Helios.cmd to launch the app on IISExpress.
4. Helios.cmd to launch the app on IISExpress.
4. [SelfHost]:
5. Run Selfhost.cmd (This runs k web) (Note: If your changes to C# files are not picked up in successive builds - try deleting the bin and obj folder)
5. [CustomHost]:
@ -24,5 +23,5 @@
2. This is a captured snapshot of build numbers which worked for this application. This LKG will be captured once in a while.
### Note:
1. By default this script starts the application at http://localhost:5001/. Modify Run.cmd if you would like to change the url
2. Use Visual studio only for editing & intellisense. Don't try to build or run the app from Visual studio.
1. By default the scripts will start the application at http://localhost:5001/. Modify the scripts to change the url.
2. Use Visual studio only for editing & intellisense. Don't try to build or run the app from Visual studio.

View File

@ -1,505 +1,484 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Abstractions.Security;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.InMemory;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using MusicStore.Models;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
//using Microsoft.AspNet.Identity;
//using Microsoft.AspNet.Identity.InMemory;
//using Microsoft.AspNet.Mvc;
//using Microsoft.AspNet.Mvc.ModelBinding;
//using MusicStore.Models;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Threading.Tasks;
namespace MusicStore.Controllers
{
//[Authorize]
public class AccountController : Controller
{
public AccountController()
//Bug: No EF yet - using an in memory store
//: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
: this(new UserManager<ApplicationUser, string>(new InMemoryUserStore<ApplicationUser>()))
{
}
//namespace MusicStore.Controllers
//{
// //[Authorize]
// public class AccountController : Controller
// {
// public AccountController()
// //Bug: No EF yet - using an in memory store
// //: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
// : this(new UserManager<ApplicationUser, string>(new InMemoryUserStore<ApplicationUser>()))
// {
// }
public AccountController(UserManager<ApplicationUser, string> userManager)
{
UserManager = userManager;
}
// public AccountController(UserManager<ApplicationUser, string> userManager)
// {
// UserManager = userManager;
// }
public UserManager<ApplicationUser, string> UserManager { get; private set; }
// public UserManager<ApplicationUser, string> UserManager { get; private set; }
//
// GET: /Account/Login
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
// private void MigrateShoppingCart(string UserName)
// {
// //Bug: No EF
// //var storeDb = new MusicStoreEntities();
// var storeDb = MusicStoreEntities.Instance;
//
// POST: /Account/Login
//Bug: HTTP verb attribs not available
//[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid == true)
{
var user = await UserManager.Find(model.UserName, model.Password);
if (user != null)
{
await SignIn(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// // Associate shopping cart items with logged-in user
// var cart = ShoppingCart.GetCart(storeDb, this.Context);
// cart.MigrateCart(UserName);
// storeDb.SaveChanges();
// If we got this far, something failed, redisplay form
return View(model);
}
// //Bug: TODO
// //Session[ShoppingCart.CartSessionKey] = UserName;
// }
//
// GET: /Account/Register
[AllowAnonymous]
public IActionResult Register()
{
return View();
}
// //
// // GET: /Account/Login
// [AllowAnonymous]
// public IActionResult Login(string returnUrl)
// {
// //ViewBag.ReturnUrl = returnUrl;
// return View();
// }
//
// POST: /Account/Register
//Bug: Missing verb attributes
//[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid == true)
{
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.Create(user, model.Password);
if (result.Succeeded)
{
await SignIn(user, isPersistent: false);
//Bug: No helper methods
//return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// //
// // POST: /Account/Login
// //Bug: HTTP verb attribs not available
// //[HttpPost]
// [AllowAnonymous]
// //[ValidateAntiForgeryToken]
// public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
// {
// //Bug: How to validate the model state?
// //if (ModelState.IsValid)
// {
// var user = await UserManager.Find(model.UserName, model.Password);
// if (user != null)
// {
// await SignIn(user, model.RememberMe);
// return RedirectToLocal(returnUrl);
// }
// else
// {
// //Bug: Model state error
// //ModelState.AddModelError("", "Invalid username or password.");
// }
// }
// If we got this far, something failed, redisplay form
return View(model);
}
// // If we got this far, something failed, redisplay form
// return View(model);
// }
//
// POST: /Account/Disassociate
//Bug: HTTP verbs
//[HttpPost]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> Disassociate(string loginProvider, string providerKey)
{
// //
// // GET: /Account/Register
// [AllowAnonymous]
// public IActionResult Register()
// {
// return View();
// }
ManageMessageId? message = null;
IdentityResult result = await UserManager.RemoveLogin(this.Context.User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded)
{
message = ManageMessageId.RemoveLoginSuccess;
}
else
{
message = ManageMessageId.Error;
}
//Bug: No helpers available
//return RedirectToAction("Manage", new { Message = message });
return View();
}
// //
// // POST: /Account/Register
// //Bug: Missing verb attributes
// //[HttpPost]
// [AllowAnonymous]
// //[ValidateAntiForgeryToken]
// public async Task<IActionResult> Register(RegisterViewModel model)
// {
// //Bug: How to validate the model state?
// //if (ModelState.IsValid)
// {
// //Bug: Replacing it with InmemoryUser
// var user = new ApplicationUser() { UserName = model.UserName };
// var result = await UserManager.Create(user, model.Password);
// if (result.Succeeded)
// {
// await SignIn(user, isPersistent: false);
// //Bug: No helper methods
// //return RedirectToAction("Index", "Home");
// }
// else
// {
// AddErrors(result);
// }
// }
//
// GET: /Account/Manage
public IActionResult Manage(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
ViewBag.HasLocalPassword = HasPassword();
//Bug: No Action method with single parameter
//ViewBag.ReturnUrl = Url.Action("Manage");
//ViewBag.ReturnUrl = Url.Action("Manage", "Account", null);
return View();
}
// // If we got this far, something failed, redisplay form
// return View(model);
// }
//
// POST: /Account/Manage
//Bug: No verb attributes
//[HttpPost]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> Manage(ManageUserViewModel model)
{
bool hasPassword = await HasPassword();
ViewBag.HasLocalPassword = hasPassword;
//Bug: No Action method with single parameter
//ViewBag.ReturnUrl = Url.Action("Manage");
//ViewBag.ReturnUrl = Url.Action("Manage", "Account", null);
if (hasPassword)
{
if (ModelState.IsValid == true)
{
IdentityResult result = await UserManager.ChangePassword(this.Context.User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
//Bug: No helper method
//return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
return View();
}
else
{
AddErrors(result);
}
}
}
else
{
// User does not have a password so remove any validation errors caused by a missing OldPassword field
ModelState state = null;
ModelState.TryGetValue("OldPassword", out state);
// //
// // POST: /Account/Disassociate
// //Bug: HTTP verbs
// //[HttpPost]
// //[ValidateAntiForgeryToken]
// public async Task<IActionResult> Disassociate(string loginProvider, string providerKey)
// {
// ManageMessageId? message = null;
// IdentityResult result = await UserManager.RemoveLogin(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
// if (result.Succeeded)
// {
// message = ManageMessageId.RemoveLoginSuccess;
// }
// else
// {
// message = ManageMessageId.Error;
// }
// //Bug: No helpers available
// //return RedirectToAction("Manage", new { Message = message });
// return View();
// }
if (state != null)
{
state.Errors.Clear();
}
// //
// // GET: /Account/Manage
// public IActionResult Manage(ManageMessageId? message)
// {
// //ViewBag.StatusMessage =
// // message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
// // : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
// // : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
// // : message == ManageMessageId.Error ? "An error has occurred."
// // : "";
// //ViewBag.HasLocalPassword = HasPassword();
// //Bug: No Action method with single parameter
// //ViewBag.ReturnUrl = Url.Action("Manage");
// //ViewBag.ReturnUrl = Url.Action("Manage", "Account", null);
// return View();
// }
if (ModelState.IsValid == true)
{
IdentityResult result = await UserManager.AddPassword(this.Context.User.Identity.GetUserId(), model.NewPassword);
if (result.Succeeded)
{
//Bug: No helper method
//return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
}
else
{
AddErrors(result);
}
}
}
// //
// // POST: /Account/Manage
// //Bug: No verb attributes
// //[HttpPost]
// //[ValidateAntiForgeryToken]
// public async Task<IActionResult> Manage(ManageUserViewModel model)
// {
// bool hasPassword = await HasPassword();
// //ViewBag.HasLocalPassword = hasPassword;
// //Bug: No Action method with single parameter
// //ViewBag.ReturnUrl = Url.Action("Manage");
// //ViewBag.ReturnUrl = Url.Action("Manage", "Account", null);
// if (hasPassword)
// {
// //if (ModelState.IsValid)
// {
// IdentityResult result = await UserManager.ChangePassword(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
// if (result.Succeeded)
// {
// //Bug: No helper method
// //return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
// return View();
// }
// else
// {
// AddErrors(result);
// }
// }
// }
// else
// {
// // User does not have a password so remove any validation errors caused by a missing OldPassword field
// //Bug: Still controller does not have a ModelState property
// //ModelState state = ModelState["OldPassword"];
// ModelState state = null;
// If we got this far, something failed, redisplay form
return View(model);
}
// if (state != null)
// {
// state.Errors.Clear();
// }
//
// POST: /Account/ExternalLogin
//Bug: No verb attributes
//[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider, string returnUrl)
{
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
// //Bug: No model state validation
// //if (ModelState.IsValid)
// {
// IdentityResult result = await UserManager.AddPassword(User.Identity.GetUserId(), model.NewPassword);
// if (result.Succeeded)
// {
// //Bug: No helper method
// //return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
// }
// else
// {
// AddErrors(result);
// }
// }
// }
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await this.Context.Response.GetExternalLoginInfo();
if (loginInfo == null)
{
//Bug: No helper
//return RedirectToAction("Login");
return View();
}
// // If we got this far, something failed, redisplay form
// return View(model);
// }
// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.Find(loginInfo.Login);
if (user != null)
{
await SignIn(user, isPersistent: false);
return RedirectToLocal(returnUrl);
}
else
{
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });
}
}
// //
// // POST: /Account/ExternalLogin
// //Bug: No verb attributes
// //[HttpPost]
// [AllowAnonymous]
// //[ValidateAntiForgeryToken]
// public IActionResult ExternalLogin(string provider, string returnUrl)
// {
// // Request a redirect to the external login provider
// return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
// }
//
// POST: /Account/LinkLogin
//Bug: No HTTP verbs
//[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account", null), this.Context.User.Identity.GetUserId());
}
// //
// // GET: /Account/ExternalLoginCallback
// [AllowAnonymous]
// public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
// {
// var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
// if (loginInfo == null)
// {
// //Bug: No helper
// //return RedirectToAction("Login");
// return View();
// }
//
// GET: /Account/LinkLoginCallback
public async Task<IActionResult> LinkLoginCallback()
{
var loginInfo = await this.Context.Response.GetExternalLoginInfo(XsrfKey, this.Context.User.Identity.GetUserId());
if (loginInfo == null)
{
//Bug: No helper method
//return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
return View();
}
var result = await UserManager.AddLogin(this.Context.User.Identity.GetUserId(), loginInfo.Login);
if (result.Succeeded)
{
//Bug: No helper method
//return RedirectToAction("Manage");
return View();
}
//Bug: No helper method
//return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
return View();
}
// // Sign in the user with this external login provider if the user already has a login
// var user = await UserManager.Find(loginInfo.Login);
// if (user != null)
// {
// await SignIn(user, isPersistent: false);
// return RedirectToLocal(returnUrl);
// }
// else
// {
// // If the user does not have an account, then prompt the user to create an account
// //ViewBag.ReturnUrl = returnUrl;
// //ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
// return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });
// }
// }
//
// POST: /Account/ExternalLoginConfirmation
//Bug: No HTTP verbs
//[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (this.Context.User.Identity.IsAuthenticated)
{
//Bug: No helper yet
//return RedirectToAction("Manage");
return View();
}
// //
// // POST: /Account/LinkLogin
// //Bug: No HTTP verbs
// //[HttpPost]
// //[ValidateAntiForgeryToken]
// public IActionResult LinkLogin(string provider)
// {
// // Request a redirect to the external login provider to link a login for the current user
// return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account", null), User.Identity.GetUserId());
// }
if (ModelState.IsValid == true)
{
// Get the information about the user from the external login provider
var info = await this.Context.Response.GetExternalLoginInfo();
if (info == null)
{
return View("ExternalLoginFailure");
}
// //
// // GET: /Account/LinkLoginCallback
// public async Task<IActionResult> LinkLoginCallback()
// {
// var loginInfo = null;// await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
// if (loginInfo == null)
// {
// //Bug: No helper method
// //return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
// return View();
// }
// var result = await UserManager.AddLogin(User.Identity.GetUserId(), loginInfo.Login);
// if (result.Succeeded)
// {
// //Bug: No helper method
// //return RedirectToAction("Manage");
// return View();
// }
// //Bug: No helper method
// //return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
// return View();
// }
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.Create(user);
if (result.Succeeded)
{
result = await UserManager.AddLogin(user.Id, info.Login);
if (result.Succeeded)
{
await SignIn(user, isPersistent: false);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
// //
// // POST: /Account/ExternalLoginConfirmation
// //Bug: No HTTP verbs
// //[HttpPost]
// [AllowAnonymous]
// //[ValidateAntiForgeryToken]
// public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
// {
// if (User.Identity.IsAuthenticated)
// {
// //Bug: No helper yet
// //return RedirectToAction("Manage");
// return View();
// }
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
// //Bug: No model state validation
// //if (ModelState.IsValid)
// {
// // Get the information about the user from the external login provider
// var info = await AuthenticationManager.GetExternalLoginInfoAsync();
// if (info == null)
// {
// return View("ExternalLoginFailure");
// }
// //Using InMemory user
// var user = new ApplicationUser() { UserName = model.UserName };
// var result = await UserManager.Create(user);
// if (result.Succeeded)
// {
// result = await UserManager.AddLogin(user.Id, info.Login);
// if (result.Succeeded)
// {
// await SignIn(user, isPersistent: false);
// return RedirectToLocal(returnUrl);
// }
// }
// AddErrors(result);
// }
//
// POST: /Account/LogOff
//Bug: No HTTP verbs
//[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult LogOff()
{
this.Context.Response.SignOut();
//Bug: No helper
//return RedirectToAction("Index", "Home");
return View();
}
// //ViewBag.ReturnUrl = returnUrl;
// return View(model);
// }
//
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public IActionResult ExternalLoginFailure()
{
return View();
}
// //
// // POST: /Account/LogOff
// //Bug: No HTTP verbs
// //[HttpPost]
// //[ValidateAntiForgeryToken]
// public IActionResult LogOff()
// {
// AuthenticationManager.SignOut();
// //return RedirectToAction("Index", "Home");
// return View();
// }
//Bug: Need this attribute
//[ChildActionOnly]
public async Task<IActionResult> RemoveAccountList()
{
var linkedAccounts = await UserManager.GetLogins(this.Context.User.Identity.GetUserId());
ViewBag.ShowRemoveButton = await HasPassword() || linkedAccounts.Count > 1;
//Bug: We dont have partial views yet
//return (IActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
return View();
}
// //
// // GET: /Account/ExternalLoginFailure
// [AllowAnonymous]
// public IActionResult ExternalLoginFailure()
// {
// return View();
// }
//Bug: Controllers need to be disposable?
protected void Dispose(bool disposing)
{
if (disposing && UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
// //Bug: Need this attribute
// //[ChildActionOnly]
// public async Task<IActionResult> RemoveAccountList()
// {
// var linkedAccounts = await UserManager.GetLogins(User.Identity.GetUserId());
// //ViewBag.ShowRemoveButton = await HasPassword() || linkedAccounts.Count > 1;
// //Bug: We dont have partial views yet
// //return (IActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
// return View();
// }
//base.Dispose(disposing);
}
// //Bug: Controllers need to be disposable?
// protected void Dispose(bool disposing)
// {
// if (disposing && UserManager != null)
// {
// UserManager.Dispose();
// UserManager = null;
// }
// //base.Dispose(disposing);
// }
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
// #region Helpers
// // Used for XSRF protection when adding external logins
// private const string XsrfKey = "XsrfId";
private async Task SignIn(ApplicationUser user, bool isPersistent)
{
this.Context.Response.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
this.Context.Response.SignIn(identity, new AuthenticationProperties() { IsPersistent = isPersistent });
}
// //private IAuthenticationManager AuthenticationManager
// //{
// // get
// // {
// // //Will change to Context.Authentication
// // return new IAuthenticationManager();
// // }
// //}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
// private async Task SignIn(ApplicationUser user, bool isPersistent)
// {
// //Bug: No cookies middleware now.
// //AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
// //var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
// //AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
private async Task<bool> HasPassword()
{
var user = await UserManager.FindById(this.Context.User.Identity.GetUserId());
if (user != null)
{
return user.PasswordHash != null;
}
return false;
}
// // Migrate the user's shopping cart
// MigrateShoppingCart(user.UserName);
// }
public enum ManageMessageId
{
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
Error
}
// private void AddErrors(IdentityResult result)
// {
// foreach (var error in result.Errors)
// {
// //ModelState.AddModelError("", error);
// }
// }
private IActionResult RedirectToLocal(string returnUrl)
{
//Bug: No helpers available
//if (Url.IsLocalUrl(returnUrl))
//{
// return Redirect(returnUrl);
//}
//else
//{
// return RedirectToAction("Index", "Home");
//}
return View();
}
// private async Task<bool> HasPassword()
// {
// //Bug: Need to get the User object somehow: TODO
// //var user = await UserManager.FindById(User.Identity.GetUserId());
// var user = await UserManager.FindById("TODO");
// if (user != null)
// {
// return user.PasswordHash != null;
// }
// return false;
// }
private class ChallengeResult : HttpStatusCodeResult
{
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
// public enum ManageMessageId
// {
// ChangePasswordSuccess,
// SetPasswordSuccess,
// RemoveLoginSuccess,
// Error
// }
public ChallengeResult(string provider, string redirectUri, string userId)
: base(401)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
// private IActionResult RedirectToLocal(string returnUrl)
// {
// //Bug: No helpers available
// //if (Url.IsLocalUrl(returnUrl))
// //{
// // return Redirect(returnUrl);
// //}
// //else
// //{
// // return RedirectToAction("Index", "Home");
// //}
// return View();
// }
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
// private class ChallengeResult : HttpStatusCodeResult
// {
// public ChallengeResult(string provider, string redirectUri)
// : this(provider, redirectUri, null)
// {
// }
new public void ExecuteResultAsync(ActionContext context)
{
var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
// public ChallengeResult(string provider, string redirectUri, string userId)
// : base(401)
// {
// LoginProvider = provider;
// RedirectUri = redirectUri;
// UserId = userId;
// }
context.HttpContext.Response.Challenge(LoginProvider, properties);
}
}
#endregion
}
// public string LoginProvider { get; set; }
// public string RedirectUri { get; set; }
// public string UserId { get; set; }
/// <summary>
/// TODO: Temporary APIs to unblock build. Need to remove this once we have these APIs available.
/// </summary>
public static class Extensions
{
public static string GetUserId(this IIdentity user)
{
return string.Empty;
}
// new public void ExecuteResultAsync(ActionContext context)
// {
// //Bug: No security package yet
// //var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
// //if (UserId != null)
// //{
// // properties.Dictionary[XsrfKey] = UserId;
// //}
// //context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
// }
// }
// #endregion
// }
public static Task<ExternalLoginInfo> GetExternalLoginInfo(this HttpResponse response)
{
return Task.FromResult<ExternalLoginInfo>(new ExternalLoginInfo());
}
// //Bug: To remove this. Until we have ClaimsPrincipal available
// internal class User
// {
// public static IdentityInstance Identity { get; set; }
public static Task<ExternalLoginInfo> GetExternalLoginInfo(this HttpResponse response, string xsrfKey, string expectedValue)
{
return Task.FromResult<ExternalLoginInfo>(new ExternalLoginInfo());
}
}
// public User()
// {
// if (Identity == null)
// {
// Identity = new IdentityInstance();
// }
// }
/// <summary>
/// TODO: Temporary APIs to unblock build. Need to remove this once we have these APIs available.
/// </summary>
public class ExternalLoginInfo
{
public string DefaultUserName { get; set; }
public UserLoginInfo Login { get; set; }
}
// internal class IdentityInstance
// {
// public string GetUserId()
// {
// return string.Empty;
// }
// public bool IsAuthenticated { get; set; }
// }
// }
//}
/// <summary>
/// TODO: Temporary APIs to unblock build. Need to remove this once we have these APIs available.
/// </summary>
public static class DefaultAuthenticationTypes
{
public const string ApplicationCookie = "Application";
public const string ExternalCookie = "External";
}
}

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System;
using System.Linq;
@ -26,20 +24,16 @@ namespace MusicStore.Controllers
//
// POST: /Checkout/AddressAndPayment
//Bug: Http verbs not available. Also binding to FormCollection is not available.
//Bug: Http verbs not available.
//Bug: Using direct model binding until we have TryUpdateModel available.
//[HttpPost]
//public IActionResult AddressAndPayment(FormCollection values)
public async Task<IActionResult> AddressAndPayment(int workaroundId)
public async Task<IActionResult> AddressAndPayment(Order order)
{
var formCollection = await Context.Request.GetFormAsync();
var order = new Order();
//TryUpdateModel(order);
try
{
//if (string.Equals(values["PromoCode"], PromoCode,
// StringComparison.OrdinalIgnoreCase) == false)
if (string.Equals(formCollection.GetValues("PromoCode").FirstOrDefault(), PromoCode,
StringComparison.OrdinalIgnoreCase) == false)
{
@ -52,20 +46,9 @@ namespace MusicStore.Controllers
? db.Orders.Max(o => o.OrderId) + 1
: 1;
//Bug: Object values should come from page (putting in hard coded values as EF can't work with nulls against SQL Server yet)
//Bug: Identity not available
order.Username = "unknown"; //User.Identity.Name;
order.OrderId = nextId;
order.Username = this.Context.User.Identity.Name;
order.OrderDate = DateTime.Now;
order.FirstName = "John";
order.LastName = "Doe";
order.Address = "One Microsoft Way";
order.City = "Redmond";
order.State = "WA";
order.Country = "USA";
order.Email = "john.doe@example.com";
order.Phone = "555-555-5555";
order.PostalCode = "98052";
//Add the Order
db.Orders.Add(order);
@ -82,7 +65,6 @@ namespace MusicStore.Controllers
// new { id = order.OrderId });
return View();
}
}
catch
{
@ -97,13 +79,9 @@ namespace MusicStore.Controllers
public IActionResult Complete(int id)
{
// Validate customer owns this order
//Bug: Identity not available
//bool isValid = storeDB.Orders.Any(
// o => o.OrderId == id &&
// o.Username == User.Identity.Name);
bool isValid = db.Orders.Any(
o => o.OrderId == id);
o => o.OrderId == id &&
o.Username == this.Context.User.Identity.Name);
if (isValid)
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using MusicStore.ViewModels;
using System.Linq;
@ -64,7 +62,7 @@ namespace MusicStore.Controllers
// 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.Carts.Single(item => item.CartItemId == id).AlbumId;
int albumId = db.CartItems.Single(item => item.CartItemId == id).AlbumId;
string albumName = db.Albums.Single(a => a.AlbumId == albumId).Title;
// Remove from cart

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
using System.Linq;

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Data.Entity;
using MusicStore.Models;
@ -49,32 +47,31 @@ namespace MusicStore.Controllers
//
// GET: /StoreManager/Create
//public IActionResult Create()
//{
// ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name");
// ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name");
// return View();
//}
public IActionResult Create()
{
//ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name");
//ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name");
return View();
}
//Bug: ModelState.IsValid not available
//Bug: RedirectToAction() not available
//Bug: SelectList not available
// POST: /StoreManager/Create
//[HttpPost]
//public IActionResult Create(Album album)
//{
// if (ModelState.IsValid)
// {
// db.Albums.Add(album);
// db.SaveChanges();
// return RedirectToAction("Index");
// }
public IActionResult Create(Album album)
{
if (ModelState.IsValid == true)
{
db.Albums.Add(album);
db.SaveChanges();
//Bug: RedirectToAction() not available
//return RedirectToAction("Index");
return View();
}
// ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
// ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
// return View(album);
//}
//ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
//ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
return View(album);
}
//
// GET: /StoreManager/Edit/5
@ -100,13 +97,13 @@ namespace MusicStore.Controllers
//[HttpPost]
public IActionResult Edit(Album album)
{
//Bug: ModelState.IsValid missing
//if (ModelState.IsValid)
if (ModelState.IsValid == true)
{
db.ChangeTracker.Entry(album).State = EntityState.Modified;
db.SaveChanges();
//Bug: Missing RedirectToAction helper
//return RedirectToAction("Index");
return View();
}
//ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
//ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);

View File

@ -1,3 +1,6 @@
REM run on k10 by default. Assign it to an empty value to run on desktop CLR.
SET TARGET_FRAMEWORK=k10
REM Selfhost does not need this bin folder
rmdir /S /Q bin

View File

@ -1 +1,4 @@
REM copy the AspNet.Loader.dll to the bin folder
call CopyAspNetLoader.cmd
"%ProgramFiles(x86)%\iis Express\iisexpress.exe" /port:5001 /path:"%cd%"

View File

@ -1,31 +1,32 @@
{
"version": "0.1-alpha-*",
"dependencies": {
"Helios": "0.1-alpha-107",
"Microsoft.AspNet.Abstractions": "0.1-alpha-162",
"Microsoft.AspNet.Mvc": "0.1-alpha-324",
"Microsoft.AspNet.Razor": "0.1-alpha-144",
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-117",
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-169",
"Microsoft.AspNet.RequestContainer": "0.1-alpha-133",
"Microsoft.AspNet.Routing": "0.1-alpha-115",
"Microsoft.AspNet.Mvc.ModelBinding": "0.1-alpha-324",
"Microsoft.AspNet.Mvc.Core": "0.1-alpha-324",
"Microsoft.AspNet.Mvc.Razor": "0.1-alpha-324",
"Microsoft.AspNet.Mvc.Rendering": "0.1-alpha-324",
"Microsoft.AspNet.StaticFiles": "0.1-alpha-090",
"System.Security.Claims": "0.1-alpha-052",
"Microsoft.AspNet.Security.DataProtection": "0.1-alpha-100",
"Microsoft.AspNet.Identity": "0.1-alpha-164",
"Microsoft.AspNet.Identity.Entity": "0.1-alpha-164",
"Microsoft.AspNet.Identity.InMemory": "0.1-alpha-164",
"Microsoft.Data.Entity": "0.1-alpha-284",
"Microsoft.Data.Relational": "0.1-alpha-284",
"Microsoft.Data.SqlServer": "0.1-pre-284",
"Microsoft.Data.InMemory": "0.1-alpha-284",
"Microsoft.AspNet.Diagnostics": "0.1-alpha-025",
"Microsoft.AspNet.Hosting": "0.1-alpha-133",
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-039"
"Helios": "0.1-alpha-168",
"Microsoft.AspNet.Abstractions": "0.1-alpha-210",
"Microsoft.AspNet.Mvc": "0.1-alpha-449",
"Microsoft.AspNet.Razor": "0.1-alpha-181",
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-167",
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-232",
"Microsoft.AspNet.RequestContainer": "0.1-alpha-201",
"Microsoft.AspNet.Routing": "0.1-alpha-182",
"Microsoft.AspNet.Mvc.ModelBinding": "0.1-alpha-449",
"Microsoft.AspNet.Mvc.Core": "0.1-alpha-449",
"Microsoft.AspNet.Mvc.Razor": "0.1-alpha-449",
"Microsoft.AspNet.Mvc.Rendering": "0.1-alpha-449",
"Microsoft.AspNet.StaticFiles": "0.1-alpha-146",
"System.Security.Claims": "0.1-alpha-094",
"System.Security.Principal": "4.0.0.0",
"Microsoft.AspNet.Security.DataProtection": "0.1-alpha-141",
"Microsoft.AspNet.Identity": "0.1-alpha-238",
"Microsoft.AspNet.Identity.Entity": "0.1-alpha-238",
"Microsoft.AspNet.Identity.InMemory": "0.1-alpha-238",
"Microsoft.Data.Entity": "0.1-alpha-380",
"Microsoft.Data.Relational": "0.1-alpha-380",
"Microsoft.Data.SqlServer": "0.1-pre-380",
"Microsoft.Data.InMemory": "0.1-alpha-380",
"Microsoft.AspNet.Diagnostics": "0.1-alpha-081",
"Microsoft.AspNet.Hosting": "0.1-alpha-201",
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-105"
},
"configurations": {
"net45": {
@ -41,7 +42,7 @@
"System.Linq": "4.0.0.0",
"System.Runtime": "4.0.20.0",
"System.Dynamic.Runtime": "4.0.0.0",
"System.Threading.Tasks": "4.0.0.0",
"System.Threading.Tasks": "4.0.10.0",
"System.ComponentModel": "4.0.0.0",
"System.Console": "4.0.0.0",
"System.Diagnostics.Debug": "4.0.10.0",

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models
{

View File

@ -1,12 +1,11 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models
{
public class CartItem
{
[Key]
public int CartItemId { get; set; }
[Required]

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Identity.InMemory;
using Microsoft.AspNet.Identity.InMemory;
namespace MusicStore.Models
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.Data.Entity;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata;
using Microsoft.Data.InMemory;
using Microsoft.Data.SqlServer;
@ -13,7 +11,7 @@ namespace MusicStore.Models
public EntitySet<Artist> Artists { get; set; }
public EntitySet<Order> Orders { get; set; }
public EntitySet<Genre> Genres { get; set; }
public EntitySet<CartItem> Carts { get; set; }
public EntitySet<CartItem> CartItems { get; set; }
public EntitySet<OrderDetail> OrderDetails { get; set; }
protected override void OnConfiguring(EntityConfigurationBuilder builder)

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MusicStore.Models

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace MusicStore.Models
namespace MusicStore.Models
{
public class OrderDetail
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.Data.Entity;
using Microsoft.Data.Entity;
using Microsoft.Data.SqlServer;
using MusicStore.Models;
using System;

View File

@ -1,7 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Abstractions;
using Microsoft.Data.Entity;
using System;
using System.Collections.Generic;
@ -19,8 +16,6 @@ namespace MusicStore.Models
_db = db;
}
public const string CartSessionKey = "CartId";
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
{
var cart = new ShoppingCart(db);
@ -38,15 +33,15 @@ namespace MusicStore.Models
public void AddToCart(Album album)
{
// Get the matching cart and album instances
var cartItem = _db.Carts.SingleOrDefault(
var cartItem = _db.CartItems.SingleOrDefault(
c => c.CartId == ShoppingCartId
&& c.AlbumId == album.AlbumId);
if (cartItem == null)
{
// TODO [EF] Swap to store generated key once we support identity pattern
var nextCartItemId = _db.Carts.Any()
? _db.Carts.Max(c => c.CartItemId) + 1
var nextCartItemId = _db.CartItems.Any()
? _db.CartItems.Max(c => c.CartItemId) + 1
: 1;
// Create a new cart item if no cart item exists
@ -59,7 +54,7 @@ namespace MusicStore.Models
DateCreated = DateTime.Now
};
_db.Carts.Add(cartItem);
_db.CartItems.Add(cartItem);
}
else
{
@ -67,14 +62,14 @@ namespace MusicStore.Models
cartItem.Count++;
// TODO [EF] Remove this line once change detection is available
_db.ChangeTracker.Entry(cartItem).State = Microsoft.Data.Entity.EntityState.Modified;
_db.ChangeTracker.Entry(cartItem).State = EntityState.Modified;
}
}
public int RemoveFromCart(int id)
{
// Get the cart
var cartItem = _db.Carts.Single(
var cartItem = _db.CartItems.Single(
cart => cart.CartId == ShoppingCartId
&& cart.CartItemId == id);
@ -93,7 +88,7 @@ namespace MusicStore.Models
}
else
{
_db.Carts.Remove(cartItem);
_db.CartItems.Remove(cartItem);
}
}
@ -103,7 +98,7 @@ namespace MusicStore.Models
public void EmptyCart()
{
var cartItems = _db.Carts.Where(cart => cart.CartId == ShoppingCartId);
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId);
foreach (var cartItem in cartItems)
{
@ -115,13 +110,13 @@ namespace MusicStore.Models
public List<CartItem> GetCartItems()
{
return _db.Carts.Where(cart => cart.CartId == ShoppingCartId).ToList();
return _db.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToList();
}
public int GetCount()
{
// Get the count of each item in the cart and sum them up
int? count = (from cartItems in _db.Carts
int? count = (from cartItems in _db.CartItems
where cartItems.CartId == ShoppingCartId
select (int?)cartItems.Count).Sum();
@ -137,7 +132,7 @@ namespace MusicStore.Models
// TODO Collapse to a single query once EF supports querying related data
decimal total = 0;
foreach (var item in _db.Carts.Where(c => c.CartId == ShoppingCartId))
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;
@ -194,38 +189,23 @@ namespace MusicStore.Models
// We're using HttpContextBase to allow access to cookies.
public string GetCartId(HttpContext context)
{
//Bug: Session not in scope. But we should substitute this with cookies when available.
//if (context.Session[CartSessionKey] == null)
//{
// if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))
// {
// context.Session[CartSessionKey] = context.User.Identity.Name;
// }
// else
// {
// // Generate a new random GUID using System.Guid class
// Guid tempCartId = Guid.NewGuid();
var sessionCookie = context.Request.Cookies.Get("Session");
string cartId = null;
// // Send tempCartId back to client as a cookie
// context.Session[CartSessionKey] = tempCartId.ToString();
// }
//}
//return context.Session[CartSessionKey].ToString();
return string.Empty;
}
// When a user has logged in, migrate their shopping cart to
// be associated with their username
public void MigrateCart(string userName)
{
var shoppingCart = _db.Carts.Where(c => c.CartId == ShoppingCartId);
foreach (CartItem item in shoppingCart)
if (string.IsNullOrWhiteSpace(sessionCookie))
{
item.CartId = userName;
//A GUID to hold the cartId.
cartId = Guid.NewGuid().ToString();
// Send cart Id as a cookie to the client.
context.Response.Cookies.Append("Session", cartId);
}
else
{
cartId = sessionCookie;
}
return cartId;
}
}
}

View File

@ -1 +0,0 @@
"%ProgramFiles(x86)%\iis Express\iisexpress.exe" /port:5001 /path:"%cd%"

View File

@ -1,3 +1,6 @@
REM run on k10 by default. Assign it to an empty value to run on desktop CLR.
SET TARGET_FRAMEWORK=k10
REM Selfhost does not need this bin folder
rmdir /S /Q bin

View File

@ -1,11 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.AspNet;
using Microsoft.AspNet;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.ConfigurationModel;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.DependencyInjection.Fallback;
using Microsoft.AspNet.DependencyInjection.NestedProviders;
using Microsoft.AspNet.RequestContainer;
using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.InMemory;
@ -22,11 +21,13 @@ public class Startup
{
CreateAdminUser();
//ErrorPageOptions.ShowAll to be used only at development time. Not recommended for production.
app.UseErrorPage(ErrorPageOptions.ShowAll);
app.UseFileServer();
var serviceProvider = MvcServices.GetDefaultServices().BuildServiceProvider(app.ServiceProvider);
app.UseContainer(serviceProvider);
var routes = new RouteCollection()
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace MusicStore.ViewModels
namespace MusicStore.ViewModels
{
public class ShoppingCartRemoveViewModel
{

View File

@ -1,6 +1,4 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Generic;
using MusicStore.Models;
namespace MusicStore.ViewModels

View File

@ -1,6 +1,5 @@
@*Bug: Having a ViewBag.Title throws compilation error: https://github.com/aspnet/WebFx/issues/67*@
@{
//Layout = "/Views/Shared/_Layout.cshtml";
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Home Page";
}

View File

@ -41,7 +41,8 @@
<hr />
<footer class="navbar navbar-fixed-bottom navbar-default text-center">
<p><a href="http://mvcmusicstore.codeplex.com">mvcmusicstore.codeplex.com</a></p>
<small>@Html.ActionLink("admin", "Index", "StoreManager")</small>
@*Bug: No Html helpers yet*@
@*<small>@Html.ActionLink("admin", "Index", "StoreManager")</small>*@
</footer>
</div>
@ -54,4 +55,4 @@
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
</body>
</html>
</html>

View File

@ -1,4 +1,9 @@
@if (ViewBag.CartCount > 0)
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
}
@if (ViewBag.CartCount > 0)
{
<li>
<a href="@Url.Action("Index", "ShoppingCart")" title="@ViewBag.CartSummary">

View File

@ -1,9 +1,11 @@
@model MvcMusicStore.ViewModels.ShoppingCartViewModel
@model MusicStore.ViewModels.ShoppingCartViewModel
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Shopping Cart";
}
@section Scripts {
@*//@section Scripts {*@
<script type="text/javascript">
$(function () {
// Document.ready -> link up remove event handler
@ -33,13 +35,13 @@
});
</script>
}
@*}*@
<h3>
<em>Review</em> your cart:
</h3>
<p class="button">
@Html.ActionLink("Checkout >>", "AddressAndPayment", "Checkout")
@*@Html.ActionLink("Checkout >>", "AddressAndPayment", "Checkout")*@
</p>
<div id="update-message">
</div>
@ -58,22 +60,22 @@
</tr>
@foreach (var item in Model.CartItems)
{
<tr id="row-@item.RecordId">
<tr id="row-@item.CartItemId">
<td>
@Html.ActionLink(item.Album.Title,
"Details", "Store", new { id = item.AlbumId }, null)
@*@Html.ActionLink(item.Album.Title,
"Details", "Store", new { id = item.AlbumId }, null)*@
</td>
<td>
@item.Album.Price
</td>
<td id="item-count-@item.RecordId">
<td id="item-count-@item.CartItemId">
@item.Count
</td>
<td>
<a href="#" class="RemoveLink" data-id="@item.RecordId"
@*<a href="#" class="RemoveLink" data-id="@item.RecordId"
data-url='@Url.Content("~/ShoppingCart/RemoveFromCart")'>
Remove from cart
</a>
</a>*@
</td>
</tr>
}

View File

@ -1,5 +1,7 @@
@model MusicStore.Models.Genre
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Browse Albums";
}
<div class="genre">

View File

@ -1,6 +1,8 @@
@model MusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Album - " + Model.Title;
}

View File

@ -1,5 +1,7 @@
@model IEnumerable<MusicStore.Models.Genre>
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Store";
}
<h3>Browse Genres</h3>

View File

@ -2,6 +2,8 @@
@model MvcMusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Create";
}

View File

@ -2,6 +2,8 @@
@model MvcMusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Delete";
}

View File

@ -2,6 +2,8 @@
@model MvcMusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Details";
}

View File

@ -2,6 +2,8 @@
@model MvcMusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Edit";
}

View File

@ -14,6 +14,8 @@
}
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Index";
}

BIN
src/MusicStore/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -15,6 +15,7 @@
"Microsoft.AspNet.Mvc.Rendering": "0.1-alpha-*",
"Microsoft.AspNet.StaticFiles": "0.1-alpha-*",
"System.Security.Claims": "0.1-alpha-*",
"System.Security.Principal": "4.0.0.0",
"Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*",
"Microsoft.AspNet.Identity": "0.1-alpha-*",
"Microsoft.AspNet.Identity.Entity": "0.1-alpha-*",