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