上一节我们建立好数据库与数据表结构之后,接下来我们在vs2012中新建MVC开发项目,默认的文件内容就不讲了,关于MVC基础知识东西可以网上查阅其他,或者阅读我的其他博文中的有关介绍。
一、首先先建立用户的Model模型类。
1)用户信息模型
using System; using System.ComponentModel.DataAnnotations; namespace Hillstone.Models { public class SysComUser { /// <summary> /// 用户名Id /// </summary> [Key] public int UserId { get; set; } /// <summary> /// 登录名 /// </summary> [Display(Name="登录名",Description="4-20个字符")] [Required(ErrorMessage = "×")] [StringLength(20, MinimumLength = 4, ErrorMessage = "×")] public string LoginName { get; set; } /// <summary> /// 用户名 /// </summary> [Display(Name = "用户名", Description = "4-20个字符")] [Required(ErrorMessage = "×")] [StringLength(20, MinimumLength = 4, ErrorMessage = "×")] public string UserName { get; set; } /// <summary> /// 登录密码 /// </summary> [Display(Name="登录密码")] [Required(ErrorMessage = "×")] [StringLength(50,MinimumLength=6,ErrorMessage="6-50个字符!")] [DataType(DataType.Password)] public string Password { get; set; } /// <summary> /// 排序号 /// </summary> [Display(Name = "排序")] public string OrderNo { get; set; } /// <summary> /// 用户类型:0-内部用户,1-外部用户 /// </summary> [Display(Name="用户类型")] public Nullable<int> UserType { get; set; } /// <summary> /// 使用状态:0-使用,1-禁用,2-删除 /// </summary> [Display(Name = "使用状态")] public Nullable<int> Flag { get; set; } /// <summary> /// 所在单位ID /// </summary> [Display(Name = "所在单位")] public Nullable<int> UnitId { get; set; } /// <summary> /// 所在岗位ID /// </summary> [Display(Name = "所在岗位")] public Nullable<int> PosId { get; set; } /// <summary> /// 创建人ID /// </summary> [Display(Name = "创建人ID")] public Nullable<int> CreatedUserId { get; set; } /// <summary> /// 创建人姓名 /// </summary> [Display(Name = "创建人")] public string CreatedUserName { get; set; } /// <summary> /// 创建时间 /// </summary> [Display(Name = "创建时间")] [DataType(DataType.DateTime)] //[DisplayFormat(DataFormatString="{0:yy-mm-dd}")] public Nullable<System.DateTime> CreatedDate { get; set; } /// <summary> /// 用户对应的群组 ///public virtual ICollection<SysComGroupUser> sysComGroupUser { get; set; } ///</summary> } }
主键要加上[key],否则实例调用时会出错的。[Display]在View页面中要显示的属性名字以及描述,
StringLenth设置字段的长度范围和错误提示信息,Required必填项要求,DataType数据类型,有Password密码、DataTime时间等。DisplayFormat设置格式显示的表达式。
2)用户登录注册模型
using System.ComponentModel.DataAnnotations; namespace Hillstone.Models { public class SysComUserRegister:SysComUser { [Display(Name="登录密码",Description="6-20个字符")] [Required(ErrorMessage = "×")] [StringLength(20,MinimumLength=6,ErrorMessage="×")] [DataType(DataType.Password)] public new string Password { get; set; } [Display(Name="确认密码",Description="再次输入登录密码!")] [Required(ErrorMessage = "×")] [Compare("Password",ErrorMessage="×")] [DataType(DataType.Password)] public string RPassword { get; set; } [Display(Name="验证码",Description="请输入图片中的验证码!")] [Required(ErrorMessage="×")] [StringLength(4,MinimumLength=4,ErrorMessage="×")] public string VerificationCode { get; set; } /// <summary> /// 读取用户其他信息 /// </summary> /// <returns></returns> public SysComUser GetUser() { return new SysComUser { LoginName = this.LoginName, UserName = this.UserName, UserType = this.UserType, UnitId = this.UnitId, Password = this.Password, PosId = this.PosId, Flag = this.Flag, OrderNo = this.OrderNo, CreatedUserId = this.CreatedUserId, CreatedDate = this.CreatedDate, CreatedUserName = this.CreatedUserName }; } } }
由于用户注册中确认密码和验证码不需要写进数据库,所以需要单独建立一个模型,但是在注册时显示的内容大部分都在用户信息模型中,所以这里要继承SysComUser类,这样就可以直接引用了。确认密码中映射[Compare]用于比较两者是否一致。通过这里可以看出模型是什么,其实就是个Class,里面可以做属性定义和方法定义。基本和我们以前ASP.NET开发时候差不多,只不过是字段的验证规则等采用了更多的对象映射技术。
二、紧接着建立用户Contrallers控制器
1)全部代码如下:
using System.Web.Mvc; using System.Drawing; using Hillstone.Models; using Hillstone.Common; namespace Hillstone.Controllers { public class SysComUserController : Controller { /// <summary> /// 用户注册显示页面 /// </summary> /// <returns></returns> public ActionResult UserRegister() { ViewData["Flag"] = Function.getSelectList(); return View(); } /// <summary> /// 执行用户信息注册 /// </summary> /// <param name="users"></param> /// <returns></returns> [HttpPost] public ActionResult UserRegister(SysComUser users) { return View(); } /// <summary> /// 生成验证码 /// </summary> /// <returns></returns> public ActionResult VerificationCode() { //验证码字数 int _verificationLength = 4; int _width = 100, _height = 20; SizeF _verificationTextSize; Bitmap _bitmap = new Bitmap(Server.MapPath("~/Skins/Common/VerificationCode.png"), true); TextureBrush _brush = new TextureBrush(_bitmap); //获取验证码 string _verificationText = Common.Text.VerificationText(_verificationLength); //存储验证码 Session["VerificationCode"] = _verificationText.ToUpper(); Font _font = new Font("Arial", 14, FontStyle.Bold); Bitmap _image = new Bitmap(_width, _height); Graphics _g = Graphics.FromImage(_image); //清空背景色 _g.Clear(Color.White); //绘制验证码 _verificationTextSize = _g.MeasureString(_verificationText, _font); _g.DrawString(_verificationText, _font, _brush, (_width - _verificationTextSize.Width) / 2, (_height - _verificationTextSize.Height) / 2); _image.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); return null; } } }
2)用户注册中首先我们要考虑的就是验证码功能的实现,这里定义一个VerificationCode()方法来绘制验证码,读取一图片到缓存中Bitmap作为绘制验证码材质.获取验证码的方法VerificationText().参数为要返回的验证码的个数,由于这是个通用的方法,因此把他单独放在一个类中,新建一个Common文件夹,添加Text.cs类。将此方法写在此类中,所有有关文本文字处理的功能都可以在这里面写。便于管理和使用。如下:
using System; namespace Hillstone.Common { public class Text { public static string VerificationText(int length) { char[] _verificationText = new char[length]; char[] _dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; Random _random = new Random(); for (int i = 0; i <= length - 1; i++) { int _number = _random.Next(_dictionary.Length - 1); _verificationText[i] = _dictionary[_number]; } return new string(_verificationText); } } }
由于命名空间不一样,所以我们要在调用此方法的文件中,引用
using namespace Hillstone.Common
才可以。
3)用户的注册就要涉及到数据的存取,对数据的库CRDU操作。用户的控制器SysComUserContrallers类中的注册等方法中没写东西,并做数据操作动作,创建Context实现对EF的操作,它继承与DBContext.为方便管理和规范,把所有对数据的增删改查功能等抽象成一个类,以接口方式,统一规范标准,继承类中必须实现这些接口标准。如下:
using System.Data.Entity; using Hillstone.Models; namespace Hillstone.DAL { public class HillstoneContext:DbContext { /// <summary> /// 初始化连接字符串 /// </summary> public HillstoneContext() : base("name=DefaultConnection") { } //注意这里的泛型名称要和表名保持一直,否则会自动创建一个表 public DbSet<SysComUser> SysComUser { get; set; } } }
接口类 IResponsitoryBase
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Hillstone.DAL namespace Hillstone.BLL { public class IRepositoryBase<TModel> { private HillstoneContext dbContext; public IRepositoryBase() { dbContext = new HillstoneContext(); } /// <summary> /// 添加【继承类重写后才能正常使用】 /// </summary> /// <param name="Tmodel">传入Model模型数据值</param> /// <returns>布尔值</returns> public virtual bool Add(TModel Tmodel) { return false; } /// <summary> /// 修改【继承类重写后才能正常使用】 /// </summary> /// <param name="Tmodel">传入Model模型数据值</param> /// <returns>布尔值</returns> public virtual bool Update(TModel Tmodel) { return false; } /// <summary> /// 删除指定值【继承类重写后才能正常使用】 /// </summary> /// <param name="Id">传入主键ID值</param> /// <returns>布尔值</returns> public virtual bool Delete(int Id) { return false; } /// <summary> /// 查询指定值【继承类重写后才能正常使用】 /// </summary> /// <param name="Id">传入主键ID值</param> /// <returns>Model模型数据值</returns> public virtual TModel Find(int Id) { return default(TModel); } /// <summary> /// 释放堆栈值 /// </summary> ~IRepositoryBase() { if (dbContext!=null) { dbContext.Dispose(); } } } }
4)创建用户的数据操作类SysComUserRepository实现增、删、改、查等方法重写,它是继承IResponsitoryBase这个接口。如下
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Hillstone.Models; namespace Hillstone.BLL { public class SysComUserRepository : IRepositoryBase<Hillstone.Models.SysComUser> { private HillstoneContext dbContext; public SysComUserRepository() { dbContext = new HillstoneContext(); } /// <summary> /// 添加一条用户信息 /// </summary> /// <param name="Tmodel">用户数据模型</param> /// <returns>布尔值</returns> public override bool Add(SysComUser Tmodel) { if (Tmodel == null) { return false; } dbContext.SysComUser.Add(Tmodel); if (dbContext.SaveChanges() > 0){ return true; }else{ return false; } } /// <summary> /// 修改一条用户信息 /// </summary> /// <param name="Tmodel">用户数据模型</param> /// <returns>布尔值</returns> public override bool Update(SysComUser Tmodel) { if (Tmodel == null) { return false; } var _tmodel = dbContext.SysComUser.FirstOrDefault(u => u.UserId == Tmodel.UserId); if (_tmodel == null) { return false; } _tmodel = Tmodel; if (dbContext.SaveChanges() > 0) { return true; } else { return false; } } } }
5)完成之后,SysComUserContrallers类中引用using Hillstone.BLL;并实例化一个对象
SysComUserRepository userRepository = new SysComUserRepository();下面就是用它来实现
UserRegister()方法。
代码如下:
[HttpPost] public ActionResult UserRegister(SysComUserRegister userRegs) { if (string.IsNullOrEmpty(Session["VerificationCode"].ToString())) { //检查验证码是否为空! ModelState.AddModelError("VerificationCode", "×"); return View(); } else if (Session["VerificationCode"].ToString() != userRegs.VerificationCode) { //检查验证码是否错误 ModelState.AddModelError("VerificationCode", "×"); return View(); } else { //验证码通过后检查登录名是否重复 if (userRepository.IsExists(userRegs.LoginName)) { ModelState.AddModelError("LoginName", "此登录名已经被使用!"); return View(); } else { //读取用户注册信息 SysComUser userInfo = userRegs.getUsers(); if (userRepository.Add(userInfo)) { return View(); } else { return View(); } } } }
用到两个方法userRepository.IsExit(LoginName)将此登录名是否存在和userRepository.Add(SysComUser)添加用户信息。具体代码如下:
/// <summary> /// 检查当前登录名是否已经存在 /// </summary> /// <param name="LoginName">登录名</param> /// <returns>布尔值:是否</returns> public bool IsExists(string LoginName) { if (dbContext.SysComUser.Any(u => u.LoginName.ToUpper() == LoginName.ToUpper())) { return true; } else { return false; } }
6)创建视图,自动生成如下:
@model Hillstone.Models.SysComUserRegister @{ ViewBag.Title = "用户注册"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>用户注册</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) <fieldset> <legend>用户注册</legend> <div class="editor-label"> @Html.LabelFor(model => model.LoginName) </div> <div class="editor-field"> @Html.EditorFor(model => model.LoginName) @Html.ValidationMessageFor(model => model.LoginName) @Html.DisplayDescriptionFor(model => model.LoginName) </div> <div class="editor-label"> @Html.LabelFor(model => model.UserName) </div> <div class="editor-field"> @Html.EditorFor(model => model.UserName) @Html.ValidationMessageFor(model => model.UserName) @Html.DisplayDescriptionFor(model => model.UserName) </div> <div class="editor-label"> @Html.LabelFor(model => model.Password) </div> <div class="editor-field"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> <div class="editor-label"> @Html.LabelFor(model => model.RPassword) </div> <div class="editor-field"> @Html.EditorFor(model => model.RPassword) @Html.ValidationMessageFor(model => model.RPassword) </div> <div class="editor-label"> @Html.LabelFor(model => model.VerificationCode) </div> <div class="editor-field"> @Html.EditorFor(model => model.VerificationCode) @Html.ValidationMessageFor(model => model.VerificationCode) <img id="verificationcode" alt="验证码" src="@Url.Action("VerificationCode", "SysComUser")" /> <a id="trydifferent" style="cursor:pointer" onclick="VerificationChange()">换一张</a> </div> <div class="editor-label"> @Html.LabelFor(model => model.OrderNo) </div> <div class="editor-field"> @Html.EditorFor(model => model.OrderNo) @Html.ValidationMessageFor(model => model.OrderNo) </div> <div class="editor-label"> @Html.LabelFor(model => model.UserType) </div> <div class="editor-field"> @Html.RadioButton("UserType",0,true) 企业内部 @Html.RadioButton("UserType",1) 企业外部 @Html.ValidationMessageFor(model => model.UserType) </div> <div class="editor-label"> @Html.LabelFor(model => model.Flag) </div> <div class="editor-field"> @Html.DropDownList("Flag",ViewData["Flag"] as SelectList) @Html.ValidationMessageFor(model => model.Flag) </div> <div class="editor-label"> @Html.LabelFor(model => model.UnitId) </div> <div class="editor-field"> @Html.EditorFor(model => model.UnitId) @Html.ValidationMessageFor(model => model.UnitId) </div> <div class="editor-label"> @Html.LabelFor(model => model.PosId) </div> <div class="editor-field"> @Html.EditorFor(model => model.PosId) @Html.ValidationMessageFor(model => model.PosId) </div> <div class="editor-label"> @Html.LabelFor(model => model.CreatedUserId) </div> <div class="editor-field"> @Html.EditorFor(model => model.CreatedUserId) @Html.ValidationMessageFor(model => model.CreatedUserId) </div> <div class="editor-label"> @Html.LabelFor(model => model.CreatedUserName) </div> <div class="editor-field"> @Html.EditorFor(model => model.CreatedUserName) @Html.ValidationMessageFor(model => model.CreatedUserName) </div> <div class="editor-label"> @Html.LabelFor(model => model.CreatedDate) </div> <div class="editor-field"> @Html.EditorFor(model => model.CreatedDate) @Html.ValidationMessageFor(model => model.CreatedDate) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div> <script type="text/javascript" > function VerificationChange() { $("#verificationcode").attr("src", "/SysComUser/VerificationCode?" + new Date()); } </script> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
7)@html.DisplayDescriptionFor(model=>model.LoginName)方法需要自己定义扩展。扩展内容放在Extensions文件夹下面,新增DisplayDescriptionExtensions.cs文件类,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Linq.Expressions;//命名空间包含的类、接口和枚举能够使语言级别的代码表达式表示为表达式树形式的对象。抽象类 Expression 充当类继承层次结构的根,这个层次结构被用于构造表达式树。 using System.Web.Mvc; using System.Web.Mvc.Html; namespace System.Web.Mvc.Html { public static class DisplayDescriptionExtensions { /// <summary> /// 通用模式:通过HTML控件模型的名称读取模型描述信息 /// </summary> /// <param name="htmlHelper">HTML控件</param> /// <param name="name">属性名称</param> /// <returns>显示文字内容:模型描述信息</returns> public static MvcHtmlString DisplayDescription(this HtmlHelper htmlHelper,string name) { //从模型的参数表达式中获取元数据:参数 1模式的标识:name, 2、视图数据字典:ViewData,3、返回值:模型的元数据 ModelMetadata _modelMetadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewData); //使用指定的文字值,建立 HTML ��a的字串,其实就是将cs中的值以文本HTML的形式显示在view中. return MvcHtmlString.Create(_modelMetadata.Description); } /// <summary> /// 强类型的实体模式:通过lamba表达式读取模型描述信息,更好的intellisense支持 /// </summary> /// <typeparam name="TModel">封装的实体对象</typeparam> /// <typeparam name="TResult">返回类型值</typeparam> /// <param name="htmlHelper">强类型视图中呈现的HTML控件</param> /// <param name="expression">以目录树的形式将强类型的lambda表达式表示为数据结构</param> /// <returns>显示文字内容:模型描述信息</returns> public static MvcHtmlString DisplayDescriptionFor<TModel, TResult>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel,TResult>> expression) { //从模型的 Expression 参数返回元数据:参数1、一个标识模型的表达式:expression。2、视图数据字典:ViewData。3、返回值:模型的元数据。 ModelMetadata _modelMetaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); return MvcHtmlString.Create(_modelMetaData.Description); } } }
本文出自 “奔跑的小蜗牛-原创空间” 博客,谢绝转载!