[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,"測試");
        }      
    }  

留言

這個網誌中的熱門文章

[Visual Studio]位於網際網路或是限制區域上 或是檔案上標有 web 字樣 所以無法處理該檔案。若希望處理這些檔案 請移除 web 字樣。

[IIS] IIS執行時,發生拒絕存取路徑 問題

[windows] xcopy 備份至 「網路磁碟機」