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模式 进行本次文章之前,我们可能需要补充一些 ...
随机推荐
- JVM 专题十八:垃圾回收(二)垃圾回收相关算法
1. 标记阶段 1.1 引用计数算法 1.1.1 对象存活判断 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象.只有被标记为己 ...
- selenium:selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.
可用链接: 1.http://blog.csdn.net/heatdeath/article/details/71136174 2.https://www.cnblogs.com/yousuosiys ...
- 李航统计学习方法(第二版)(十):决策树CART算法
1 简介 1.1 介绍 1.2 生成步骤 CART树算法由以下两步组成:(1)决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;(2)决策树剪枝:用验证数据集对己生成的树进行剪枝并选择最优子 ...
- Django之 Models组件
本节内容 路由系统 models模型 admin views视图 template模板 引子 讲django的models之前, 先来想一想, 让你通过django操作数据库,你怎么做? 做苦思冥想, ...
- 接口测试框架实战(三)| JSON 请求与响应断言
关注公众号,获取测试开发实战干货合辑.本文节选自霍格沃兹<测试开发实战进阶>课程教学内容. 数据驱动就是通过数据的改变驱动自动化测试的执行,最终引起测试结果的改变.简单来说,就是参数化在自 ...
- 关于JS深拷贝和浅拷贝
最近在前端开发中遇到一些问题,就是数组中的某个对象或某个对象的值改变之后,在不刷新页面的时候需要重新渲染值时,页面显示的还是原来的数据.比如: data{ A:[{id:1,num:1},{id:2, ...
- Go Pentester - HTTP CLIENTS(3)
Interacting with Metasploit Early-stage Preparation: Setting up your environment - start the Metaspl ...
- Spark实现wordcount的几种方式
方法一:map + reduceByKey package com.cw.bigdata.spark.wordcount import org.apache.spark.rdd.RDD import ...
- hibearnate的一级缓存和二级缓存的功能
首先要明白缓存是干什么的,缓存就是要将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能.再说明一级与二级缓存的作用:一级缓存是Sessi ...
- JVM系列之:对象的锁状态和同步
目录 简介 java对象头 java中锁状态的变化 偏向锁biased locking 轻量级锁thin lock 重量级锁 三种锁状态的不同 简介 锁和同步是java多线程编程中非常常见的使用场景. ...