Layui+MVC+EF (專案從新建立開始)

Victor_huang發表於2020-08-05

最近學習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 = 0; 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,執行頁面如下

 主頁面是用的度娘做的測試,下面我們建立Main頁面

 Main頁面增加,測試OK的

 到這裡我們已經整個框架已經搭建的差不多了,下面將實現具體功能的實現,

一, 實現登入功能

繼續完善中...............

 

相關文章