最近学习Layui ,就准备通过Layui来实现之前练习的项目,

先创建一个新的Web 空项目,选MVC

新建项目

创建各种类库,模块之间添加引用,并安装必要Nuget包(EF包)

     模块名称            模块之间引用                    安装Nuget包


BizLogic-------业务逻辑      (BizModel.DLL, DataEntity.DLL, Util.DLL)                      entityframework


BizModel------实体类    


DataEntity-----DB映射模块             (Util.DLL)                     entityframework 


Util---------------公共类库


Web--------------界面UI     (BizLogic.DLL, BizModel.DLL, DataEntity.DLL, Util.DLL)       entityframework

创建并生成EF

中小项目 可以直接关闭懒加载

连接DB配置,移动到UI层

下面编写公共方法

DataResult.cs ------------通用数据结果类

PagedResult.cs----------分页通过数据结果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CarterHotel.Util
{
/// <summary>
/// 通用数据结果类
/// </summary>
/// <typeparam name="TModel"></typeparam>
public class DataResult<TModel>
{
/// <summary>
/// 操作是否成功
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 错误提示信息
/// </summary>
public string ErrorMessage { get; set; }
/// <summary>
/// 数据结果
/// </summary>
public TModel Data { get; set; } public DataResult()
{
IsSuccess = true;
} public DataResult(string errorMessage)
{
IsSuccess = false;
ErrorMessage = errorMessage;
} public DataResult(TModel data)
{
IsSuccess = true;
Data = data;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CarterHotel.Util
{
/// <summary>
/// 分页通过数据结果
/// </summary>
public class PagedResult<TModel>:DataResult<TModel>//继承DataResult
{
/// <summary>
/// 当前页索引
/// </summary>
public int PageIndex { get; set; } /// <summary>
/// 每页记录条数
/// </summary>
public int PageSize { get; set; } /// <summary>
/// 数据记录条数
/// </summary>
public int TotalCount { get; set; } /// <summary>
/// 当前页数据
/// </summary>
public List<TModel> CurrentPageData { get; set; } public PagedResult(int pageIndex, int pageSize, int totalCount, List<TModel> currentPageData)
{
IsSuccess = true;
PageIndex = pageIndex;
TotalCount = totalCount;
CurrentPageData = currentPageData;
} public PagedResult(int totalCount, List<TModel> currentPageData)
{
IsSuccess = true;
TotalCount = totalCount;
CurrentPageData = currentPageData;
}
}
}

创建EncryptionMD5.cs 单向MD5加密

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace CarterHotel.Util
{
/// <summary>
/// MD5
/// 单向加密
/// </summary>
public class EncryptionMD5
{
/// <summary>
/// 获得一个字符串的加密密文
/// 此密文为单向加密,即不可逆(解密)密文
/// </summary>
/// <param name="plainText">待加密明文</param>
/// <returns>已加密密文</returns>
public static string EncryptString(string plainText)
{
return EncryptStringMD5(plainText);
} /// <summary>
/// 获得一个字符串的加密密文
/// 此密文为单向加密,即不可逆(解密)密文
/// </summary>
/// <param name="plainText">待加密明文</param>
/// <returns>已加密密文</returns>
public static string EncryptStringMD5(string plainText)
{
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(plainText));
StringBuilder encryptText = new StringBuilder();
for (int i = ; i < data.Length; i++)
{
encryptText.Append(data[i].ToString("x2"));
}
return encryptText.ToString(); } /// <summary>
/// 判断明文与密文是否相符
/// </summary>
/// <param name="plainText">待检查的明文</param>
/// <param name="encryptText">待检查的密文</param>
/// <returns>bool</returns>
public static bool EqualEncryptString(string plainText, string encryptText)
{
return EqualEncryptStringMD5(plainText, encryptText);
} /// <summary>
/// 判断明文与密文是否相符
/// </summary>
/// <param name="plainText">待检查的明文</param>
/// <param name="encryptText">待检查的密文</param>
/// <returns>bool</returns>
public static bool EqualEncryptStringMD5(string plainText, string encryptText)
{
bool result = false;
if (string.IsNullOrEmpty(plainText) || string.IsNullOrEmpty(encryptText))
return result;
result = EncryptStringMD5(plainText).Equals(encryptText);
return result;
}
}
}

接下来对公共错误页面的编写

在UI层新建StaticContent文件夹 并将下载好的Layui 样式 js 文件放到文件夹下,并添加对应的视图,异常处理过滤器

下面 错误页面html代码

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>错误提示</title>
<link href="~/StaticContent/layui/css/layui.css" rel="stylesheet" />
<style>
.layadmin-tips {
margin-top: 30px;
text-align: center
} .layadmin-tips .layui-icon[face] {
display: inline-block;
font-size: 300px;
color: #393D49;
} .layadmin-tips .layui-text {
width: 500px;
margin: 30px auto;
padding-top: 20px;
border-top: 5px solid #009688;
font-size: 22px
}
</style>
</head>
<body>
<div class="layui-fluid">
<div class="layadmin-tips">
<i class="layui-icon layui-icon-face-surprised" face></i>
<div class="layui-text">好像出错了</div>
</div>
</div>
</body>
</html>

增加异常处理过滤器 App_Start 新创建Filter-->HandleExceptionFileterAttribute类 并实现IExceptionFilter 接口;

2,在App_Start 下创建FilterConfig 过滤器配置类,并注册过滤器

代码如下

using CarterHotel.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace CarterHotel.Web.App_Start.Filters
{
/// <summary>
/// 异常处理过滤器
/// </summary>
public class HandleExceptionFileterAttribute : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
//判断当前的请求是否为ajax
bool isAjaxRequest = filterContext.HttpContext.Request.IsAjaxRequest();
if (isAjaxRequest)
{
filterContext.Result = new JsonResult()
{
Data = new DataResult<string>(errorMessage: "系统发生错误")
};
}
else
{
filterContext.Result = new RedirectResult(url: "/Error");
} //异常发生后,进行处理以后,需要告诉应用程序,这个异常处理意见处理过了
filterContext.ExceptionHandled = true;
}
}
}

注册过滤器

using CarterHotel.Web.App_Start.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace CarterHotel.Web.App_Start
{
/// <summary>
/// 过滤器配置类
/// </summary>
public static class FilterConfig
{
/// <summary>
/// 过滤器注册
/// </summary>
/// <param name="filters"></param>
public static void RegisterFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionFileterAttribute());
}
}
}

控制器里增加Home控制器

此时此刻公共错误页面已经完成,我们可以测试,公共错误页面是否有问题;

JS文件

StaticContent-->scripts-->unobtrusive.js(内容如下)

layui.define(["jquery"], function (exports) {
var jQuery = layui.jquery; (function ($) {
var data_click = "unobtrusiveAjaxClick",
data_target = "unobtrusiveAjaxClickTarget",
data_validation = "unobtrusiveValidation"; function getFunction(code, argNames) {
var fn = window, parts = (code || "").split(".");
while (fn && parts.length) {
fn = fn[parts.shift()];
}
if (typeof (fn) === "function") {
return fn;
}
argNames.push(code);
return Function.constructor.apply(null, argNames);
} function isMethodProxySafe(method) {
return method === "GET" || method === "POST";
} function asyncOnBeforeSend(xhr, method) {
if (!isMethodProxySafe(method)) {
xhr.setRequestHeader("X-HTTP-Method-Override", method);
}
} function asyncOnSuccess(element, data, contentType) {
var mode; if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
return;
} mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
$(element.getAttribute("data-ajax-update")).each(function (i, update) {
var top; switch (mode) {
case "BEFORE":
top = update.firstChild;
$("<div />").html(data).contents().each(function () {
update.insertBefore(this, top);
});
break;
case "AFTER":
$("<div />").html(data).contents().each(function () {
update.appendChild(this);
});
break;
case "REPLACE-WITH":
$(update).replaceWith(data);
break;
default:
$(update).html(data);
break;
}
});
} function asyncRequest(element, options) {
var confirm, loading, method, duration; confirm = element.getAttribute("data-ajax-confirm");
if (confirm && !window.confirm(confirm)) {
return;
} loading = $(element.getAttribute("data-ajax-loading"));
duration = parseInt(element.getAttribute("data-ajax-loading-duration"), 10) || 0; $.extend(options, {
type: element.getAttribute("data-ajax-method") || undefined,
url: element.getAttribute("data-ajax-url") || undefined,
cache: !!element.getAttribute("data-ajax-cache"),
beforeSend: function (xhr) {
var result;
asyncOnBeforeSend(xhr, method);
result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(element, arguments);
if (result !== false) {
loading.show(duration);
}
return result;
},
complete: function () {
loading.hide(duration);
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments);
},
success: function (data, status, xhr) {
asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(element, arguments);
},
error: function () {
getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(element, arguments);
}
}); options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" }); method = options.type.toUpperCase();
if (!isMethodProxySafe(method)) {
options.type = "POST";
options.data.push({ name: "X-HTTP-Method-Override", value: method });
} $.ajax(options);
} function validate(form) {
var validationInfo = $(form).data(data_validation);
return !validationInfo || !validationInfo.validate || validationInfo.validate();
} $(document).on("click", "a[data-ajax=true]", function (evt) {
evt.preventDefault();
asyncRequest(this, {
url: this.href,
type: "GET",
data: []
});
}); $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
var name = evt.target.name,
target = $(evt.target),
form = $(target.parents("form")[0]),
offset = target.offset(); form.data(data_click, [
{ name: name + ".x", value: Math.round(evt.pageX - offset.left) },
{ name: name + ".y", value: Math.round(evt.pageY - offset.top) }
]); setTimeout(function () {
form.removeData(data_click);
}, 0);
}); $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
var name = evt.currentTarget.name,
target = $(evt.target),
form = $(target.parents("form")[0]); form.data(data_click, name ? [{ name: name, value: evt.currentTarget.value }] : []);
form.data(data_target, target); setTimeout(function () {
form.removeData(data_click);
form.removeData(data_target);
}, 0);
}); $(document).on("submit", "form[data-ajax=true]", function (evt) {
var clickInfo = $(this).data(data_click) || [],
clickTarget = $(this).data(data_target),
isCancel = clickTarget && clickTarget.hasClass("cancel");
evt.preventDefault();
if (!isCancel && !validate(this)) {
return;
}
asyncRequest(this, {
url: this.action,
type: this.method || "GET",
data: clickInfo.concat($(this).serializeArray())
});
});
}(jQuery));
exports('unobtrusive',null)
});

StaticContent\image\user.png 图片如下

二, 实现基于layui前台页面后台管理的搭建

1, 添加区域

2, 在Shared-->_Layout.cshtml  (新增)

3, Views-->_ViewStart.cshtml   (新增)

_Layout.cshtml

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>后台管理</title>
<link href="~/StaticContent/layui/css/layui.css" rel="stylesheet" />
@RenderSection("styles",false)
</head>
<body>
@RenderBody()
<script src="~/StaticContent/layui/layui.js"></script>
<script type="text/javascript"> </script>
@RenderSection("scripts",false);
</body>
</html>

_ViewStart.cshtml

@{ 

    Layout = "~/Areas/Manage/Views/Shared/_Layout.cshtml";
}

在增加的区域里控制器增加Main控制器,并添加对应的视图

视图代码

<body class="layui-layout-body">
<div class="layui-layout-admin">
<!--头部内容-->
<div class="layui-header">
<div class="layui-logo">后台管理</div>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="#">
<img src="~/StaticContent/image/user.png" class="layui-nav-img" /> Admin
</a>
<dl class="layui-nav-child">
<dd><a href="#">修改密码</a></dd>
<dd><a href="#">退出登入</a></dd>
</dl>
</li>
</ul>
</div>
<!--侧边导航-->
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<ul class="layui-nav layui-nav-tree">
<li class="layui-nav-item">
<a href="javascript:;">
<i class="layui-icon layui-icon-home">主页</i>
</a>
</li>
</ul>
</div>
</div>
<!--主内容区-->
<div class="layui-body" style="overflow:hidden">
<iframe src="https://www.baidu.com/" frameborder="0" style="height:100%;width:100%"></iframe>
</div>
<!--底部区域-->
<div class="layui-footer">
©1999-2020 个人开发
</div>
</div>
</body>
@section Scripts
{
<script type="text/javascript">
layui.use('element')
</script>
}

运行测试,整个页面已经搭建了7788,运行页面如下

三,实现登入功能

Layui+MVC+EF (项目从新创建开始)的更多相关文章

  1. Jexus 安装asp.net mvc EF 项目引发的错误总

    1.Linux 中的文件路径问题(配置文件路径),必须使用左斜杆 “/” 2.MVC 看 View/Web.config 下的配置文件中版本不对报错,如下: Could not locate Razo ...

  2. MVC+Ef项目(1) 项目的框架搭建

    一:首先我们来搭建最基本的项目框架,这里使用MVC3作为web项目,然后我们添加几个类库项目 最后的项目如下, 其中有一个 YouJiao.MvcWeb.Repository 实际就当做是 DAL层即 ...

  3. MVC+Ef项目(4) 抽象业务逻辑层BLL层

    接下来,我们就要到业务逻辑层了,简单的说,业务逻辑层就是调用Repository(可以看做是DAL数据库访问层) 先来看看项目的架构 我们现在就开始来做BLL层.  同样,先编写  UserInfoS ...

  4. MVC+Ef项目(3) 抽象数据库访问层的统一入口;EF上下文线程内唯一

    抽象一个数据库访问层的统一入口(类似于EF的上下文,拿到上下文,就可以拿到所有的表).实际这个入口就是一个类,类里面有所有的仓储对应的属性.这样,只要拿到这个类的实例,就可以点出所有的仓储,我们在 R ...

  5. MVC+Ef项目(2) 如何更改项目的生成顺序;数据库访问层Repository仓储层的实现

    我们现在先来看看数据库的生成顺序   居然是 Idal层排在第一,而 web层在第二,model层反而在第三 了   我们需要把 coomon 公用层放在第一,Model层放在第二,接下来是 Idal ...

  6. 规范化创建一个vs2017 Mvc框架项目

    vs2107 + dapper + MiniUi 标准化分层封装使 3.1 规范化创建一个vs2017 Mvc框架项目 此时创建的项目勾选 添加单元测试. 添加一个类库,主要用于实体类操作,类库名称 ...

  7. ASP.NET Core MVC+Layui使用EF Core连接MySQL执行简单的CRUD操作

    前言: 本章主要通过一个完整的示例讲解ASP.NET Core MVC+EF Core对MySQL数据库进行简单的CRUD操作,希望能够为刚入门.NET Core的小伙伴们提供一个完整的参考实例.关于 ...

  8. Contoso 大学 - 使用 EF Code First 创建 MVC 应用

    原文 Contoso 大学 - 使用 EF Code First 创建 MVC 应用 Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Co ...

  9. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式 进行本次文章之前,我们可能需要补充一些 ...

随机推荐

  1. VSCode, 当今最流行的免费开源代码编辑器,微软出品,必属精品

    什么是VSCode? Visual Studio Code是一个轻量级但功能强大的源代码编辑器,可在您的桌面上运行,并且可用于Windows,macOS和Linux.它内置了对JavaScript,T ...

  2. redis(十四):Redis 有序集合(sorted set)

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  3. Spring Boot Redis 实现分布式锁,真香!!

    之前看很多人手写分布式锁,其实 Spring Boot 现在已经做的足够好了,开箱即用,支持主流的 Redis.Zookeeper 中间件,另外还支持 JDBC. 本篇栈长以 Redis 为例(这也是 ...

  4. js 分享QQ、QQ空间、微信、微博

    //分享QQ好友 function qq(title,url,pic) { var p = { url: 'http://test.qicheyitiao.com',/*获取URL,可加上来自分享到Q ...

  5. js中实现继承的方法

    目录 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承 借用构造函数 这种技术的基本思想很简单,就是在子类型构造函数的内部调用超类型的构造函数.另外,函数只不过是在特定环境中执行代码的对 ...

  6. Spring IoC深入理解

    本文相关代码(来自官方源码spring-test模块)请参见spring-demysify org.springframework.mylearntest包下. 三种注入方式 1.构造方法注入 pub ...

  7. CI/CD系列之阿里云云效2020应用篇

    目录 前言 实战 制品仓库 maven配置 项目pom配置 代码管理 流水线 参考资料 前言 前不久登录阿里云后台,看到云效的介绍,出于好奇便点进去看了看,刚开始以为云效是类似Jenkins的一套自动 ...

  8. 设计模式:mediator模式

    目的:解决多组件之间的通信问题,使得组件之间的通信变得简单 核心:提供一个管理类,用来处理组件之间的通信,所有的组件只和管理类通信,组件彼此之间不在单独通信 例子: class Mediator { ...

  9. UVA1104 芯片难题 Chips Challenge

    题目链接 题意 网格上放点,有些强制放,有些不能放,有些可以放可以不放.要求: 第 \(i\) 行的点数 = 第 \(i\) 列的点数 每一行每一列的点数不超过总点数的 \(k\) 倍(\(k\) 已 ...

  10. 题解 洛谷 P4112 【[HEOI2015]最短不公共子串】

    给定两个字符串\(A\)和\(B\),我们需要找出一个串,其在\(A\)中出现且不在\(B\)中出现,这个串为子串或者子序列,求在每种情况下,该串的最短长度. 考虑到后缀自动机可以识别一个字符串的所有 ...