[Mvc] Alert 提示訊息 服務功能 概念與實作
需求:
之前曾開發過一個專案,每次對資料庫做完動作之後,都會用RedirectToAction()的方式,重新載入頁面,我是覺得這個設計方式很有問題啦...畢竟如果執行有問題,那錯誤訊息的顯示只能用Tempdata來處理,而且使用者輸入的頁面資料都會不見。
不過沒辦法,這個專案已經是歷史共業了,只能硬著頭皮做優化了。
這個專案的設計方式是這樣的,如果遇到有錯誤訊息的情況,就會用TempData儲存錯誤訊息,然後在每個view再寫一個javascript去判斷TempData有沒有值,若有值就顯示alert這樣。
這樣的設計方式非常不好,一來重複性的code太多了,二來沒有一個統一的寫法會導致後期維護不易,因此我才想寫一個Alert Service來便於管理。
概念與實作:
大致上的想法就是建立一個「AlertHelper」,將寫入Tempdata的這個動作做集中管理,並且在layout寫一個javascript去判斷TempData有沒有值,這樣就不用每個頁面都有重複性的code,可以統一做管理。
1.建立一個「AlertModel」
public class AlertModel { public AlertType AlertType { get; set; } public string Message { get; set; } public AlertModel(AlertType alertType, string message) { AlertType = alertType; Message = message; } }
2.建立一個列舉 「AlertType」
public enum AlertType { None, Suceess, Information, Warning, Danger }
3.建立「AlertHelper」
public static class AlertHelper { private static readonly string AlertsKey = "_Alerts"; public static List<AlertModel> GetAlerts(this TempDataDictionary temps) { var result = new List<AlertModel>(); if (temps.ContainsKey(AlertsKey)) { result = temps[AlertsKey] as List<AlertModel>; } return result; } public static void AddAlert(this TempDataDictionary temps, AlertModel data) { var alerts = GetAlerts(temps); alerts.Add(data); temps[AlertsKey] = alerts; } public static ActionResult Alert(this ActionResult result, AlertType inAlertType, string inMessage) { return new AlertDecoratorActionResult(result, inAlertType, inMessage); } public static string GetAlertClass(AlertType alertType) { switch (alertType) { default: return string.Empty; case AlertType.Suceess: return "alert-success"; case AlertType.Information: return "alert-info"; case AlertType.Warning: return "alert-warning"; case AlertType.Danger: return "alert-danger"; } } public static MvcHtmlString CheckAlert(this HtmlHelper htmlHelper, TempDataDictionary temps) { var alerts = temps.GetAlerts(); if (!alerts.Any()) { return new MvcHtmlString(string.Empty); } var content = string.Join("\\n", alerts.Select(x => x.Message.ToString())); var alertClass = GetAlertClass(alerts.FirstOrDefault().AlertType); var path = @"D:\Test\TestConsole\TestConsole\MVCTest\Helpers\AlertService\Tamplate.html"; var template = File.ReadAllText(path); template=template.Replace("{Content}", content); template=template.Replace("{AlertClass}", alertClass); return new MvcHtmlString(template); } }
ps:CheckAlert()方法用來在頁面上生成提示視窗的modal
Tamplate.html
<div id="AlertMessageModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">提示訊息</h4> </div> <div class="modal-body"> <div class="alert {AlertClass}"> {Content}</div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">關閉</button> </div> </div> </div> </div>
4.建立一個「AlertDecoratorActionResult」繼承「ActionResult」
public class AlertDecoratorActionResult : ActionResult { private ActionResult InnerResult { get; set; } private AlertType AlertType { get; set; } private string Message { get; set; } public AlertDecoratorActionResult(ActionResult inInnerResult, AlertType inAlertType, string inMessage) { this.InnerResult = inInnerResult; this.AlertType = inAlertType; this.Message = inMessage; } public override void ExecuteResult(ControllerContext context) { var model = new AlertModel(this.AlertType, this.Message); context.Controller.TempData.AddAlert(model); this.InnerResult.ExecuteResult(context); } }
5.Layout設定
functions.js
$(document).ready(function () { CheckAlert(); }); function CheckAlert() { var alert = $('#AlertMessageModal'); if (alert != undefined) { alert.modal('show'); } }
使用方法:
直接在ActionResult之後加上Alert()填寫欲提示的訊息即可。
public class HomeController : Controller { public ActionResult Index() { return RedirectToAction("Index","Test").Alert(AlertType.Suceess,"測試"); } }
留言
張貼留言