中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用MVC構架進行項目結構搭建

發布時間:2021-12-13 09:52:40 來源:億速云 閱讀:158 作者:柒染 欄目:開發技術

本篇文章給大家分享的是有關如何用MVC構架進行項目結構搭建,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

一、前言

下面將使用代碼的方式來一一解說各個層次。由于要搭建一個基本完整的結構,可能文章會比較長。另外出于實用的目的,因而并不會嚴格按照傳統的三層那樣進行非常明確的層次職能劃分。

二、需求說明

為方便大家理解,將以一個賬戶管理的小系統來進行解說,具體需求如下:

  1. 用戶信息分主要信息與擴展信息,一個用戶可以有(或沒有)一個用戶擴展信息。

  2. 記錄用戶的登錄記錄,一個用戶可以有多條登錄記錄,但登錄記錄所屬用戶唯一。

  3. 一個用戶可以有多個角色,一個角色也可以分配給多個用戶。

三、架構基礎

(一) 功能返回值

對于一個操作性業務功能(比如添加,修改,刪除),通常我們處理返回值的做法是使用簡單類型,通常會有如下幾種方案:

  1. 直接返回void,即什么也不返回,在操作過程中拋出異常,只要沒有異常拋出,就認為是操作成功了

  2. 返回是否操作成功的bool類型的返回值

  3. 返回操作變更后的新數據信息

  4. 返回表示各種結果的狀態碼的返回值

  5. 返回一個自定義枚舉來表示操作的各種結果

  6. 如果要返回多個值,還要使用 out 來添加返回參數

這樣做有什么不妥之處呢,我們來逐一分析:

  1. 靠拋異常的方式來終止系統的運行,異常是沿調用堆棧逐層向上拋出的,會造成很大的性能問題

  2. bool值太死板,無法表示出業務操作中的各種情況

  3. 返回變更后的數據,還要與原始數據來判斷才能得到是否操作成功

  4. 用狀態碼解決了2的問題,但各種狀態碼的維護成本也會非常高

  5. 用枚舉值一定程序上解決了翻譯的問題,但還是要把枚舉值翻譯成各種情況的文字描述

綜上,我們到底需要一個怎樣的業務操作結果呢?

  1. 要能表示操作的成功失敗(廢話)

  2. 要能快速表示各種操作場景(如參數錯誤,查詢數據不存在,數據狀態不滿足操作要求等)

  3. 能返回附加的返回信息(如更新成功后有后續操作,需要使用更新后的新值)

  4. 最好在調用方能使用統一的代碼進行返回值處理

  5. 最好能自定義返回的文字描述信息

  6. 最好能把返回給用戶的信息與日志記錄的信息分開

再綜上,顯然簡單類型的返回值滿足不了需求了,那就需要定義一個專門用來封裝返回值信息的返回值類,這里定義如下:

/// <summary>       ///     業務操作結果信息類,對操作結果進行封裝       /// </summary>       public class OperationResult       {           #region 構造函數              /// <summary>           ///     初始化一個 業務操作結果信息類 的新實例           /// </summary>           /// <param name="resultType">業務操作結果類型</param>           public OperationResult(OperationResultType resultType)           {               ResultType = resultType;           }              /// <summary>           ///     初始化一個 定義返回消息的業務操作結果信息類 的新實例           /// </summary>           /// <param name="resultType">業務操作結果類型</param>           /// <param name="message">業務返回消息</param>           public OperationResult(OperationResultType resultType, string message)               : this(resultType)           {               Message = message;           }              /// <summary>           ///     初始化一個 定義返回消息與附加數據的業務操作結果信息類 的新實例           /// </summary>           /// <param name="resultType">業務操作結果類型</param>           /// <param name="message">業務返回消息</param>           /// <param name="appendData">業務返回數據</param>           public OperationResult(OperationResultType resultType, string message, object appendData)               : this(resultType, message)           {               AppendData = appendData;           }              /// <summary>           ///     初始化一個 定義返回消息與日志消息的業務操作結果信息類 的新實例           /// </summary>           /// <param name="resultType">業務操作結果類型</param>           /// <param name="message">業務返回消息</param>           /// <param name="logMessage">業務日志記錄消息</param>           public OperationResult(OperationResultType resultType, string message, string logMessage)               : this(resultType, message)           {               LogMessage = logMessage;           }              /// <summary>           ///     初始化一個 定義返回消息、日志消息與附加數據的業務操作結果信息類 的新實例           /// </summary>           /// <param name="resultType">業務操作結果類型</param>           /// <param name="message">業務返回消息</param>           /// <param name="logMessage">業務日志記錄消息</param>           /// <param name="appendData">業務返回數據</param>           public OperationResult(OperationResultType resultType, string message, string logMessage, object appendData)               : this(resultType, message, logMessage)           {               AppendData = appendData;           }              #endregion              #region 屬性              /// <summary>           ///     獲取或設置 操作結果類型           /// </summary>           public OperationResultType ResultType { get; set; }              /// <summary>           ///     獲取或設置 操作返回信息           /// </summary>           public string Message { get; set; }              /// <summary>           ///     獲取或設置 操作返回的日志消息,用于記錄日志           /// </summary>           public string LogMessage { get; set; }              /// <summary>           ///     獲取或設置 操作結果附加信息           /// </summary>           public object AppendData { get; set; }              #endregion       }

再定義一個表示業務操作結果的枚舉,枚舉項上有一個DescriptionAttribute的特性,用來作為當上面的Message為空時的返回結果描述。

/// <summary>       ///     表示業務操作結果的枚舉       /// </summary>       [Description("業務操作結果的枚舉")]       public enum OperationResultType       {           /// <summary>           ///     操作成功           /// </summary>           [Description("操作成功。")]           Success,              /// <summary>           ///     操作取消或操作沒引發任何變化           /// </summary>           [Description("操作沒有引發任何變化,提交取消。")]           NoChanged,              /// <summary>           ///     參數錯誤           /// </summary>           [Description("參數錯誤。")]           ParamError,              /// <summary>           ///     指定參數的數據不存在           /// </summary>           [Description("指定參數的數據不存在。")]           QueryNull,              /// <summary>           ///     權限不足           /// </summary>           [Description("當前用戶權限不足,不能繼續操作。")]           PurviewLack,              /// <summary>           ///     非法操作           /// </summary>           [Description("非法操作。")]           IllegalOperation,              /// <summary>           ///     警告           /// </summary>           [Description("警告")]           Warning,              /// <summary>           ///     操作引發錯誤           /// </summary>           [Description("操作引發錯誤。")]           Error,       }

(二) 實體基類

對于業務實體,有一些相同的且必要的信息,比如信息的創建時間,總是必要的;再比如想讓數據庫有一個“回收站”的功能,以給數據刪除做個緩沖,或者很多數據并非想從數據庫中徹底刪除掉,只是暫時的“禁用”一下,添加個邏輯刪除的標記也是必要的。再有就是想給所有實體數據倉儲操作來個類型限定,以防止傳入了其他非實體類型。基于以上理由,就有了下面這個實體基類:

/// <summary>       ///     可持久到數據庫的領域模型的基類。       /// </summary>       [Serializable]       public abstract class Entity       {           #region 構造函數              /// <summary>           ///     數據實體基類           /// </summary>           protected Entity()           {               IsDeleted = false;               AddDate = DateTime.Now;           }              #endregion              #region 屬性              /// <summary>           ///     獲取或設置 獲取或設置是否禁用,邏輯上的刪除,非物理刪除           /// </summary>           public bool IsDeleted { get; set; }              /// <summary>           ///     獲取或設置 添加時間           /// </summary>           [DataType(DataType.DateTime)]           public DateTime AddDate { get; set; }              /// <summary>           ///     獲取或設置 版本控制標識,用于處理并發           /// </summary>           [ConcurrencyCheck]           1621913756           public byte[] Timestamp { get; set; }              #endregion       }

這里要補充一下,本來實體基類中是可以定義一個表示“實體編號”的Id屬性的,但有個問題,如果定義了,就限定了Id屬性的數據類型了,但實際需求中可能有些實體使用自增的int類型,有些實體使用的是易于數據合并的guid類型,因此為靈活方便,不在此限制住 Id的數據類型。

四、架構分層

具體的架構分層如下圖所示:

如何用MVC構架進行項目結構搭建

(一) 核心業務層

根據 需求說明 中定義的需求,簡單起見,這里只實現一個簡單的用戶登錄功能:

用戶信息實體:

/// <summary>       ///     實體類&mdash;&mdash;用戶信息       /// </summary>       [Description("用戶信息")]       public class Member : Entity       {           /// <summary>           /// 獲取或設置 用戶編號           /// </summary>           public int Id { get; set; }              /// <summary>           /// 獲取或設置 用戶名           /// </summary>           [Required]           [StringLength(20)]           public string UserName { get; set; }              /// <summary>           /// 獲取或設置 密碼           /// </summary>           [Required]           [StringLength(32)]           public string Password { get; set; }              /// <summary>           /// 獲取或設置 用戶昵稱           /// </summary>           [Required]           [StringLength(20)]           public string NickName { get; set; }              /// <summary>           /// 獲取或設置 用戶郵箱           /// </summary>           [Required]           [StringLength(50)]           public string Email { get; set; }              /// <summary>           /// 獲取或設置 用戶擴展信息           /// </summary>           public virtual MemberExtend Extend { get; set; }              /// <summary>           /// 獲取或設置 用戶擁有的角色信息集合           /// </summary>           public virtual ICollection<Role> Roles { get; set; }              /// <summary>           /// 獲取或設置 用戶登錄記錄集合           /// </summary>           public virtual ICollection<LoginLog> LoginLogs { get; set; }       }

核心業務契約:注意接口的返回值使用了上面定義的返回值類

/// <summary>       ///     賬戶模塊核心業務契約       /// </summary>       public interface IAccountContract       {           /// <summary>           /// 用戶登錄           /// </summary>           /// <param name="loginInfo">登錄信息</param>           /// <returns>業務操作結果</returns>           OperationResult Login(LoginInfo loginInfo);       }

核心業務實現:核心業務實現類為抽象類,因沒有數據訪問功能,這里使用了一個Members字段來充當數據源,業務功能的實現為虛方法,必要時可以在具體的客戶端(網站、桌面端,移動端)相應的派生類中進行重寫。請注意具體實現中對于返回值的處理。這里登錄只負責最核心的登錄業務操作,不涉及比如Http上下文狀態的操作。

/// <summary>       ///     賬戶模塊核心業務實現       /// </summary>       public abstract class AccountService : IAccountContract       {           private static readonly Member[] Members = new[]           {               new Member { UserName = "admin", Password = "123456", Email = "admin@gmfcn.net", NickName = "管理員" },               new Member { UserName = "gmfcn", Password = "123456", Email = "mf.guo@qq.com", NickName = "郭明鋒" }           };              private static readonly List<LoginLog> LoginLogs = new List<LoginLog>();              /// <summary>           /// 用戶登錄           /// </summary>           /// <param name="loginInfo">登錄信息</param>           /// <returns>業務操作結果</returns>           public virtual OperationResult Login(LoginInfo loginInfo)           {               PublicHelper.CheckArgument(loginInfo, "loginInfo");               Member member = Members.SingleOrDefault(m => m.UserName == loginInfo.Access || m.Email == loginInfo.Access);               if (member == null)               {                   return new OperationResult(OperationResultType.QueryNull, "指定賬號的用戶不存在。");               }               if (member.Password != loginInfo.Password)               {                   return new OperationResult(OperationResultType.Warning, "登錄密碼不正確。");               }               LoginLog loginLog = new LoginLog { IpAddress = loginInfo.IpAddress, Member = member };               LoginLogs.Add(loginLog);               return new OperationResult(OperationResultType.Success, "登錄成功。", member);           }       }

(二) 站點業務層

站點業務契約:站點業務契約繼承核心業務契約,即可擁有核心層定義的業務功能。站點登錄驗證使用了Forms的Cookie驗證,這里的退出不涉及核心層的操作,因而核心層沒有退出功能

/// <summary>       ///     賬戶模塊站點業務契約       /// </summary>       public interface IAccountSiteContract : IAccountContract       {           /// <summary>           ///     用戶登錄           /// </summary>           /// <param name="model">登錄模型信息</param>           /// <returns>業務操作結果</returns>           OperationResult Login(LoginModel model);              /// <summary>           ///     用戶退出           /// </summary>           void Logout();       }

站點業務實現:站點業務實現繼承核心業務實現與站點業務契約,負責把從UI中接收到的視圖模型信息轉換為符合核心層定義的參數,并處理與網站狀態相關的Session,Cookie等Http相關業務

/// <summary>       ///     賬戶模塊站點業務實現       /// </summary>       public class AccountSiteService : AccountService, IAccountSiteContract       {           /// <summary>           ///     用戶登錄           /// </summary>           /// <param name="model">登錄模型信息</param>           /// <returns>業務操作結果</returns>           public OperationResult Login(LoginModel model)           {               PublicHelper.CheckArgument(model, "model");               LoginInfo loginInfo = new LoginInfo               {                   Access = model.Account,                   Password = model.Password,                   IpAddress = HttpContext.Current.Request.UserHostAddress               };               OperationResult result = base.Login(loginInfo);               if (result.ResultType == OperationResultType.Success)               {                   Member member = (Member)result.AppendData;                   DateTime expiration = model.IsRememberLogin                       ? DateTime.Now.AddDays(7)                       : DateTime.Now.Add(FormsAuthentication.Timeout);                   FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, member.UserName, DateTime.Now, expiration,                       true, member.NickName, FormsAuthentication.FormsCookiePath);                   HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));                   if (model.IsRememberLogin)                   {                       cookie.Expires = DateTime.Now.AddDays(7);                   }                   HttpContext.Current.Response.Cookies.Set(cookie);                   result.AppendData = null;               }               return result;           }              /// <summary>           ///     用戶退出           /// </summary>           public void Logout()           {               FormsAuthentication.SignOut();           }       }

(三) 站點展現層

MVC控制器:Action提供統一風格的代碼來對業務操作結果OperationResult進行處理

public class AccountController : Controller       {           public AccountController()           {               AccountContract = new AccountSiteService();           }              #region 屬性              public IAccountSiteContract AccountContract { get; set; }              #endregion              #region 視圖功能              public ActionResult Login()           {               string returnUrl = Request.Params["returnUrl"];               returnUrl = returnUrl ?? Url.Action("Index", "Home", new { area = "" });               LoginModel model = new LoginModel               {                   ReturnUrl = returnUrl               };               return View(model);           }              [HttpPost]           public ActionResult Login(LoginModel model)           {               try              {                   OperationResult result = AccountContract.Login(model);                   string msg = result.Message ?? result.ResultType.ToDescription();                   if (result.ResultType == OperationResultType.Success)                   {                       return Redirect(model.ReturnUrl);                   }                   ModelState.AddModelError("", msg);                   return View(model);               }               catch (Exception e)               {                   ModelState.AddModelError("", e.Message);                   return View(model);               }           }              public ActionResult Logout( )           {               string returnUrl = Request.Params["returnUrl"];               returnUrl = returnUrl ?? Url.Action("Index", "Home", new { area = "" });               if (User.Identity.IsAuthenticated)               {                   AccountContract.Logout();               }               return Redirect(returnUrl);           }              #endregion       }

MVC 視圖:

@model GMF.Demo.Site.Models.LoginModel  @{      ViewBag.Title = "Login";      Layout = "~/Views/Shared/_Layout.cshtml";  }  <h3>Login</h3>  @using (Html.BeginForm()) {      @Html.AntiForgeryToken()      @Html.ValidationSummary(true)      <fieldset>          <legend>LoginModel</legend>          <div class="editor-label">              @Html.LabelFor(model => model.Account)          </div>          <div class="editor-field">              @Html.EditorFor(model => model.Account)              @Html.ValidationMessageFor(model => model.Account)          </div>          <div class="editor-label">              @Html.LabelFor(model => model.Password)          </div>          <div class="editor-field">              @Html.EditorFor(model => model.Password)              @Html.ValidationMessageFor(model => model.Password)          </div>          <div class="editor-label">              @Html.LabelFor(model => model.IsRememberLogin)          </div>          <div class="editor-field">              @Html.EditorFor(model => model.IsRememberLogin)              @Html.ValidationMessageFor(model => model.IsRememberLogin)          </div>          @Html.HiddenFor(m => m.ReturnUrl)          <p>              <input type="submit" value="登錄" />          </p>      </fieldset>  }  <div>      @Html.ActionLink("Back to List", "Index", "Home")  </div>  @section Scripts {      @Scripts.Render("~/bundles/jqueryval")  }

至此,整個項目構架搭建完成,運行結果如下:
如何用MVC構架進行項目結構搭建 如何用MVC構架進行項目結構搭建

以上就是如何用MVC構架進行項目結構搭建,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

mvc
AI

德令哈市| 中超| 泰州市| 镇江市| 海宁市| 文成县| 信丰县| 溆浦县| 庆安县| 郯城县| 当涂县| 绥江县| 泸水县| 陇西县| 吕梁市| 页游| 荆门市| 建昌县| 西乌珠穆沁旗| 罗江县| 五莲县| 乌兰浩特市| 灵山县| 洪泽县| 桦甸市| 平和县| 新建县| 玉林市| 鄢陵县| 建始县| 濮阳县| 惠来县| 平原县| 汾西县| 旬阳县| 同心县| 巴青县| 仲巴县| 衡南县| 奉新县| 沿河|