Layui+MVC+EF (项目从新创建开始)
最近学习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 (项目从新创建开始)的更多相关文章
- Jexus 安装asp.net mvc EF 项目引发的错误总
1.Linux 中的文件路径问题(配置文件路径),必须使用左斜杆 “/” 2.MVC 看 View/Web.config 下的配置文件中版本不对报错,如下: Could not locate Razo ...
- MVC+Ef项目(1) 项目的框架搭建
一:首先我们来搭建最基本的项目框架,这里使用MVC3作为web项目,然后我们添加几个类库项目 最后的项目如下, 其中有一个 YouJiao.MvcWeb.Repository 实际就当做是 DAL层即 ...
- MVC+Ef项目(4) 抽象业务逻辑层BLL层
接下来,我们就要到业务逻辑层了,简单的说,业务逻辑层就是调用Repository(可以看做是DAL数据库访问层) 先来看看项目的架构 我们现在就开始来做BLL层. 同样,先编写 UserInfoS ...
- MVC+Ef项目(3) 抽象数据库访问层的统一入口;EF上下文线程内唯一
抽象一个数据库访问层的统一入口(类似于EF的上下文,拿到上下文,就可以拿到所有的表).实际这个入口就是一个类,类里面有所有的仓储对应的属性.这样,只要拿到这个类的实例,就可以点出所有的仓储,我们在 R ...
- MVC+Ef项目(2) 如何更改项目的生成顺序;数据库访问层Repository仓储层的实现
我们现在先来看看数据库的生成顺序 居然是 Idal层排在第一,而 web层在第二,model层反而在第三 了 我们需要把 coomon 公用层放在第一,Model层放在第二,接下来是 Idal ...
- 规范化创建一个vs2017 Mvc框架项目
vs2107 + dapper + MiniUi 标准化分层封装使 3.1 规范化创建一个vs2017 Mvc框架项目 此时创建的项目勾选 添加单元测试. 添加一个类库,主要用于实体类操作,类库名称 ...
- ASP.NET Core MVC+Layui使用EF Core连接MySQL执行简单的CRUD操作
前言: 本章主要通过一个完整的示例讲解ASP.NET Core MVC+EF Core对MySQL数据库进行简单的CRUD操作,希望能够为刚入门.NET Core的小伙伴们提供一个完整的参考实例.关于 ...
- Contoso 大学 - 使用 EF Code First 创建 MVC 应用
原文 Contoso 大学 - 使用 EF Code First 创建 MVC 应用 Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Co ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式 进行本次文章之前,我们可能需要补充一些 ...
随机推荐
- nuxt.js使用scss
1>安装一些loader npm i node-sass sass-loader scss-loader --save-dev 2>在nuxt.config.js中配置(需要全局使用的sc ...
- electron自定义最小化,最大化和关闭按钮
Electron ipcRenderer 模块 ipcRenderer 模块是一个 EventEmitter 类的实例. 它提供了有限的方法,你可以从渲染进程向主进程发送同步或异步消息. 也可以收到主 ...
- 01 flask源码剖析之werkzurg 了解wsgi
01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...
- 数据可视化实例(十五):有序条形图(matplotlib,pandas)
偏差 (Deviation) 有序条形图 (Ordered Bar Chart) 有序条形图有效地传达了项目的排名顺序. 但是,在图表上方添加度量标准的值,用户可以从图表本身获取精确信息. https ...
- Python 实现邮件发送功能(初级)
在我们日常项目中,会经常使用到邮件的发送功能,如何利用Python发送邮件也是一项必备的技能.本文主要讲述利用Python来发送邮件的一些基本操作. 本章主要包含知识点: 邮件发送原理简述即常用smt ...
- bzoj3378[Usaco2004 Open]MooFest 狂欢节*
bzoj3378[Usaco2004 Open]MooFest 狂欢节 题意: n只奶牛,第i只听力为vi,坐标为xi,两只奶牛聊天时音量是max(vi,vj)*abs(xi-xj).求n(n-1)/ ...
- 六十来行python代码完成一个文件分类器
你的桌面是否像这样的一样被各种文件给堆满了,但是每一个文件又不清楚是否后面还有作用,也不敢删除,自己一个一个转移又太麻烦了.没关系,今天我带大家用python一起来做一个文件归类器,一键进行 ...
- 从零开始学Electron笔记(六)
在之前的文章我们介绍了一下Electron如何通过链接打开浏览器和嵌入网页,接下来我们继续说一下Electron中的对话框 Dialog和消息通知 Notification. 在之前的文章中其实我们是 ...
- [Qt插件]-03创建Qt Designer自定义部件
如何创建自定义部件并添加到Qt Designer来爽快的拖动部件可视化界面设计? Qt Designer基于插件的架构使得它可以使用用户设计或者第三方提供的自定义部件,就像使用标准的Qt部件一样. ...
- P2058 海港 (洛谷)
这个题复制过来真的有点恶心,懒得手打,以后再搬题面吧. 今天我双更了,AC这个题我就完成某谷春令营第一课的作业了(假的) 这个题是个双指针.非常友善.一直往里读入就可以了,遇见不是一条船的乘客输出这一 ...