2017-11-14 19 views
0

私はAlertify.jsを使用して、私のビューに確認メッセージなどを表示します。私はコントローラからのメッセージを渡すための良い方法を見つけるのに苦労してきました。ビューへのメッセージの受け渡し

TempDataを使用したjanky-feeling設定がありますが、リダイレクトではなく、ビューを返す場合に限り、かなり役に立たなくなります。

私は当初、この機能を基本ビューモデルに追加しようとしていましたが、RedirectToActionはビューモデルを渡すことをサポートしていません。

TempDataスティックを長くするか、別のプロセスを使用する必要があります。

私が今使用します。

public class AlertifyMessages 
{ 
    public List<AlertifyMessage> Messages { get; private set; } = new List<AlertifyMessage>(); 
    public void Add(AlertifyType type, string message, string callbackUrl = null) 
    { 
     Messages.Add(new AlertifyMessage(type, message, callbackUrl)); 
    } 
} 

public class AlertifyMessage 
{ 
    public AlertifyType Type { get; set; } 
    public string Message { get; set; } 
    public string CallbackUrl { get; set; } 
    public AlertifyMessage(AlertifyType type, string message, string callbackUrl) 
    { 
     Type = type; 
     Message = message; 
     CallbackUrl = callbackUrl; 
    } 
} 

public enum AlertifyType 
{ 
    Log, 
    Error, 
    Success 
} 

/// <summary> 
/// Applies Alertify messages to TempData after action method runs 
/// <para>Can only be used with <see cref="BaseController"/></para> 
/// </summary> 
public class AlertifyAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext context) 
    { 
     BaseController bc = (BaseController)context.Controller; 
     bc.TempData["Alertify"] = bc.AlertifyMessages; 
    } 
} 

[Alertify] 
public class BaseController : Controller 
{ 
    public BaseController() 
    { 
     AlertifyMessages = new AlertifyMessages(); 
    } 

    public AlertifyMessages AlertifyMessages { get; set; } 
} 

使用法:

public class MyController : BaseController 
{ 
    public ActionResult Index() 
    { 
     AlertifyMessages.Add(AlertifyType.Success, "Yay!", Url.Action("Index")); 
     return View(/*new ViewModel()*/); 
    } 
} 
// Then loop through and display messages in view using TempData 

編集
受け入れ答えが正しいですが、リファクタリングのトンを避けるためには、私はちょうど私に別のフィルタを追加しました属性:

private const string alertify = "Alertify"; 
public override void OnActionExecuting(ActionExecutingContext context) 
{ 
    BaseController bc = (BaseController)context.Controller; 
    bc.Messages = (bc.TempData[alertify] == null) ? new AlertifyMessages() : (AlertifyMessages)bc.TempData[alertify]; 
    // Faster? Better? Harder? Stronger? 
    //bc.Messages = (AlertifyMessages)bc.TempData[alertify] ?? new AlertifyMessages(); 
} 
+2

TempDataはリダイレクトを処理する必要があります。なぜそれは動作していないと思いますか?発行しているコードを共有できますか? – Shyju

+0

@Shyju私はビューを返す場合に動作し、リダイレクトを返す場合は動作しません。私はその属性がそのtempdataエントリを再割り当てして、ビューに与えられる前に既存のものが失われると思います。私はちょうどこれを行う方法がわからない。 – Sinjai

答えて

2

現在のコードでは、OnResultExecutingはリダイレクトの過程で2回実行されます。

あなたはSaveアクションメソッドから結果を返すとき、それはのAlertifyMessagesプロパティ値の読み込みwhichsあなたAlertifyMessagesフィルタのOnResultExecuting方法を実行します。ここ

public ActionResult Save(SomeViewModel model) 
{ 
    AlertifyMessages.Add(AlertifyType.Success, "Yay!", Url.Action("Index")); 
    return RedirectToAction("Index"); 
} 
public ActionResult Index() 
{ 
    return View(); 
} 

、あなたがこのようにリダイレクトやっているとしましょうTempDataに設定します。

は今、それがリダイレクト応答であるため、お使いのブラウザはIndexアクションに新たなGETリクエストを発行します、そして、また、そのアクションメソッドのために、それはOnResultExecuting内のコードを実行し、それはAlertifyMessagesプロパティを読み取ろうとすることを設定します〜TempData。しかし、AlertifyMessagesはあなたのIndexアクションメソッドでそれを設定していないので、今は値がありません。 Httpはステートレスであることを覚えておいてください。ここでのインデックスアクションメソッドコールはまったく新しいコールのようなもので、そのコールはコントローラの新しいインスタンスを作成します。

解決策は、プロパティ値を再初期化することです。 TempDataから読み取ることができます

public ActionResult Index() 
{ 
    AlertifyMessages = TempData["Alertify"] as AlertifyMessages; 
    return View(); 
} 
+2

私は、リダイレクトされたリクエストが新しいコントローラインスタンスであると説明すると便利だと思います。 – Jasen

関連する問題