编程

当前位置:永利皇宫463登录 > 编程 > 一步一步创建ASP

一步一步创建ASP

来源:http://www.makebuLuo.com 作者:永利皇宫463登录 时间:2019-09-22 05:18

仓储层

在项目【TsBlog.Repositories】中创建 IUserRepository.cs 以及其实现类 UserRepository.cs

IUserRepository.cs:

using TsBlog.Domain.Entities;namespace TsBlog.Repositories{    public interface IUserRepository : IRepository<User>    {    }}

UserRepository.cs:

using TsBlog.Domain.Entities;namespace TsBlog.Repositories{    public class UserRepository : GenericRepository<User>, IUserRepository    {    }}

安装第三方分页组件

为了方便,本示例教程使用的是第三方的分页组件来实现UI层的分页功能,组件为:PagedList。安装的方式为:nuget,所以与以前几期的nuget包安装类似,打开nuget包管理工具,搜索关键词PagedList,在查询出来的包中,选择PagedList.MvcPagedList两个分页组件包并安装,如下:

图片 1

分页组件安装完成之后,我们再打开 HomeController 控制器,修改Index这个ActionHomerController.cs修改后的完整代码如下:

using PagedList;using System.Linq;using System.Web.Mvc;using TsBlog.AutoMapperConfig;using TsBlog.Frontend.Extensions;using TsBlog.Services;using TsBlog.ViewModel.Post;namespace TsBlog.Frontend.Controllers{ public class HomeController : Controller { /// <summary> /// 文章服务接口 /// </summary> private readonly IPostService _postService; public HomeController(IPostService postService) { _postService = postService; } /// <summary> /// 首页 /// </summary> /// <returns></returns> public ActionResult Index(int? page) { //var list = _postService.FindHomePagePosts(); //读取分页数据,返回IPagedList<Post> page = page ?? 0; var list = _postService.FindPagedList(x => !x.IsDeleted && x.AllowShow, pageIndex: page, pageSize: 10); var model = list.Select(x => x.ToModel().FormatPostViewModel; ViewBag.Pagination = new StaticPagedList<PostViewModel>(model, list.PageIndex, list.PageSize, list.TotalCount); return View; } }}

最后,再打开Index对应的视图文件:/Views/Home/Index.cshtml,添加分页控件,如下:

@using PagedList@using PagedList.Mvc@model IEnumerable<TsBlog.ViewModel.Post.PostViewModel>@{ Layout = "~/Views/Shared/_Layout.cshtml"; ViewBag.Title = "ASP.NET MVC 5 系列文章教程--首页";}<div > <h1>小伙伴,你好</h1> <p>欢迎来到 Rector 的ASP.NET MVC 5 系列文章教程。在这里,Rector将和你一起一步一步创建一个集成Repository+Autofac+Automapper+SqlSugar的WEB应用程序。</p> <p>你准备好了吗?</p> <p>......</p> <p>让我们开始ASP.NET MVC 5 应用程序的探索之旅吧!!!</p></div><strong >文章列表(@(Model.Count</strong><ul > @foreach (var p in Model) { <li> <h2><a href="~/post/details/@p.Id">@p.Title</a></h2> <p >@p.Summary ... <a href="~/post/details/@p.Id">阅读全文</a></p> </li> }</ul>@Html.PagedListPager((IPagedList)ViewBag.Pagination, page => Url.Action("index", new { page }), new PagedListRenderOptions{ LinkToFirstPageFormat = "首页", LinkToPreviousPageFormat = "上一页", LinkToNextPageFormat = "下一页", LinkToLastPageFormat = "末页", DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded, DisplayLinkToLastPage = PagedListDisplayMode.Never, DisplayEllipsesWhenNotShowingAllPageNumbers = true, MaximumPageNumbersToDisplay = 5})

以上所有更改完成后,就完成了我们对通用分页的封装和实现,当然,这个通用分页是非常简单的,只能满足单表数据的分页查询和读取。更复杂的分页需求请自行根据思路进行实现。

完成以上步骤之后,我们重新编译和生成项目 TsBlog.Frontend 。最后,在浏览器中打开地址: ,检查一下,数据分页功能是否起作用了呢?

好了,如果你喜欢Rector,或者是喜欢本系列文章,请为我点个赞,以鼓励Rectro继续写出更好的文章,或者系列文章。

本期源码托管地址:请至首发地址《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]》查看

看完教程如果觉得还不过瘾的,想“勾对”的,欢迎加入图享网官方QQ群:483350228,如果你按照教程还原出来的程序运行有问题,请参照本期源码对应调整与修改遇到问题的,也欢迎加入QQ群。有什么,你懂的。。。_

谢谢你的耐心阅读,本系列未完待续,我们下期再见……

同时,也欢迎大家关注我们的.NET编程爱好者社区: 每天都有.NET的开发技术干货更新哦。

[] 一个.NET编程爱好者社区,专注.NET/C#开发,帮助你找到疑难问题的更优美、更高级的解决方案

添加必要JS库

由于之前我们将项目中的多余的JS库全部移除掉了,所以现在我们重新安装一下我们项目中将要到的一些JS库,包括:jQuery,Bootstrap等,都使用Nuget来安装,方便统一管理和升级。

安装jQuery:

图片 2

安装Bootstrap:

图片 3

安装jquery.validate.bootstrap:

图片 4

安装完成后的JS库文件夹:

图片 5

public IEnumerable<Post> FindHomePagePosts(int limit = 20) { using (var db = DbFactory.GetSqlSugarClient { var list = db.Queryable<Post>().OrderBy(x => x.Id, OrderByType.Desc).Take.ToList(); return list; } }

服务层

在项目【TsBlog.Services】中创建 IUserService.cs 以及其实现类 UserService.cs

IUserService.cs:

using TsBlog.Domain.Entities;namespace TsBlog.Services{    public interface IUserService : IService<User>    {        User FindByLoginName(string loginName);    }}

UserService.cs:

using TsBlog.Domain.Entities;using TsBlog.Repositories;namespace TsBlog.Services{    public class UserService : GenericService<User>, IUserService    {        private readonly IUserRepository _repository;        public UserService(IUserRepository repository) : base(repository)        {            _repository = repository;        }        public User FindByLoginName(string loginName)        {            return _repository.FindByClause(x => x.LoginName == loginName);        }    }}

来读取文章表中的前N条记录作为首页的文章列表数据源。那么,本文将为大家封装一个通用的分页信息类以及分页泛型方法,并最终实现首页文章列表的数据分页功能。分页效果如下图:

创建加密类

在解决方案文件夹【1.Libraries】中创建一个新的项目,取名为【TsBlog.Core】,在此项目中先创建一个名为 Security的文件夹,再创建一个加密类 Encryptor.cs

using System.Security.Cryptography;using System.Text;namespace TsBlog.Core.Security{    /// <summary>    /// 加密静态类    /// </summary>    public static class Encryptor    {        //MD5加密一个字符串        public static string Md5Hash(string text)        {            MD5 md5 = new MD5CryptoServiceProvider();            md5.ComputeHash(Encoding.ASCII.GetBytes;            var result = md5.Hash;            var strBuilder = new StringBuilder();            foreach (var t in result)            {                strBuilder.Append(t.ToString("x2"));            }            return strBuilder.ToString();        }    }}

在用户注册或者登录时,我们将使用这个MD5加密用户的密码,并将其保存到数据库中(数据库中保存明文的密码是非常危险的,特别是在重要的安全级别很高的项目中,千别样!!!)。

  • 通用分页的封装
  • 文章分页的实现

前言

Hi,
大家好,还是星期五,还是Rector,又在图享网准时和大家见面了。
今天给大家带来系列教程《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]》的第八期了,不知道你有没有按照教程将前七期的都实际练习一篇呢?如果是,你在练习的时候有没有遇到什么问题呢?
反正Rector是有收到部分童鞋发来他们练习过程中的问题反馈的哦。

如果你仔细阅读并实际练习了前面七期的教程,我相信,作为刚入门或者经验尚浅的你一定会有收获的。

加油吧,骚年!!! 人生苦短,就怕努力!!!

Rector这是要成为心理导师的节奏啊,一来就给大家灌饱心灵鸡汤。。。

本文篇幅有点长,请作好心里准备!!!
同时,也吐个槽,本文看似内容简单的一B,但也花了笔者几个小时来准备示例以及写作,写技术文章真心伤不起
珍爱生命,远离程序!!!

还是回到我们的正题,开始我们今天的系列教程:《一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar》

图片 6一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar

完成注册页面

在 [Views/Account]文件夹中创建注册页面视图 register.cshtml

@model TsBlog.ViewModel.User.RegisterViewModel@{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport" content="width=device-width" />    <title>用户注册</title>    <style type="text/css">        * { box-sizing: border-box; }        body { box-sizing: border-box; margin: 0; padding: 0; color: #333; }        .account-container { position: absolute; margin: auto; top: 0; right: 0; bottom: 0; left: 0; width: 400px; height: 480px; background-color: #fff; /*border-radius: 3px;*/ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); }        .account-signin-container { margin-top: 15px; }            .account-signin-container h1 { font-size: 20px; border-bottom: 2px solid #f7f7f7; margin: 0 0 15px; padding-bottom: 10px; padding-left: 15px; letter-spacing: 0.1em; }        .account-form { padding: 15px; }            .account-form .form-group { width: 100%; margin-bottom: 15px; }                .account-form .form-group label { width: 100%; display: block; }                .account-form .form-group input { border: 1px solid #ccc; line-height: 32px; font-size: 16px; padding: 2px 0px; padding-left: 5px; display: block; width: 100%; margin-top: 5px; }            .account-form #btn_register { border: 0; background: #3b78e7; color: #fff; font-size: 18px; font-weight: bold; padding: 8px 25px; cursor: pointer; margin-top: 15px; display: inline-block; box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); border-radius: 3px; min-width: 100px; text-align: center; }                .account-form #btn_register:hover { background: #4885F3; }        span.error { color: #f00; }        .btn-login { float: right; display: block; margin-top: 25px; color: #4885f3; }        @@media(max-width:500px) {            .account-container { width: 100%; height: 100vh; }        }    </style></head><body>    <div class="account-container">        <div class="account-modal-container">            <div class="modal"></div>            <div class="load-bar-container">                <div class="load-bar">                    <div class="bar"></div>                    <div class="bar"></div>                    <div class="bar"></div>                </div>            </div>            <div class="account-signin-container">                <h1>用户注册</h1>                @using (Html.BeginForm("register", "account", FormMethod.Post, new { @class = "account-form", role = "form" }))                {                    @Html.ValidationMessage("error_message", new { @class = "error" })                    @Html.AntiForgeryToken()                    <div class="form-group">                        <label>                            登录名:                            @Html.TextBoxFor(m => m.UserName, new { placeholder = "请输入登录名" })                            @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "error" })                        </label>                    </div>                    <div class="form-group">                        <label>                            密码:                            @Html.PasswordFor(m => m.Password, new { placeholder = "请输入密码" })                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "error" })                        </label>                    </div>                    <div class="form-group">                        <label>                            确认密码:                            @Html.PasswordFor(m => m.ConfirmPassword, new { placeholder = "请输入确认密码" })                            @Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { @class = "error" })                        </label>                    </div>                    <div class="form-group">                        <button id="btn_register" type="submit">注 册</button>                        <a class="btn-login" href="~/account/login">登录</a>                    </div>                }            </div>        </div>    </div>    <script src="~/Scripts/jquery-3.2.1.min.js"></script>    <script src="~/Scripts/jquery.validate.min.js"></script>    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script></body></html>

再在当前文件夹下创建 login.cshtml 视图文件用作登录页面:

@model TsBlog.ViewModel.User.LoginViewModel@{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport" content="width=device-width" />    <title>用户登录</title>    <style type="text/css">        * { box-sizing: border-box; }        body { box-sizing: border-box; margin: 0; padding: 0; color: #333; }        .account-container { position: absolute; margin: auto; top: 0; right: 0; bottom: 0; left: 0; width: 400px; height: 450px; background-color: #fff; /*border-radius: 3px;*/ box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); }        .account-signin-container { margin-top: 15px; }            .account-signin-container h1 { font-size: 20px; border-bottom: 2px solid #f7f7f7; margin: 0 0 15px; padding-bottom: 10px; padding-left: 15px; letter-spacing: 0.1em; }        .account-form { padding: 15px; }            .account-form .form-group { width: 100%; margin-bottom: 15px; }                .account-form .form-group label { width: 100%; display: block; }                .account-form .form-group input { border: 1px solid #ccc; line-height: 32px; font-size: 16px; padding: 2px 0px; padding-left: 5px; display: block; width: 100%; margin-top: 5px; }            .account-form #btn_login { border: 0; background: #3b78e7; color: #fff; font-size: 18px; font-weight: bold; padding: 8px 25px; cursor: pointer; margin-top: 15px; display: inline-block; box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); border-radius: 3px; min-width: 100px; text-align: center; }                .account-form #btn_login:hover { background: #4885F3; }        span.error { color: #f00; }        .btn-register { float: right; display: block; margin-top: 25px; color: #4885f3; }        @@media(max-width:500px) {            .account-container { width: 100%; height: 100vh; }        }    </style></head><body>    <div class="account-container">        <div class="account-modal-container">            <div class="modal"></div>            <div class="load-bar-container">                <div class="load-bar">                    <div class="bar"></div>                    <div class="bar"></div>                    <div class="bar"></div>                </div>            </div>            <div class="account-signin-container">                <h1>用户登录</h1>                @using (Html.BeginForm("login", "account", FormMethod.Post, new { @class = "account-form", role = "form" }))                {                    @Html.ValidationMessage("error_message", new { @class = "error" })                    @Html.AntiForgeryToken()                    <div class="form-group">                        <label>                            登录名:                            @Html.TextBoxFor(m => m.UserName, new { placeholder = "请输入登录名" })                            @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "error" })                        </label>                    </div>                    <div class="form-group">                        <label>                            密码:                            @Html.PasswordFor(m => m.Password, new { placeholder = "请输入密码" })                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "error" })                        </label>                    </div>                    <div class="form-group">                        <button id="btn_login" type="submit">登 录</button>                        <a class="btn-register" href="~/account/register">注册账号</a>                    </div>                }            </div>        </div>    </div>    <script src="~/Scripts/jquery-3.2.1.min.js"></script>    <script src="~/Scripts/jquery.validate.min.js"></script>    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>    <script src="~/res/assets/notie/notie.min.js"></script></body></html>

这两个页面均是响应式的布局,可适应不同设备。

好了,关于注册和登录的逻辑以及页面都完成了,那么运行项目,打开注册页面:

图片 7

注册成功后,系统将带你到登录页面:

图片 8

具体功能也请自行体验。

以上,我们只完成了注册和登录的基本功能,接下来我们来体验一下简单的权限访问,在本期教程之前,我们的: 以及 是可以直接访问的,现在我们给这两个页面添加访问权限,即只有登录后才能访问,修改 HomeController.cs 如下:

using System.Web.Mvc;using TsBlog.AutoMapperConfig;using TsBlog.Services;namespace TsBlog.Frontend.Controllers{    public class HomeController : Controller    {        private readonly IPostService _postService;        public HomeController(IPostService postService)        {            _postService = postService;        }        public ActionResult Index()        {            //如果未登录,则跳转到登录页面            if (Session["user_account"] == null)            {                return RedirectToAction("login", "account");            }            return View();        }        public ActionResult Post()        {            //如果未登录,则跳转到登录页面            if (Session["user_account"] == null)            {                return RedirectToAction("login", "account");            }            var post = _postService.FindById.ToModel();            return View;        }    }}

重新编译项目,按F5运行,再打开地址: ,发生了什么情况?
是不是被重定向到了登录页面,要求你登录?
这就对了,输入你刚才注册的用户名和密码,登录后,系统会重新带你到: 页面。

OK,今天这期的关于用户注册和登录功能就介绍到这里,本期只实现了简单的功能,在后续的教程中将重构和封装相应的功能代码,敬请期待。。。

如果你喜欢Rector的本系列文章,请为我点个大大的赞。

看完教程如果觉得还不过瘾的,遇到问题的,想“勾对”的,欢迎加入图享网官方QQ群:483350228。有什么,你懂的。。。

谢谢你的耐心阅读,未完待续,我们下期再见……

本期源码托管,请至首发地址获取-- 《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]》

数据库脚本文件请到目录下获取:TsBlogdocumentscriptsmysqlv1.8
本文来源自 图享网 《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]》

小伙伴们,大家好,我是Rector。最近Rector忙于换工作,没有太多时间来更新我们的ASP.NET MVC 5系列文章 [一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar],直到现在才挤些时间赶紧更新一篇,小伙伴们等得太久了。

创建领域实体和视图实体

在项目 【TsBlog.Domain】中的Entities文件夹中创建 User.cs 实体类:

using SqlSugar;using System;namespace TsBlog.Domain.Entities{    [SugarTable("tb_user")]    public class User    {        [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]        public int Id { get; set; }        public string LoginName { get; set; }        public string Password { get; set; }        public string RealName { get; set; }        public string EmailAddress { get; set; }        public string Avatar { get; set; }        public int Status { get; set; }        public string Telephone { get; set; }        public string Qq { get; set; }        public string WebsiteUrl { get; set; }        public DateTime CreatedOn { get; set; }        public string CreatedIp { get; set; }        public int LoginCount { get; set; }        public DateTime? LatestLoginDate { get; set; }        public string LatestLoginIp { get; set; }        public DateTime? ModifiedOn { get; set; }        public int Type { get; set; }    }}

再在项目【TsBlog.ViewModel】中创建 User 的文件夹,并创建以下几个视图实体类

LoginViewModel.cs

using System.ComponentModel.DataAnnotations;namespace TsBlog.ViewModel.User{    /// <summary>    /// 用户登录视图实体    /// </summary>    public class LoginViewModel    {        [Required(ErrorMessage = "请输入用户")]        [Display(Name = "用户名")]        public string UserName { get; set; }        [Required(ErrorMessage = "请输入密码")]        [Display(Name = "密码")]        [DataType(DataType.Password)]        public string Password { get; set; }    }}

RegisterViewModel.cs

using System.ComponentModel.DataAnnotations;namespace TsBlog.ViewModel.User{    /// <summary>    /// 用户注册视图实体    /// </summary>    public class RegisterViewModel    {        [Required(ErrorMessage = "请输入用户名")]        [Display(Name = "用户名")]        public string UserName { get; set; }        [Required(ErrorMessage = "请输入密码")]        [Display(Name = "密码")]        [DataType(DataType.Password), MaxLength(20, ErrorMessage = "密码最大长度为20个字符"), MinLength(6, ErrorMessage = "密码最小长度为6个字符")]        public string Password { get; set; }        [Required(ErrorMessage = "请输入确认密码")]        [Display(Name = "确认密码")]        [DataType(DataType.Password), Compare("Password", ErrorMessage = "两次密码不一致")]        public string ConfirmPassword { get; set; }    }}

UserViewModel.cs:

using System;namespace TsBlog.ViewModel.User{    /// <summary>    /// 与领域用户实体对应的用户视图实体    /// </summary>    public class UserViewModel    {        public int Id { get; set; }        public string LoginName { get; set; }        public string Password { get; set; }        public string RealName { get; set; }        public string EmailAddress { get; set; }        public string Avatar { get; set; }        public int Status { get; set; }        public string Telephone { get; set; }        public string Qq { get; set; }        public string WebsiteUrl { get; set; }        public DateTime CreatedOn { get; set; }        public string CreatedIp { get; set; }        public int LoginCount { get; set; }        public DateTime? LatestLoginDate { get; set; }        public string LatestLoginIp { get; set; }        public DateTime? ModifiedOn { get; set; }        public int Type { get; set; }    }}

在之前两期中,我们的文章列表页面是没有分页功能的,而是使用如下方法:

本文知识要点

  • 用户注册/登录功能设计与实现

创建IPagedList接口及实现

打开项目TsBlog.Repositories,在此项目中分别新建两个类:IPagedList.csPagedList.cs,代码分别如下:

IPagedList.cs

using System.Collections.Generic;namespace TsBlog.Repositories{ public interface IPagedList<T> : IList<T> { int PageIndex { get; } int PageSize { get; } int TotalCount { get; } int TotalPages { get; } bool HasPreviousPage { get; } bool HasNextPage { get; } }}

IPagedLIst.cs

using System;using System.Collections.Generic;using System.Linq;namespace TsBlog.Repositories{ /// <summary> /// 分页组件实体类 /// </summary> /// <typeparam name="T">泛型实体</typeparam> [Serializable] public class PagedList<T> : List<T>, IPagedList<T> { /// <summary> /// 构造函数 /// </summary> /// <param name="source">数据源</param> /// <param name="pageIndex">分页索引</param> /// <param name="pageSize">分页大小</param> public PagedList(IQueryable<T> source, int pageIndex, int pageSize) { var total = source.Count(); TotalCount = total; TotalPages = total / pageSize; if (total % pageSize > 0) TotalPages++; PageSize = pageSize; PageIndex = pageIndex; AddRange(source.Skip(pageIndex * pageSize).Take.ToList; } /// <summary> /// 构造函数 /// </summary> /// <param name="source">数据源</param> /// <param name="pageIndex">分页索引</param> /// <param name="pageSize">分页大小</param> public PagedList(IList<T> source, int pageIndex, int pageSize) { TotalCount = source.Count(); TotalPages = TotalCount / pageSize; if (TotalCount % pageSize > 0) TotalPages++; PageSize = pageSize; PageIndex = pageIndex; AddRange(source.Skip(pageIndex * pageSize).Take.ToList; } /// <summary> /// 构造函数 /// </summary> /// <param name="source">数据源</param> /// <param name="pageIndex">分页索引</param> /// <param name="pageSize">分页大小</param> /// <param name="totalCount">总记录数</param> public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount) { TotalCount = totalCount; TotalPages = TotalCount / pageSize; if (TotalCount % pageSize > 0) TotalPages++; PageSize = pageSize; PageIndex = pageIndex; AddRange; } /// <summary> /// 分页索引 /// </summary> public int PageIndex { get; } /// <summary> /// 分页大小 /// </summary> public int PageSize { get; private set; } /// <summary> /// 总记录数 /// </summary> public int TotalCount { get; } /// <summary> /// 总页数 /// </summary> public int TotalPages { get; } /// <summary> /// 是否有上一页 /// </summary> public bool HasPreviousPage { get { return (PageIndex > 0); } } /// <summary> /// 是否有下一页 /// </summary> public bool HasNextPage { get { return (PageIndex + 1 < TotalPages); } } }}

其中,IPagedList.cs为一个分页信息接口,包含了分页的基本信息,如:当前页索引(PageIndex),分页大小,总记录数(TotalCount),总页数(TotalPages)等等。而PagedList.cs类文件则是对IPagedList.cs接口的实现。

创建控制器

在项目【TsBlog.Frontend】中创建控制器 AccountController.cs,并添加如下代码:

AccountController.cs

using System;using System.Web.Mvc;using TsBlog.Core.Security;using TsBlog.Domain.Entities;using TsBlog.Services;using TsBlog.ViewModel.User;namespace TsBlog.Frontend.Controllers{    /// <summary>    /// 用户中心控制器    /// </summary>    public class AccountController : Controller    {        /// <summary>        /// 用户服务接口        /// </summary>        private readonly IUserService _userService;        public AccountController(IUserService userService)        {            _userService = userService;        }        /// <summary>        /// 登录页面        /// </summary>        /// <returns></returns>        public ActionResult Login()        {            return View();        }        /// <summary>        /// 提交登录请求        /// </summary>        /// <param name="model"></param>        /// <returns></returns>        [HttpPost, ValidateAntiForgeryToken, AllowAnonymous]        public ActionResult Login(LoginViewModel model)        {            //如果视图模型中的属性没有验证通过,则返回到登录页面,要求用户重新填写            if (!ModelState.IsValid)            {                return View;            }            //根据用户登录名查询指定用户实体            var user = _userService.FindByLoginName(model.UserName.Trim;            //如果用户不存在,则携带错误消息并返回登录页面            if (user == null)            {                ModelState.AddModelError("error_message", "用户不存在");                return View;            }            //如果密码不匹配,则携带错误消息并返回登录页面            if (user.Password != Encryptor.Md5Hash(model.Password.Trim            {                ModelState.AddModelError("error_message", "密码错误,请重新登录");                return View;            }            //并用户实体保存到Session中            Session["user_account"] = user;            //跳转到首页            return RedirectToAction("index", "home");        }        /// <summary>        /// 注册页面        /// </summary>        /// <returns></returns>        public ActionResult Register()        {            return View();        }        /// <summary>        /// 提交注册请求        /// </summary>        /// <param name="model"></param>        /// <returns></returns>        [HttpPost, ValidateAntiForgeryToken, AllowAnonymous]        public ActionResult Register(RegisterViewModel model)        {            //如果视图模型中的属性没有验证通过,则返回到注册页面,要求用户重新填写            if (!ModelState.IsValid)            {                return View;            }            //创建一个用户实体            var user = new User            {                LoginName = model.UserName,                Password = Encryptor.Md5Hash(model.Password.Trim,                CreatedOn = DateTime.Now                //由于是示例教程,所以其他字段不作填充了            };            //将用户实体对象写入数据库中            var ret = _userService.Insert;            if (ret <= 0)            {                //如果注册失败,则携带错误消息并返回注册页面                ModelState.AddModelError("error_message", "注册失败");                return View;            }            //如果注册成功,则跳转到登录页面            return RedirectToAction("login");        }    }}

添加泛型仓储分页接口

打开项目TsBlog.RepositoriesIRepository.cs 文件,在其中新建分页接口,如下:

/// <summary>/// 根据条件查询分页数据/// </summary>/// <param name="predicate"></param>/// <param name="orderBy"></param>/// <param name="pageIndex">当前页面索引</param>/// <param name="pageSize">分布大小</param>/// <returns></returns>IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20);

再打开此项目中的 GenericRepository.cs 泛型仓储实现类,在其中实现FindPagedList这个分页方法,如下:

/// <summary>/// 根据条件查询分页数据/// </summary>/// <param name="predicate"></param>/// <param name="orderBy"></param>/// <param name="pageIndex">当前页面索引</param>/// <param name="pageSize">分布大小</param>/// <returns></returns>public IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20){ using (var db = DbFactory.GetSqlSugarClient { var totalCount = 0; var page = db.Queryable<T>().OrderBy.ToPageList(pageIndex, pageSize, ref totalCount); var list = new PagedList<T>(page, pageIndex, pageSize, totalCount); return list; }}

类似地操作,打开项目 TsBlog.Services,并打开文件 IService.cs,在其中添加分页服务接口,如下:

/// <summary>/// 根据条件查询分页数据/// </summary>/// <param name="predicate"></param>/// <param name="orderBy"></param>/// <param name="pageIndex">当前页面索引</param>/// <param name="pageSize">分布大小</param>/// <returns></returns>IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20);

再打开此项目中的泛型服务类GenericService.cs,在其中实现分页服务接口,如下:

/// <summary>/// 根据条件查询分页数据/// </summary>/// <param name="predicate"></param>/// <param name="orderBy"></param>/// <param name="pageIndex">当前页面索引</param>/// <param name="pageSize">分布大小</param>/// <returns></returns>public IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20){ return _repository.FindPagedList(predicate, orderBy, pageIndex, pageSize);}

到此,我们的泛型仓储和服务的通用分页接口和实现就封装完成了,现在我们需要使用以上的分页封装,在UI层来实现文章列表的分页功能。

**切换到项目 TsBlog.Frontend **。

设计用户表

这个表呢,Rector已经为大家准备好了,MySQL表结构如下:

SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for ts_user-- ----------------------------DROP TABLE IF EXISTS `tb_user`;CREATE TABLE `tb_user`  (  `Id` int NOT NULL AUTO_INCREMENT,  `LoginName` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '登录名',  `Password` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '密码',  `DisplayName` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '显示名称',  `RealName` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '真实姓名',  `EmailAddress` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '电子邮箱',  `Avatar` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '用户头像',  `Status` int NOT NULL DEFAULT 1 COMMENT '用户的状态,0:禁用,1:正常',  `Telephone` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '手机号码',  `Qq` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',  `WebsiteUrl` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',  `CreatedOn` datetime NULL DEFAULT NULL COMMENT '用户创建时间',  `CreatedIp` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '创建用户时的IP地址',  `LoginCount` int NULL DEFAULT 0 COMMENT '登录次数累加器',  `LatestLoginDate` datetime NULL DEFAULT NULL COMMENT '最近一次登录时间',  `LatestLoginIp` varchar CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '最近一次登录时的IP地址',  `ModifiedOn` datetime NULL DEFAULT NULL COMMENT '最近修改时间',  `Type` int NULL DEFAULT 0 COMMENT '用户类型[-1:超级管理员,0:一般用户]',  PRIMARY KEY  USING BTREE,  UNIQUE INDEX `IX_LoginName`(`LoginName`) USING BTREE,  UNIQUE INDEX `IX_EmailAddress`(`EmailAddress`) USING BTREE,  INDEX `IX_CreatedOn`(`CreatedOn`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

请直接复制以上MySQL脚本,然后到对应数据执行即可,当然你也可以在这个版本的源码里面找到。
这个表就不准备提前写入示例数据了,一会我们用注册功能来写入数据。

本期是该系列的第十一篇,上一篇《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]》我们了解了母版页和部分视图,并使用母版页和部分视图重新组织了页面的共用区域的HTML代码,本文我们将要涉及到的内容为:

写系列文章是一件并不容易的事情,相信有过写系列文章经验朋友也应该有所体会。

本文由永利皇宫463登录发布于编程,转载请注明出处:一步一步创建ASP

关键词: