第十话 Asp.Net MVC 3.0 【MVC项目实战の六】
今天主要演示的就是前面项目的后台功能的开发,在后台我们搞了一个上传图片的功能,具体的下面开始!(这次东东可能有点多,想学习的同学可要耐心的看哦!)
考虑到是我们需要搞一个图片上传的功能,所以我们的表肯定也添加新的字段等;还有我们后台要有区别于前台的模版等!接下来就一步一步的完善吧!
首先添加管理目录,我们习惯用下面的页面来管理我们的数据,如下图1.
图1.这是一个CRUD的草图(CRUD:它代表创建(Create)、更新(Update)、读取(Read)和删除(Delete)操作,这里是简称)。
接下来创建一个CURD的Controller(控制器),在我们的Web项目的Controllers文件夹下创建,如下图2.
图2.命名为"AdminController",具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { [Authorize] public class AdminController : Controller { private IProductRepository repository; public AdminController(IProductRepository repo) { this.repository = repo; } /// <summary> /// 展示商品列表页面 /// </summary> /// <returns>商品的列表</returns> public ViewResult Index() { return this.View(this.repository.Products); } } }
这里我们写了一个很简单的Index Action(方法),现在先开始弄一个简单的后台页面出来,我们创建一个相应的视图!哦,忘了。我们后台又有却别于前台的模版页面,所以我们新建一个模版页面如下图3.
图3.(在们web项目的Views/Shared文件夹下创建),创建好我们对模版修改如下:
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Admin.css")" rel="Stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> </head> <body> <div> @if (TempData["message"]!=null) { <div class="Message">@TempData["Message"]</div> } @RenderBody() </div> </body> </html>
蓝色加粗部分是我们的后台样式,具体代码如下;红色加粗部分引入的JS是为了验证客户端数据;粉红色加粗部分则是一个提示信息的预留位置。
后台样式我们在web项目的Content文件下创建,具体样式如下:
BODY, TD { font-family: Segoe UI, Verdana } H1 { padding: .5em; padding-top: 0; font-weight: bold; font-size: 1.5em; border-bottom: 2px solid gray; } DIV#content { padding: .9em; } TABLE.Grid TD, TABLE.Grid TH { border-bottom: 1px dotted gray; text-align:left; } TABLE.Grid { border-collapse: collapse; width:100%; } TABLE.Grid TH.NumericCol, Table.Grid TD.NumericCol { text-align: right; padding-right: 1em; } FORM {margin-bottom: 0px; } DIV.Message { background: gray; color:White; padding: .2em; margin-top:.25em; } .field-validation-error { color: red; display: block; } .field-validation-valid { display: none; } .input-validation-error { border: 1px solid red; background-color: #ffeeee; } .validation-summary-errors { font-weight: bold; color: red; } .validation-summary-valid { display: none; } .editor-field { margin-bottom: .8em; } .editor-label { font-weight: bold; } .editor-label:after { content: ":" } .text-box { width: 25em; } .multi-line { height: 5em; font-family: Segoe UI, Verdana; }
OK!现在回到我们的AdminController里面来,创建我们的List展示页面,具体如下图4.
图4.建立好Index.cshtml页面,修改它的代码如下:
@model IEnumerable<SportsStore.Domain.Entities.Product> @{ ViewBag.Title = "Administration All Index"; Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h1>Administration All Index</h1> <p> @Html.ActionLink("Create New", "Create") </p> <table class="Grid"> <tr> <th>ID</th> <th>Name</th> <th class="NumericCol">Price</th> <th>Actions</th> </tr> @foreach (var item in Model) { <tr> <td>@item.ProductID</td> <td>@Html.ActionLink(item.Name, "Edit", new { item.ProductID })</td> <td class="NumericCol">@item.Price.ToString("c")</td> <td> @using (Html.BeginForm("Delete", "Admin")) { @Html.Hidden("ProductID", item.ProductID) <input type="submit" value="Delete"/> } </td> </tr> } </table> <p>@Html.ActionLink("Add a New Product","Create")</p>
写完这个我们运行一下我们的项目,结果如下图5.(因为这个跟前台没有直接关联,所以写完需要我们拼写它的路径也就是你想看页面的Controller/Index的URL方式)。
图5.这个后台一个简单的展示页面,他现在只具备列出我们所有商品,像新建,编辑,删除的功能还不存在。接下来一并搞这个三个功能,都是在我们的AdminController控制器里完成,首先来看编辑和新建功能。
一个编辑功能应该是管理者可以修改商品的属性(信息)等,接下来我们在AdminController添加一个编辑功能,具体代码如下:
/// <summary> /// 编辑方法 /// </summary> /// <param name="productId">商品的ID</param> /// <returns>编辑后的商品</returns> public ViewResult Edit(int productId) { Product product = this.repository.Products.FirstOrDefault(h => h.ProductID == productId); return this.View(product); }
接着我们创建Edit Action(方法)对应的视图页面,具体如下图6(我们在这里还继续使用强类型数据模型).
图6.创建完Edit.cshtml后,我们修改他如下:
@model SportsStore.Domain.Entities.Product @{ ViewBag.Title = "Admin:Edit" + @Model.Name; Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h1>Admin Edit @Model.Name</h1> @using (Html.BeginForm()) { @Html.EditorForModel() <input type="submit" value="Save" /> @Html.ActionLink("Cancel And Return To List", "Index") }
上面红色加粗部分@Html.EditorForModel()是一个复制方法,MVC框架会自动检测创建编辑窗口,运行可以看到效果如下图7.
图7.我们一般习惯在编辑的时候,不让编辑ProductID这个属性,还有我们的描述相比其他的字体应该更小点。我们可以在这里试着用一下"模型元数据"(model metadata)这个后面在做讲解,修改我们Product的实体类如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; namespace SportsStore.Domain.Entities { public class Product : Object { [HiddenInput(DisplayValue = false)] public int ProductID { get; set; } public string Name { get; set; } [DataType(DataType.MultilineText)] public string Description { get; set; } public decimal Price { get; set; } public string Category { get; set; } } }
在MVC框架里HiddenInput会是呈现的属性隐藏起来,DataType给定我们一个值允许我们执行相应的编辑。添加玩属性后在运行我们的项目如下图8.
图8.我们之前编辑的商品信息,怎么保存到储存卡呢!我们需要在IProductRepository接口添加保存的方法,这是在需要保存的地方调用方法即可;所以我们修改IProductRepository接口如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SportsStore.Domain.Entities; namespace SportsStore.Domain.Abstract { public interface IProductRepository { IQueryable<Product> Products { get; } //保存商品 void SaveProduct(Product product); } }
接着我们需要在EFProductRepository类里实现他,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SportsStore.Domain.Abstract; using System.Data.Entity; using SportsStore.Domain.Entities; namespace SportsStore.Domain.Concrete { public class EFProductRepository : IProductRepository { private EFDbContext context = new EFDbContext(); public IQueryable<Product> Products { get { return this.context.Products; } } //实现接口里保存商品的方法 public void SaveProduct(Product product) { //不存在商品就新增 if (product.ProductID == 0) { this.context.Products.Add(product); } this.context.SaveChanges(); } } //EFDbContext类可以使简单数据模型与数据库交互 public class EFDbContext : DbContext { public DbSet<Product> Products { get; set; } } }
接下来我们实现Edit Action(方法)的Post提交处理,具体代码如下:
[HttpPost] public ActionResult Edit(Product product) { if (ModelState.IsValid) { this.repository.SaveProduct(product); //设置临时字典 TempData["message"] = string.Format("{0} Has Been Saved", product.Name); return this.View(product); //.RedirectToAction("Index"); } }
我们检查模型绑定器已经能够验证用户提交的数据。如果一切OK,我们就可以保存到储存库里面。
然后我们更新一下一条信息看看效果,运行如下图9.
图9.因为在这里我们建立的模版里留着提示消息的位置,使用TempData来显示消息,TempData会自动获取传递的字典数据,而且他会自动销毁数据,我们只要从新刷新页面他就会销毁当前传递的数据。
接下来我们需要添加模型验证,就目前而言,我们编辑的时候,价格可以输入负值,商品描述为空等都可以保存,而这些是不允许,所以我们需要给我们的商品模型添加验证属性,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.ComponentModel.DataAnnotations; namespace SportsStore.Domain.Entities { public class Product : Object { [HiddenInput(DisplayValue = false)] public int ProductID { get; set; } [Required(ErrorMessage = "Please enter a product name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter a description")] [DataType(DataType.MultilineText)] public string Description { get; set; } [Required] [Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")] public decimal Price { get; set; } [Required(ErrorMessage = "Please specify a category")] public string Category { get; set; } public byte[] ImageData { get; set; } [HiddenInput(DisplayValue = false)] public string ImageMimeType { get; set; } } }
添加验证特性后,我们运行项目如果输入错误的话,会有相应的提示,如下图10.
图10.
然后我们实现新建商品功能,在AdminController里添加Create Action(方法),具体代码如下:
/// <summary> /// 创建商品 /// </summary> /// <returns>新的商品</returns> public ViewResult Create() { return this.View("Edit", new Product()); }
我们这里没有返回默认视图,而是指定到Edit Action(方法),我们试着显示指定在别的Controller控制器和Action方法来搞搞。修改我们的编辑(Edit.cshtml)页面如下:
@model SportsStore.Domain.Entities.Product @{ ViewBag.Title = "Admin:Edit" + @Model.Name; Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h1>Admin Edit @Model.Name</h1> @using (Html.BeginForm("Edit", "Admin")) { @Html.EditorForModel() <input type="submit" value="Save" /> @Html.ActionLink("Cancel And Return To List", "Index") }
试着运行我们的项目如下图10。
图10我们新建的商品信息,然后接续我们的删除操作。和保存一样我们在IProductRepository接口里定义删除的方法如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SportsStore.Domain.Entities; namespace SportsStore.Domain.Abstract { public interface IProductRepository { IQueryable<Product> Products { get; } //保存商品 void SaveProduct(Product product); //删除商品 void DeleteProduct(Product product); } }
接着我们在EFProductRepository类里实现上面定义的删除方法,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SportsStore.Domain.Abstract; using System.Data.Entity; using SportsStore.Domain.Entities; namespace SportsStore.Domain.Concrete { public class EFProductRepository : IProductRepository { private EFDbContext context = new EFDbContext(); public IQueryable<Product> Products { get { return this.context.Products; } } //实现接口里保存商品的方法 public void SaveProduct(Product product) { //不存在商品就新增 if (product.ProductID == 0) { this.context.Products.Add(product); } this.context.SaveChanges(); } //实现接口的删除商品的方法 public void DeleteProduct(Product product) { this.context.Products.Remove(product); this.context.SaveChanges(); } } //EFDbContext类可以使简单数据模型与数据库交互 public class EFDbContext : DbContext { public DbSet<Product> Products { get; set; } } }
然后继续在AdminController里添加我们的删除功能,具体代码如下:
/// <summary> /// 删除商品 /// </summary> /// <param name="productID">商品的ID</param> /// <returns>URL从新指向列表</returns> [HttpPost] public ActionResult Delete(int productId) { Product prod = this.repository.Products.FirstOrDefault(h => h.ProductID == productId); if (prod!=null) { this.repository.DeleteProduct(prod); TempData["message"] = string.Format("{0} Was Deleted", prod.Name); } return this.RedirectToAction("Index"); }
搞完删除运行一下我们的项目,试试删除功能,具体如下图11.
图11.(删除了ID为15的信息)我们的后台应该有一个简单的登录页面,做也要做个样子吗?简单的搞搞我们只要说明那么回事。Asp.Net MVC是建立在Asp.Net核心平台上的,所以我们可以访问Asp.Net Form验证的功能,这也是一个比较通用的功能。只有登录成功的人才能操作后台。关于From验证我们配置我们项目的Web.Config如下:
...... <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880"> <credentials passwordFormat="Clear"> <user name="admin" password="123" /> </credentials> </forms> </authentication> .......
MVC框架有一个非常强大的功能称为Filters。这些都是Attributes,应用到一个Action方法或Controller类。当一个请求被处理的时候,这些Attributes引入了额外的逻辑。我们也可以定义自己的Filter。接下来给我们AdminController添加Filters(过滤器吧)!具体操作如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { [Authorize] public class AdminController : Controller { private IProductRepository repository; public AdminController(IProductRepository repo) { this.repository = repo; } .......
添加了Filters(过滤器),然后我们在运行项目,结果如下图12.
图12.这就是我们使用Filters(过滤器)的结果。接下来我们需要一个验证者(程序),我们首先定义,身份验证提供者接口,在我们Web项目的Infrastructure/Abstract文件夹下创建接口("IAuthProvider"),具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SportsStore.WebUI.Infrastructure.Abstract { public interface IAuthProvider { bool Authenticate(string username, string password); } }
接着在Infrastructure文件夹里面再创建一个Concrete文件夹,添加一个实现类FormsAuthProvider,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using SportsStore.WebUI.Infrastructure.Abstract; using System.Web.Security; namespace SportsStore.WebUI.Infrastructure.Concrete { public class FormsAuthProvider : IAuthProvider { public bool Authenticate(string username, string password) { bool result = FormsAuthentication.Authenticate(username, password); if (result) { FormsAuthentication.SetAuthCookie(username, false); } return result; } } }
然后在NinjectControllerFactory里面使用Ninject绑定,具体代码如下:
private void AddBindings() { //绑定额外数据 this.ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>(); EmailSettings emailSettings = new EmailSettings { WriteAsFile = bool.Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ?? "false") }; this.ninjectKernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>() .WithConstructorArgument("settings", emailSettings); //添加身份验证 this.ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>(); }
然后我们需要创建一个登录的视图模型类("LogOnViewModel")为了传递数据,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace SportsStore.WebUI.Models { public class LogOnViewModel { [Required] public string UserName { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } } }
然后在项目添加AccountController控制器类,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.WebUI.Infrastructure.Abstract; using SportsStore.WebUI.Models; namespace SportsStore.WebUI.Controllers { public class AccountController : Controller { IAuthProvider authProvider; public AccountController(IAuthProvider auth) { this.authProvider = auth; } /// <summary> /// 登录页面 /// </summary> /// <returns>View</returns> public ViewResult LogOn() { return this.View(); } /// <summary> /// Post请求登录页面 /// </summary> [HttpPost] public ActionResult LogOn(LogOnViewModel model, string returnUrl) { if (ModelState.IsValid) { if (this.authProvider.Authenticate(model.UserName, model.Password)) { return this.Redirect(returnUrl ?? Url.Action("Index", "Admin")); } else { ModelState.AddModelError("", "Incorrect username or password"); return this.View(); } } else { return this.View(); } } } }
接着,我们创建LogOn的视图,如下图13.
图13.创建好LogOn.cshtml页面后,具体代码如下:
@model SportsStore.WebUI.Models.LogOnViewModel @{ ViewBag.Title = "Admin:LogOn"; Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h1>Log In</h1> <p>Please log in to access the administrative area:</p> @using (Html.BeginForm()) { @Html.ValidationSummary(true) @Html.EditorForModel() <p><input type="submit" value="Log In" /></p> }
添加好我们的登录页面,运行程序如下图14.
图16.(这里只有输入我们在Web.comfig文件里配置的帐号密码方可登录进去)。接下来搞我们最后一个功能图片上传功能。首先我们必须给我们的数据表里面添加新的字段,具体如下图17.
图17.更改数据表,我们也要同步到我们的域模型,修改我们的Product模型如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.ComponentModel.DataAnnotations; namespace SportsStore.Domain.Entities { public class Product : Object { [HiddenInput(DisplayValue = false)] public int ProductID { get; set; } [Required(ErrorMessage = "Please enter a product name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter a description")] [DataType(DataType.MultilineText)] public string Description { get; set; } [Required] [Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")] public decimal Price { get; set; } [Required(ErrorMessage = "Please specify a category")] public string Category { get; set; } public byte[] ImageData { get; set; } [HiddenInput(DisplayValue = false)] public string ImageMimeType { get; set; } } }
然后我们需要跟新到我们的实体模型,如给你给项目添加了数据模型,打开运行"自定义功能",VS就会自动帮你同步的,我这没有用数据模型的(*.edmx),所以我这里只需要更新域模型即可。创建用户的上传界面,上传图片习惯应该在编辑页面,所以修改我们的Edit.cshtml页面,代码如下:
@model SportsStore.Domain.Entities.Product @{ ViewBag.Title = "Admin:Edit" + @Model.Name; Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h1>Admin Edit @Model.Name</h1> @using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.EditorForModel() <div class="editor-label">Image</div> <div class="editor-field"> @if (Model.ImageData == null) { @:None } else { <img width="150" height="150" src="@Url.Action("GetImage", "Product", new { Model.ProductID })" /> } <div>Upload new image:<input type="file" name="Image" /></div> </div> <input type="submit" value="Save" /> @Html.ActionLink("Cancel And Return To List", "Index") }
接下来我们需要在AdminController的Edit Action(方法)保存我们的图片数据,具体修改如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { [Authorize] public class AdminController : Controller { private IProductRepository repository; public AdminController(IProductRepository repo) { this.repository = repo; } /// <summary> /// 展示商品列表页面 /// </summary> /// <returns>商品的列表</returns> public ViewResult Index() { return this.View(this.repository.Products); } /// <summary> /// 编辑方法 /// </summary> /// <param name="productId">商品的ID</param> /// <returns>编辑后的商品</returns> public ViewResult Edit(int productId) { Product product = this.repository.Products.FirstOrDefault(h => h.ProductID == productId); return this.View(product); } [HttpPost] public ActionResult Edit(Product product, HttpPostedFileBase image) { if (ModelState.IsValid) { if (image != null) { product.ImageMimeType = image.ContentType; product.ImageData = new byte[image.ContentLength]; image.InputStream.Read(product.ImageData, 0, image.ContentLength); } this.repository.SaveProduct(product); //设置临时字典 TempData["message"] = string.Format("{0} Has Been Saved", product.Name); return this.View(product); //.RedirectToAction("Index"); } } /// <summary> /// 创建商品 /// </summary> /// <returns>新的商品</returns> public ViewResult Create() { return this.View("Edit", new Product()); } /// <summary> /// 删除商品 /// </summary> /// <param name="productID">商品的ID</param> /// <returns>URL从新指向列表</returns> [HttpPost] public ActionResult Delete(int productId) { Product prod = this.repository.Products.FirstOrDefault(h => h.ProductID == productId); if (prod!=null) { this.repository.DeleteProduct(prod); TempData["message"] = string.Format("{0} Was Deleted", prod.Name); } return this.RedirectToAction("Index"); } } }
OK,我们貌似还需要一个取出存贮图片的方法,在我们的ProductOntroller里添加GetImage Action(方法),具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using SportsStore.Domain.Abstract; using SportsStore.Domain.Concrete; using SportsStore.WebUI.Models; using SportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { public class ProductController : Controller { public int PageSize = 4; //设置一页显示多少商品 private IProductRepository repository; public ProductController(IProductRepository productReposittory) { this.repository = productReposittory; } //返回一个视图 public ViewResult List(string category, int page = 1) { ProductsListViewModel viewModel = new ProductsListViewModel { Products = this.repository.Products .Where(h => category == null || h.Category == category) .OrderBy(h => h.ProductID) .Skip((page - 1) * PageSize) .Take(PageSize), PagingInfo = new PagingInfo { CurrentPage = page, ItemsPerPage = PageSize, TotalItems = category == null ? this.repository.Products.Count() : this.repository.Products.Where(h => h.Category == category).Count() }, CurrentCategory = category }; return this.View(viewModel); } //获取图片的方法 public FileContentResult GetImage(int productId) { Product prod = this.repository.Products.FirstOrDefault(h => h.ProductID == productId); if (prod != null) { return File(prod.ImageData, prod.ImageMimeType); } else { return null; } } } }
还记得我们在("EFProductRepository")实现保存方法的时候,我们只考虑到不存在商品的情况,也就是我们实际上就无法修改商品,现在我们在实现他商品存在修改的情况,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SportsStore.Domain.Abstract; using System.Data.Entity; using SportsStore.Domain.Entities; namespace SportsStore.Domain.Concrete { public class EFProductRepository : IProductRepository { private EFDbContext context = new EFDbContext(); public IQueryable<Product> Products { get { return this.context.Products; } } //实现接口里保存商品的方法 public void SaveProduct(Product product) { //不存在商品就新增 if (product.ProductID == 0) { this.context.Products.Add(product); } else { //存在则修改 this.context.Products.Attach(product); //EntityFramwork4.0修改的写法 //this.context.ObjectStateManager.ChangeObjectState(product, System.Data.EntityState.Modified); //EntityFramwork4.1修改的写法 this.context.Entry(product).State = System.Data.EntityState.Modified; } this.context.SaveChanges(); } //实现接口的删除商品的方法 public void DeleteProduct(Product product) { this.context.Products.Remove(product); this.context.SaveChanges(); } } //EFDbContext类可以使简单数据模型与数据库交互 public class EFDbContext : DbContext { public DbSet<Product> Products { get; set; } } }
然后运行一下我们的Web程序,看看我们的上传功能到时是否OK。运行结果如下图18.
图17.OK说明我们的上传已经是没有问题的了!我们在后台上传图片前台肯定也需要一块地方展示商品图片,还还记我们的前台展示商品列表的页面好像用的是一个局部视图,那么我们就在这块局部视图中给商品图片分配一块位置,修改ProductSummary.cshtml页面,具体如下:
@model SportsStore.Domain.Entities.Product @{ ViewBag.Title = "ProductSummary"; } <div class="item"> @if (Model.ImageData != null) { <div style="float:left;margin-right:20px"> <img width="75" height="75" src="@Url.Action("GetImage", "Product", new { Model.ProductID })" /> </div> } <h3>@Model.Name</h3> @Model.Description @using (Html.BeginForm("AddToCart","Cart")) { @Html.HiddenFor(h=>h.ProductID) @Html.Hidden("returnUrl",this.Request.Url.PathAndQuery) <input type="submit" value="+ Add to cart" /> } <h4>@Model.Price.ToString("C")</h4> </div>
在前台分配好商品展示的地方,在后台上传好商品的图片然后运行,前台页面,运行结果如下图18.
图18.今天的后台就实战到这里,我的简单的购物流程也就暂时搞一个阶段了,后续我们在继续深入的学习MVC,几天的这篇文章写的真的很仓促,要是那里有写错还是描述错误的地方,还请各位前辈朋友多多批评指导,大家共同进步啊!在此,深表明哥指导学习。