CMS是Content Management System的缩写,意为“内容管理系统”。在前面我们开发了基本界面和基本功能页面,点击这里查看文章。
这一节,我们将完成所有的功能。先用户管理控制器:UsersAdmin,再完成角色管理控制器:RolesAdmin。最后再完成用户评论,用户评论将在Details 页面中显示出来,并且对登录用户显示文本框可以输入评论,难度略有提高。
新建控制器:UsersAdmin
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using AxCMS.Models;
namespace AxCMS.Controllers
{
[Authorize(Roles = "Admin")]
public class UsersAdminController : Controller
{
public UsersAdminController()
{
}
public UsersAdminController(ApplicationUserManager userManager, ApplicationRoleManager roleManager)
{
UserManager = userManager;
RoleManager = roleManager;
}
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager
{
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
private set
{
_roleManager = value;
}
}
//
// GET: /Users/
public async Task<ActionResult> Index()
{
return View(await UserManager.Users.ToListAsync());
}
//
// GET: /Users/Details/5
public async Task<ActionResult> Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
ViewBag.RoleNames = await UserManager.GetRolesAsync(user.Id);
return View(user);
}
//
// GET: /Users/Create
public async Task<ActionResult> Create()
{
//Get the list of Roles
ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
return View();
}
//
// POST: /Users/Create
[HttpPost]
public async Task<ActionResult> Create(RegisterViewModel userViewModel, params string[] selectedRoles)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = userViewModel.Email, Email = userViewModel.Email };
var adminresult = await UserManager.CreateAsync(user, userViewModel.Password);
//Add User to the selected Roles
if (adminresult.Succeeded)
{
if (selectedRoles != null)
{
var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
return View();
}
}
}
else
{
ModelState.AddModelError("", adminresult.Errors.First());
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
return View();
}
return RedirectToAction("Index");
}
ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
return View();
}
//
// GET: /Users/Edit/1
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
var userRoles = await UserManager.GetRolesAsync(user.Id);
return View(new EditUserViewModel()
{
Id = user.Id,
Email = user.Email,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
{
Selected = userRoles.Contains(x.Name),
Text = x.Name,
Value = x.Name
})
});
}
//
// POST: /Users/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Email,Id")] EditUserViewModel editUser, params string[] selectedRole)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
user.UserName = editUser.Email;
user.Email = editUser.Email;
var userRoles = await UserManager.GetRolesAsync(user.Id);
selectedRole = selectedRole ?? new string[] { };
var result = await UserManager.AddToRolesAsync(user.Id, selectedRole.Except(userRoles).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
ModelState.AddModelError("", "Something failed.");
return View();
}
//
// GET: /Users/Delete/5
public async Task<ActionResult> Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
//
// POST: /Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(string id)
{
if (ModelState.IsValid)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
var result = await UserManager.DeleteAsync(user);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
return View();
}
}
}
一般就是用户的编辑和删除,下面我们对角色的编辑和删除:RolesAdminController
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using AxCMS.Models;
namespace AxCMS.Controllers
{
[Authorize(Roles = "Admin")]
public class RolesAdminController : Controller
{
public RolesAdminController()
{
}
public RolesAdminController(ApplicationUserManager userManager,
ApplicationRoleManager roleManager)
{
UserManager = userManager;
RoleManager = roleManager;
}
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
set
{
_userManager = value;
}
}
private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager
{
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
private set
{
_roleManager = value;
}
}
//
// GET: /Roles/
public ActionResult Index()
{
return View(RoleManager.Roles);
}
//
// GET: /Roles/Details/5
public async Task<ActionResult> Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
// Get the list of Users in this Role
var users = new List<ApplicationUser>();
// Get the list of Users in this Role
foreach (var user in UserManager.Users.ToList())
{
if (await UserManager.IsInRoleAsync(user.Id, role.Name))
{
users.Add(user);
}
}
ViewBag.Users = users;
ViewBag.UserCount = users.Count();
return View(role);
}
//
// GET: /Roles/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Roles/Create
[HttpPost]
public async Task<ActionResult> Create(RoleViewModel roleViewModel)
{
if (ModelState.IsValid)
{
var role = new IdentityRole(roleViewModel.Name);
var roleresult = await RoleManager.CreateAsync(role);
if (!roleresult.Succeeded)
{
ModelState.AddModelError("", roleresult.Errors.First());
return View();
}
return RedirectToAction("Index");
}
return View();
}
//
// GET: /Roles/Edit/Admin
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
RoleViewModel roleModel = new RoleViewModel { Id = role.Id, Name = role.Name };
return View(roleModel);
}
//
// POST: /Roles/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Name,Id")] RoleViewModel roleModel)
{
if (ModelState.IsValid)
{
var role = await RoleManager.FindByIdAsync(roleModel.Id);
role.Name = roleModel.Name;
await RoleManager.UpdateAsync(role);
return RedirectToAction("Index");
}
return View();
}
//
// GET: /Roles/Delete/5
public async Task<ActionResult> Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
return View(role);
}
//
// POST: /Roles/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(string id, string deleteUser)
{
if (ModelState.IsValid)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = await RoleManager.FindByIdAsync(id);
if (role == null)
{
return HttpNotFound();
}
IdentityResult result;
if (deleteUser != null)
{
result = await RoleManager.DeleteAsync(role);
}
else
{
result = await RoleManager.DeleteAsync(role);
}
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
return View();
}
}
}
视图方面我已经上传到Nuget,在程序包安装管理器控制台中输入Install-Package AxCMS
就可以了。
下面重点来了解一下在Details视图如何加入评论内容以及加入评论的表单。这是一个比较实用的方法,依照ASP.NET生成的默认增修改虽然很方便,但满足不了我们各种要求。
下面的难点就在于多个model对一个视图,像这个文章的详细页面是属于一个model,评论则是属于另外一个model。如果非要生成一个页面也是可以的,但还要做成一个大model。
public class BigModel
{
public Contents contents { get; set; }
public List<UserCommments> usercomments { get; set; }
}
在控制器方面的代码,我们先查询出id对应的文章,然后再根据这个id,再做一次查询,把评论也查询出来。
public ActionResult Index(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ViewBag.forid = id;
BigModel bigmodel = new BigModel();
bigmodel.usercomments = (from u in db.UserCommments where u.ContentsId == id select u).ToList();
bigmodel.contents = (from c in db.Contents where c.ContentsId == id select c).FirstOrDefault();
if (bigmodel== null)
{
return HttpNotFound();
}
return View(bigmodel);
}
视图方面比较简单,把model定为BigModel,里面包含着两个小的实例model:
@model AxCMS.Models.BigModel
@{
ViewBag.Title = "Index";
}
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model=>model.contents.Title)
</dt>
<dd>
@Html.DisplayFor(model=>model.contents.Title)
</dd>
<dt>
@Html.DisplayNameFor(model => model.contents.User)
</dt>
<dd>
@Html.DisplayFor(model => model.contents.User)
</dd>
<dt>
@Html.DisplayNameFor(model => model.contents.Content)
</dt>
<dd>
@Html.DisplayFor(model => model.contents.Content)
</dd>
<dt>
用户评论:
</dt>
<dd>
<ul>
@foreach(var b in Model.usercomments)
{
<li>@Html.DisplayFor(model=>b.Comments)</li>
}
</ul>
</dd>
<dt>
发表评论:
</dt>
<dd>
</dd>
</dl>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
可以看出,我们还留有发表评论的空间。
实现发表评论的方法有好几种,我们还是用一种比较适合MVC结构的方式来编写,首先修改BigModel:
public class BigModel
{
public Contents contents { get; set; }
public List<UserCommments> usercomments { get; set; }
public UserCommments usercommentss { get; set; }
}
在视图上我们加入发表评论的表单,@if (Request.IsAuthenticated && User.IsInRole("Admin"))
,这里是限制了只有角色名为Admin才能显示发表评论的表单,可以修改或者去掉后面的User.IsInRole("Admin"),这样只需登录用户就可以发表评论了。
@if (Request.IsAuthenticated && User.IsInRole("Admin"))
{
using (Html.BeginForm("Indexsave", "Test"))
{
@Html.AntiForgeryToken()
<input name="usercommentss.ContentsId" id="usercommentss_ContentsId" type="hidden" value="@ViewBag.forid" />
@Html.EditorFor(m=>m.usercommentss.Comments)
<input type="submit" value="Create" class="btn btn-default" />
}
}
最后,在控制器中修改,增加如下代码:
@if (Request.IsAuthenticated && User.IsInRole("Admin"))
{
using (Html.BeginForm("Indexsave", "Test"))
{
@Html.AntiForgeryToken()
<input name="usercommentss.ContentsId" id="usercommentss_ContentsId" type="hidden" value="@ViewBag.forid" />
@Html.EditorFor(m=>m.usercommentss.Comments)
<input type="submit" value="Create" class="btn btn-default" />
}
}
好了,这个基本的CMS已经完成,这些代码都是最基本的代码,它提供一点思路,当然也是及其入门的知识点。
比较可惜的是,没能在这个例子里面加入AJAX的例子,我很希望在这个例子里面加入数据库生成JSON,再从读取JSON AJAX到视图的教程,下次有机会再说。
谢谢大家。转帖的时候请把凉风有兴或者AlexZeng.net进行署名。本文版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
网友评论