Making a few more changes including:

1. Adding a view component
2. Adding more partial views from the sample and enabled a few of them.
3. Updating Account controller to accomodate all the recent identity changes.
4. Enabling some available Url helpers like Url.Content
5. Adding a ~ to all the scripts and images as this bug is fixed now.
This commit is contained in:
Praburaj 2014-04-04 17:19:27 -07:00
parent 4709bca281
commit 45e6e71bc8
34 changed files with 572 additions and 155 deletions

View File

@ -0,0 +1,29 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using MusicStore.Models;
namespace MusicStore.Components
{
[ViewComponent(Name = "GenreMenu")]
public class GenreMenuComponent : ViewComponent
{
private MusicStoreContext db = new MusicStoreContext();
public async Task<IViewComponentResult> InvokeAsync()
{
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
//var genres = db.Genres
//.OrderByDescending(
// g => g.Albums.Sum(
// a => a.OrderDetails.Sum(
// od => od.Quantity)))
//.Take(9)
//.ToList();
var genres = db.Genres.ToList();
return View(genres);
}
}
}

View File

@ -17,16 +17,16 @@ namespace MusicStore.Controllers
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>()))
: this(new UserManager<ApplicationUser>(new InMemoryUserStore<ApplicationUser>()))
{
}
public AccountController(UserManager<ApplicationUser, string> userManager)
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser, string> UserManager { get; private set; }
public UserManager<ApplicationUser> UserManager { get; private set; }
//
// GET: /Account/Login
@ -47,7 +47,7 @@ namespace MusicStore.Controllers
{
if (ModelState.IsValid == true)
{
var user = await UserManager.Find(model.UserName, model.Password);
var user = await UserManager.FindByUserNamePassword(model.UserName, model.Password);
if (user != null)
{
await SignIn(user, model.RememberMe);
@ -82,7 +82,7 @@ namespace MusicStore.Controllers
if (ModelState.IsValid == true)
{
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.Create(user, model.Password);
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignIn(user, isPersistent: false);
@ -108,7 +108,8 @@ namespace MusicStore.Controllers
{
ManageMessageId? message = null;
IdentityResult result = await UserManager.RemoveLogin(this.Context.User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
var user = new ApplicationUser() { UserName = this.Context.User.Identity.GetUserId() };
IdentityResult result = await UserManager.RemoveLogin(user, new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded)
{
message = ManageMessageId.RemoveLoginSuccess;
@ -155,7 +156,8 @@ namespace MusicStore.Controllers
{
if (ModelState.IsValid == true)
{
IdentityResult result = await UserManager.ChangePassword(this.Context.User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
var user = new ApplicationUser() { UserName = this.Context.User.Identity.GetUserId() };
IdentityResult result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
//Bug: No helper method
@ -181,7 +183,8 @@ namespace MusicStore.Controllers
if (ModelState.IsValid == true)
{
IdentityResult result = await UserManager.AddPassword(this.Context.User.Identity.GetUserId(), model.NewPassword);
var user = new ApplicationUser() { UserName = this.Context.User.Identity.GetUserId() };
IdentityResult result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
//Bug: No helper method
@ -224,7 +227,7 @@ namespace MusicStore.Controllers
}
// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.Find(loginInfo.Login);
var user = await UserManager.FindByLoginAsync(loginInfo.Login);
if (user != null)
{
await SignIn(user, isPersistent: false);
@ -261,7 +264,8 @@ namespace MusicStore.Controllers
//return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
return View();
}
var result = await UserManager.AddLogin(this.Context.User.Identity.GetUserId(), loginInfo.Login);
var user = new ApplicationUser() { UserName = this.Context.User.Identity.GetUserId()};
var result = await UserManager.AddLogin(user, loginInfo.Login);
if (result.Succeeded)
{
//Bug: No helper method
@ -298,10 +302,10 @@ namespace MusicStore.Controllers
}
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.Create(user);
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLogin(user.Id, info.Login);
result = await UserManager.AddLogin(user, info.Login);
if (result.Succeeded)
{
await SignIn(user, isPersistent: false);
@ -340,7 +344,8 @@ namespace MusicStore.Controllers
//[ChildActionOnly]
public async Task<IActionResult> RemoveAccountList()
{
var linkedAccounts = await UserManager.GetLogins(this.Context.User.Identity.GetUserId());
var user = new ApplicationUser() { UserName = this.Context.User.Identity.GetUserId() };
var linkedAccounts = await UserManager.GetLogins(user);
ViewBag.ShowRemoveButton = await HasPassword() || linkedAccounts.Count > 1;
//Bug: We dont have partial views yet
//return (IActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
@ -380,7 +385,7 @@ namespace MusicStore.Controllers
private async Task<bool> HasPassword()
{
var user = await UserManager.FindById(this.Context.User.Identity.GetUserId());
var user = await UserManager.FindByIdAsync(this.Context.User.Identity.GetUserId());
if (user != null)
{
return user.PasswordHash != null;

View File

@ -3,7 +3,7 @@ using MusicStore.Models;
using System.Collections.Generic;
using System.Linq;
namespace MvcMusicStore.Controllers
namespace MusicStore.Controllers
{
public class HomeController : Controller
{

View File

@ -84,9 +84,7 @@ namespace MusicStore.Controllers
DeleteId = id
};
//Bug: Missing helper
//return Json(results);
return new JsonResult(results);
return Json(results);
}
}
}

View File

@ -36,25 +36,11 @@ namespace MusicStore.Controllers
{
var album = 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.
album.Genre = db.Genres.Single(g => g.GenreId == album.GenreId);
album.Artist = db.Artists.Single(a => a.ArtistId == album.ArtistId);
return View(album);
}
///Bug: Missing [ChildActionOnly] attribute
//[ChildActionOnly]
public IActionResult GenreMenu()
{
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
var genres = db.Genres
.OrderByDescending(
g => g.Albums.Sum(
a => a.OrderDetails.Sum(
od => od.Quantity)))
.Take(9)
.ToList();
//Bug: Missing PartialView method.
//return PartialView(genres);
return View();
}
}
}

View File

@ -34,12 +34,17 @@ namespace MusicStore.Controllers
public IActionResult Details(int id = 0)
{
Album album = db.Albums.Single(a => a.AlbumId == id);
if (album == null)
{
//Bug: Need method HttpNotFound() on Controller
//return HttpNotFound();
return new HttpStatusCodeResult(404);
}
// 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);
}

View File

@ -1,32 +1,32 @@
{
"version": "0.1-alpha-*",
"dependencies": {
"Helios": "0.1-alpha-168",
"Microsoft.AspNet.Abstractions": "0.1-alpha-210",
"Microsoft.AspNet.Mvc": "0.1-alpha-449",
"Helios": "0.1-alpha-191",
"Microsoft.AspNet.Abstractions": "0.1-alpha-220",
"Microsoft.AspNet.Mvc": "0.1-alpha-490",
"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",
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-234",
"Microsoft.AspNet.RequestContainer": "0.1-alpha-213",
"Microsoft.AspNet.Routing": "0.1-alpha-195",
"Microsoft.AspNet.Mvc.ModelBinding": "0.1-alpha-490",
"Microsoft.AspNet.Mvc.Core": "0.1-alpha-490",
"Microsoft.AspNet.Mvc.Razor": "0.1-alpha-490",
"Microsoft.AspNet.Mvc.Rendering": "0.1-alpha-490",
"Microsoft.AspNet.StaticFiles": "0.1-alpha-158",
"System.Security.Claims": "0.1-alpha-103",
"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"
"Microsoft.AspNet.Identity": "0.1-alpha-264",
"Microsoft.AspNet.Identity.Entity": "0.1-alpha-264",
"Microsoft.AspNet.Identity.InMemory": "0.1-alpha-264",
"Microsoft.Data.Entity": "0.1-alpha-390",
"Microsoft.Data.Relational": "0.1-alpha-390",
"Microsoft.Data.SqlServer": "0.1-pre-390",
"Microsoft.Data.InMemory": "0.1-alpha-390",
"Microsoft.AspNet.Diagnostics": "0.1-alpha-094",
"Microsoft.AspNet.Hosting": "0.1-alpha-213",
"Microsoft.AspNet.Server.WebListener": "0.1-alpha-128"
},
"configurations": {
"net45": {

View File

@ -13,9 +13,7 @@ namespace MusicStore.Web.Models
{
public static class SampleData
{
//Bug: Currently a ~ in the url results in an razor exception: https://github.com/aspnet/WebFx/issues/66
//const string imgUrl = "~/Images/placeholder.png";
const string imgUrl = "/Images/placeholder.png";
const string imgUrl = "~/Images/placeholder.png";
public static void InitializeMusicStoreDatabase()
{

View File

@ -82,22 +82,22 @@ public class Startup
string _password = "YouShouldChangeThisPassword"; // configuration.Get("DefaultAdminPassword");
string _role = "Administrator";
var userManager = new UserManager<ApplicationUser, string>(new InMemoryUserStore<ApplicationUser>());
var roleManager = new RoleManager<InMemoryRole>(new InMemoryRoleStore());
var userManager = new UserManager<ApplicationUser>(new InMemoryUserStore<ApplicationUser>());
var roleManager = new RoleManager<InMemoryRole>(new InMemoryRoleStore<InMemoryRole>());
var role = new InMemoryRole(_role);
var result = await roleManager.RoleExists(_role);
var result = await roleManager.RoleExistsAsync(_role);
if (result == false)
{
await roleManager.Create(role);
await roleManager.CreateAsync(role);
}
var user = await userManager.FindByName(_username);
var user = await userManager.FindByNameAsync(_username);
if (user == null)
{
user = new ApplicationUser { UserName = _username };
await userManager.Create(user, _password);
await userManager.AddToRole(user.Id, _role);
await userManager.CreateAsync(user, _password);
await userManager.AddToRoleAsync(user, _role);
}
}
}

View File

@ -0,0 +1,36 @@
@model MusicStore.Models.ExternalLoginConfirmationViewModel
@{
ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
<h3>Associate your @ViewBag.LoginProvider account.</h3>
@using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Association Form</h4>
<hr />
@Html.ValidationSummary(true)
<p class="text-info">
You've successfully authenticated with <strong>@ViewBag.LoginProvider</strong>.
Please enter a user name for this site below and click the Register button to finish
logging in.
</p>
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.UserName)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

View File

@ -0,0 +1,8 @@
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Login Failure";
}
<h2>@ViewBag.Title.</h2>
<h3 class="text-error">Unsuccessful login with service.</h3>

View File

@ -0,0 +1,60 @@
@model MusicStore.Models.LoginViewModel
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Log in";
}
<h2>@ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.UserName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
<p>
@Html.ActionLink("Register", "Register") if you don't have a local account.
</p>
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
@Html.Partial("_ExternalLoginsListPartial", new { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

View File

@ -0,0 +1,31 @@
@using MusicStore.Models;
@using Microsoft.AspNet.Identity;
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Manage Account";
}
<h2>@ViewBag.Title.</h2>
<p class="text-success">@ViewBag.StatusMessage</p>
<div class="row">
<div class="col-md-12">
@if (ViewBag.HasLocalPassword)
{
@Html.Partial("_ChangePasswordPartial")
}
else
{
@Html.Partial("_SetPasswordPartial")
}
<section id="externalLogins">
@Html.Action("RemoveAccountList")
@Html.Partial("_ExternalLoginsListPartial", new { Action = "LinkLogin", ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

View File

@ -0,0 +1,43 @@
@model MusicStore.Models.RegisterViewModel
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

View File

@ -0,0 +1,36 @@
@using Microsoft.AspNet.Identity
@model MusicStore.Models.ManageUserViewModel
<p>You're logged in as <strong>@User.Identity.GetUserName()</strong>.</p>
@using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Change Password Form</h4>
<hr />
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Change password" class="btn btn-default" />
</div>
</div>
}

View File

@ -0,0 +1,33 @@
@using Microsoft.AspNet.Identity;
<h4>Use another service to log in.</h4>
<hr />
@{
var loginProviders = Context.HttpContext.GetAuthenticationTypes();
if (loginProviders.Count() == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
string action = Model.Action;
string returnUrl = Model.ReturnUrl;
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }))
{
@Html.AntiForgeryToken()
<div id="socialLoginList">
<p>
@foreach (AuthenticationDescription p in loginProviders)
{
<button type="submit" class="btn btn-default" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">@p.AuthenticationType</button>
}
</p>
</div>
}
}
}

View File

@ -0,0 +1,34 @@
@model ICollection<microsoft.aspnet.identity.userlogininfo>
@if (Model.Count > 0)
{
<h4>Registered Logins</h4>
<table class="table">
<tbody>
@foreach (var account in Model)
{
<tr>
<td>@account.LoginProvider</td>
<td>
@if (ViewBag.ShowRemoveButton)
{
using (Html.BeginForm("Disassociate", "Account"))
{
@Html.AntiForgeryToken()
<div>
@Html.Hidden("loginProvider", account.LoginProvider)
@Html.Hidden("providerKey", account.ProviderKey)
<input type="submit" class="btn btn-default" value="Remove" title="Remove this @account.LoginProvider login from your account" />
</div>
}
}
else
{
@: &nbsp;
}
</td>
</tr>
}
</tbody>
</table>
}

View File

@ -0,0 +1,32 @@
@model MusicStore.Models.ManageUserViewModel
<p class="text-info">
You do not have a local username/password for this site. Add a local
account so you can log in without an external login.
</p>
@using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Create Local Login</h4>
<hr />
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Set password" class="btn btn-default" />
</div>
</div>
}

View File

@ -0,0 +1,35 @@
@model MusicStore.Models.Order
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Address And Payment";
}
@section Scripts {
@*@Scripts.Render("~/bundles/jqueryval")*@
}
@*@using (Html.BeginForm())*@
@*{*@
<h2>Address And Payment</h2>
<fieldset>
<legend>Shipping Information</legend>
@*@Html.EditorForModel()*@
</fieldset>
<fieldset>
<legend>Payment</legend>
<p>We're running a promotion: all music is free with the promo code: "FREE"</p>
<div class="editor-label">
@*@Html.Label("Promo Code")*@
</div>
<div class="editor-field">
@Html.TextBox("PromoCode")
</div>
</fieldset>
<input type="submit" value="Submit Order" />
@*}*@

View File

@ -0,0 +1,16 @@
@model int
@{
//Bug: Need to have a way to specify an application level layout page
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Checkout Complete";
}
<h2>Checkout Complete</h2>
<p>Thanks for your order! Your order number is: @Model</p>
<p>
How about shopping for some more music in our
@*@Html.ActionLink("Store", "Index", "Home")*@
</p>

View File

@ -1,23 +1,20 @@
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>MVC Music Store</h1>
@*Bug: Having a ~ in url throws compilation error : https://github.com/aspnet/WebFx/issues/66*@
<img src="/Images/home-showcase.png" />
<img src="~/Images/home-showcase.png" />
</div>
<ul class="row list-unstyled" id="album-list">
@foreach (var album in Model)
{
<li class="col-lg-2 col-md-2 col-sm-2 col-xs-4 container">
<a href="@Url.Action("Details", "Store", new { id = album.AlbumId })">
@*Bug: Url helpers not implemented yet*@
@*<img alt="@album.Title" src="@Url.Content(@album.AlbumArtUrl)" />*@
<img alt="@album.Title" src="@album.AlbumArtUrl" />
<img alt="@album.Title" src="@Url.Content(@album.AlbumArtUrl)" />
<h4>@album.Title</h4>
</a>
</li>

View File

@ -0,0 +1,25 @@
@model IEnumerable<MusicStore.Models.Genre>
<li class="dropdown">
<a href="@Url.Action("Store")" class="dropdown-toggle" data-toggle="dropdown">Store <b class="caret"></b></a>
<ul class="dropdown-menu">
@foreach (var genre in Model)
{
@*<li>
@Html.ActionLink(genre.Name,
"Browse", "Store",
new { Genre = genre.Name }, null)
</li>*@
<li>
<a href="@Url.Action("Browse", "Store", new { Genre = genre.Name })">@genre.Name</a>
</li>
}
<li class="divider"></li>
<li>
@*@Html.ActionLink("More...", "Index", "Store")*@
<a href="@Url.Action("Index", "Store")">More...</a>
</li>
</li>
</ul>
</li>

View File

@ -0,0 +1,8 @@
@{
//Bug: Need a way to specify the layout page in a single place
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

View File

@ -8,9 +8,9 @@
@*Bug: No Style and Script helpers yet. Manually including the script files*@
@*@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")*@
<link rel="stylesheet" href="/Content/bootstrap.min.css" />
<link rel="stylesheet" href="/Content/Site.css" />
<script type="text/javascript" src="/Scripts/modernizr-2.6.2.js"></script>
<link rel="stylesheet" href="~/Content/bootstrap.min.css" />
<link rel="stylesheet" href="~/Content/Site.css" />
<script type="text/javascript" src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
@ -23,17 +23,17 @@
</button>
@*Bug: no Html helpers yet*@
@*@Html.ActionLink("ASP.NET MVC Music Store", "Index", "Home", null, new { @class = "navbar-brand" })*@
<a class="navbar-brand" href="/">ASP.NET MVC Music Store</a>
<a class="navbar-brand" href="~/">ASP.NET MVC Music Store</a>
</div>
@*Bug: HtmlHelpers missing*@
@*<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
@Html.Action("GenreMenu", "Store")
@Html.Action("CartSummary", "ShoppingCart")
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@*<li>@Html.ActionLink("Home", "Index", "Home")</li>*@
@await Component.InvokeAsync("GenreMenu")
@* @Html.Action("CartSummary", "ShoppingCart")*@
</ul>
@Html.Partial("_LoginPartial")
</div>*@
@await Html.PartialAsync("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@ -51,8 +51,8 @@
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)*@
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/bootstrap.js"></script>
<script src="~/Scripts/respond.js"></script>
</body>
</html>

View File

@ -0,0 +1,25 @@
@using Microsoft.AspNet.Identity;
@if (Context.HttpContext.User != null && Context.HttpContext.User.Identity.IsAuthenticated)
{
@*using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}*@
}
else
{
<ul class="nav navbar-nav navbar-right">
@*<li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
<li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>*@
<li>Register</li>
<li>Log in</li>
</ul>
}

View File

@ -5,7 +5,7 @@
ViewBag.Title = "Shopping Cart";
}
@*//@section Scripts {*@
@section Scripts {
<script type="text/javascript">
$(function () {
// Document.ready -> link up remove event handler
@ -35,7 +35,7 @@
});
</script>
@*}*@
}
<h3>
<em>Review</em> your cart:
@ -72,10 +72,10 @@
@item.Count
</td>
<td>
@*<a href="#" class="RemoveLink" data-id="@item.RecordId"
data-url='@Url.Content("~/ShoppingCart/RemoveFromCart")'>
Remove from cart
</a>*@
<a href="#" class="RemoveLink" data-id="@item.CartItemId"
data-url='@Url.Content("~/ShoppingCart/RemoveFromCart")'>
Remove from cart
</a>
</td>
</tr>
}

View File

@ -8,7 +8,7 @@
<h3>
<em>@Model.Name</em> Albums
</h3>
<ul id="album-list" class="list-unstyled">
@foreach (var album in Model.Albums)
{
@ -16,9 +16,7 @@
<a href="@Url.Action("Details", new { id = album.AlbumId })">
@if (!string.IsNullOrEmpty(album.AlbumArtUrl))
{
@*Bug: Url helpers not implemented yet*@
@*<img alt="@album.Title" src="@Url.Content(@album.AlbumArtUrl)" />*@
<img alt="@album.Title" src="@album.AlbumArtUrl" />
<img alt="@album.Title" src="@Url.Content(@album.AlbumArtUrl)" />
}
<h5 class="control-label">@album.Title</h5>
</a>

View File

@ -9,9 +9,7 @@
<h2>@Model.Title</h2>
<p>
@*Bug: Url helpers not implemented yet*@
@*<img alt="@Model.Title" src="@Url.Content(@Model.AlbumArtUrl)" />*@
<img alt="@Model.Title" src="@Model.AlbumArtUrl" />
<img alt="@Model.Title" src="@Url.Content(@Model.AlbumArtUrl)" />
</p>
<div id="album-details">
@ -25,8 +23,7 @@
</p>
<p>
<em>Price:</em>
@*Bug: HTML helpers not implemented yet*@
@*@Html.DisplayFor(model => model.Price)*@
@Html.ValueFor(model => model.Price)
</p>
<p class="button">
@*Bug: HTML helpers not implemented yet*@

View File

@ -1,21 +0,0 @@
@*Bug: intellisense changes the case of the type. Need to use a normal text editor to edit this view.
Bug: Child actions not implemented yet*@
@*@model System.Collections.Generic.IEnumerable<mvcmusicstore.models.genre>*@
<li class="dropdown">
<a href="@Url.Action("Store")" class="dropdown-toggle" data-toggle="dropdown">Store <b class="caret"></b></a>
<ul class="dropdown-menu">
@foreach (var genre in Model)
{
<li>
@Html.ActionLink(genre.Name,
"Browse", "Store",
new { Genre = genre.Name }, null)
</li>
}
<li class="divider"></li>
<li>
@Html.ActionLink("More...", "Index", "Store")
</li>
</ul>
</li>

View File

@ -1,5 +1,5 @@
@*Bug: Fully dependent on HTML helpers*@
@model MvcMusicStore.Models.Album
@model MusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page

View File

@ -1,5 +1,5 @@
@*Bug: Dependent on Htmlhelpers*@
@model MvcMusicStore.Models.Album
@model MusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page

View File

@ -1,5 +1,4 @@
@*Bug: Dependent on Htmlhelpers*@
@model MvcMusicStore.Models.Album
@model MusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page
@ -14,48 +13,49 @@
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Artist.Name)
@Html.NameFor(model => model.Artist.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Artist.Name)
@Html.ValueFor(model => model.Artist.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Genre.Name)
@Html.NameFor(model => model.Genre.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Genre.Name)
@Html.ValueFor(model => model.Genre.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Title)
@Html.NameFor(model => model.Title)
</dt>
<dd>
@Html.DisplayFor(model => model.Title)
@Html.ValueFor(model => model.Title)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Price)
@Html.NameFor(model => model.Price)
</dt>
<dd>
@Html.DisplayFor(model => model.Price)
@Html.ValueFor(model => model.Price)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AlbumArtUrl)
@Html.NameFor(model => model.AlbumArtUrl)
</dt>
<dd>
@Html.DisplayFor(model => model.AlbumArtUrl)
@Html.ValueFor(model => model.AlbumArtUrl)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.AlbumId }) |
@Html.ActionLink("Back to List", "Index")
</p>
@*Bug: Need HtmlHelpers*@
@*<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.AlbumId }) |
@Html.ActionLink("Back to List", "Index")
</p>*@

View File

@ -1,5 +1,4 @@
@*Bug: Dependent on Htmlhelpers*@
@model MvcMusicStore.Models.Album
@model MusicStore.Models.Album
@{
//Bug: Need to have a way to specify an application level layout page

View File

@ -1,5 +1,4 @@
@*Bug: Dependent on Htmlhelpers*@
@model IEnumerable<mvcmusicstore.models.album>
@model IEnumerable<MusicStore.Models.Album>
@helper Truncate(string input, int length)
{
@ -22,21 +21,26 @@
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@*@Html.ActionLink("Create New", "Create")*@
</p>
<table class="table">
@*Bug: Html.NameFor does not contain an overload taking in IEnumerable<Tmodel>*@
<tr>
<th>
@Html.DisplayNameFor(model => model.Genre.Name)
@*@Html.NameFor(model => model.Genre.Name)*@
@Html.NameFor(model => model.FirstOrDefault().Genre.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Artist.Name)
@*@Html.NameFor(model => model.Artist.Name)*@
@Html.NameFor(model => model.FirstOrDefault().Artist.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Title)
@*@Html.NameFor(model => model.Title)*@
@Html.NameFor(model => model.FirstOrDefault().Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
@*@Html.NameFor(model => model.Price)*@
@Html.NameFor(model => model.FirstOrDefault().Price)
</th>
<th></th>
</tr>
@ -45,7 +49,7 @@
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre.Name)
@Html.ValueFor(modelItem => item.Genre.Name)
</td>
<td>
@Truncate(item.Artist.Name, 25)
@ -54,13 +58,13 @@
@Truncate(item.Title, 25)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
@Html.ValueFor(modelItem => item.Price)
</td>
<td>
@*<td>
@Html.ActionLink("Edit", "Edit", new { id = item.AlbumId }) |
@Html.ActionLink("Details", "Details", new { id = item.AlbumId }) |
@Html.ActionLink("Delete", "Delete", new { id = item.AlbumId })
</td>
</td>*@
</tr>
}