2011-06-20 10 views
8

まだC#に少し新しく、私はこれと正しい方向にいくつかのポインタを必要としています。グローバル通知クラスを作成するにはどうすればよいですか?

C#/ Asp.netの通知システムをビルドしたいと思います次のページの読み込み時にループできるいくつかの静的リストにメッセージとメッセージタイプを追加します。これは、スタックオーバーフローが各ページの負荷での成果のバナー通知を行う方法と似ています(「あなたはxバッジを獲得した、あなたはyバッジを獲得しました」など)。 ?

で(「メッセージ」、「メッセージタイプを」)を追加

編集:

私がメッセージを格納するSession.Add("Notificiations", myList);を使用することが示唆されています、私は通知」という初期化については行くだろうか/

"リストしたら、他の場所でlist.add()を実行しますか?

答えて

6

あなたはこのようなクラスを書くことができます(私には何もありませんDE私の近くに、私は)コードがコンパイルを願っています:

public class MessageHelper 
{ 
    protected const String sessionName = "messages_session"; 
    public List<String> Messages 
    { 
     get 
     { 
      List<string> list; 
      if (Session[sessionName] != null) 
      { 
       list = (List<string>)Session[sessionName]; 
      } 
      else 
      { 
       list = new List<string>(); 
      } 
      Session[sessionName] = list; 
      return list; 
     } 
     set 
     { 
      Session[sessionName] = value; 
     } 
    } 

    public void AddMessage(String message) 
    { 
     List<String> list = this.Messages; 
     list.Add(message); 
     this.Messages = list; 
    } 

} 

がメッセージを追加するには、どうなる:

MessageHelper messageHelper = new MessageHelper(); 
messageHelper.AddMessage("hello world"); 

を(これらのメッセージは、特定のユーザを意味し、セッションに格納されています)。

は、あなたがあなたがあなたのメッセージを表示したいあなたのマスターページ、リテラル持っていると仮定しましょう:あなたのマスターページで

<asp:Literal ID="litMessages" runat="server" /> 

あなたがOnInit Eventhandlerを追加します。

protected override void OnInit(EventArgs e) 
{ 
    MessageHelper messageHelper = new MessageHelper(); 
    String output = string.Empty; 
    foreach(String message in messageHelper.Messages) 
    { 
    output += String.Format("{0}<br />", message); 
    } 
    this.litMessages.Text = output; 

} 

これはあなたに基本を与える必要があります概要、メッセージを保存して表示する方法について説明します。もちろん、このコードを調整するには、メッセージを削除するメソッドを追加するか、または優れたクライアントの副作用(StackOverflowの通知など)を行うことができます。回)

私はこれがあなたを助けてくれることを願っています。

+0

http://msdn.microsoft.com/en-us/library/ms972429.aspxこのようにSession.Add( "Notificiations"、myList);その「通知」リストを初期化してどこにでも追加する方法はありますか? – tester

+0

@テスター:以前の回答にいくつかのコードを追加しました – citronas

+0

素晴らしいです。これは 'Session''HttpContext.Current.Session'を作ったときにうまくいきました。ありがとう! – tester

9

ポストバック時にページ上部のポップアップバナーを表示するのはかなりきれいですが、jQueryとajaxを使用してサーバーとの定期的なチェックを行って、何かの状態が変わったかどうかを確認するユーザーに「新しい」メッセージがある場合

これは実際には、Webサーバー上で実行されている非同期プロセスがあり、それがどれくらい時間がかかるか(またはそれが本当に長い時間かかると確信している)あなたのクライアントのブラウザがそれを待っているのを望んではいけません。 javascriptとwindow.setIntervalを使用すると、30秒ごとに(または何でも好きなように)関数を設定することができます。次に、関数がサーバーに対してajaxポストを実行して、非同期プロセスが完了したかどうかを確認します。あなたのケースでは、ajax投稿は、ユーザに "新しい"メッセージがあるかどうかをサーバに尋ねるだけです。ユーザーが新しいメッセージを持っている場合は、jQueryを使用してページに隠れたdivを表示して、新しいメッセージがあることをユーザーに知らせるだけです。

これはちょっと複雑な解決策で、アマチュアのスキルを超えているかもしれませんが、利益はそれだけの価値があります!

  • は、Webアプリは、よりステートフルおよびサーバー
  • 上の変更の「意識」思われてしまう、ユーザーエクスペリエンス

などのように破壊する傾向が不要なページが更新が既に指摘しているが不要「グローバル」情報を格納するための最良の場所は通常はセッションです(セッションの限られた範囲に留意してください)。 MSDN ASP.NET Session State

ただし、すべてのクライアントがアクセスする必要があるデータの場合は、アプリケーションのキャッシュに保存することができます。 ASP.NET Caching

もちろん、セッションまたはキャッシュにどれくらいの量のデータを保存するかには注意が必要です。足で自分を撃つのは簡単です。

1

私はこれをwcf/webサービスまたはあなたのWebアプリケーション内のインターフェイスとして実装できるサービスとして定義することをお勧めします。

サービスとしてこの機能を使用すると、スケーラビリティ、可用性などの利点があります。たとえば、iphoneアプリを使用しているクライアントがメッセージを送信し、Webサイトを使用している別のクライアントがそれを見ることができます。

2番目のアプローチを使用する場合は、NinjectなどのDIフレームワークを使用し、DI/Iocフレームワークがインスタンスにシングルトンパターンを適用する必要があります。

私はここにサンプルコードを与えることができますが、帰宅するまではできません。

+0

は例を見るのが大好きです! – tester

1

以下のコードは、さまざまな回答の良い組み合わせかもしれないと思います。 Webサービスを使用して新しい通知を取得し、jqueryを使用してある間隔で通知を取得します。ユーザセッションに通知を保存します。

まずは、メッセージを表す単純な「Message」クラスを最初に使用します。あなたの質問では、複数の種類のメッセージがあることに気付きましたので、私はそれをカバーするソリューションを提供したいと思っていました。私のメッセージクラスは、TextとTypeという2つのプロパティしか持っていません。タイプは、私のデモでは、メッセージの背景色として使用されます。

public class Message 
{ 
    public string Text { get; set; } 
    public string Type { get; set; } 
} 

次は、メッセージの保存と取得を処理するUserMessagesクラスです。すべてのメッセージをユーザーセッションに保存します。私のデモのために

public class UserMessages 
{ 
    protected static string _messageSessionID = "userMessages"; 

    public static List<Message> GetMessages() 
    { 
     var msg = HttpContext.Current.Session[_messageSessionID]; 

     if (msg == null) 
     { 
      return new List<Message>(); 
     } 

     //clear existing messages 
     HttpContext.Current.Session[_messageSessionID] = null; 

     //return messages 
     return (List<Message>)msg; 
    } 

    public static void AddMessage(Message message) 
    { 
     var msg = GetMessages(); 
     msg.Add(message); 

     HttpContext.Current.Session[_messageSessionID] = msg; 
    } 
} 

私はASP.NetのWebサービス、のScriptManager、とjQueryを組み合わせることによって、AJAXを使用してmessaagesを読むことにしました。ここに私のWebサービスは、次のとおりです。

私のaspxページで

--ASMX File--

<%@ WebService Language="C#" CodeBehind="~/App_Code/MessageService.cs" Class="UserNotification.MessageService" %> 

--CS File--

namespace UserNotification 
{ 
    [WebService(Namespace = "http://tempuri.org/")] 
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [System.Web.Script.Services.ScriptService] 
    public class MessageService : System.Web.Services.WebService 
    { 

     public MessageService() 
     { 
     } 

     [WebMethod(EnableSession = true)] 
     public List<Message> GetMessages() 
     { 
      return UserMessages.GetMessages(); 
     } 
    } 
} 

私は私のサービスに関連してのScriptManagerを作成し、メッセージのためのdivプレースホルダと素早く汚れたメッセージを追加するインターフェイス:

<asp:ScriptManager runat="server"> 
     <Services> 
      <asp:ServiceReference Path="~/MessageService.asmx" /> 
     </Services> 
    </asp:ScriptManager> 
    <div> 
     <div id="msgArea"> 

     </div> 

     <span>Add Message</span> 
     Text: <asp:TextBox ID="txtMessage" runat="server" /> 
     <br /> 
     Type: <asp:TextBox ID="txtType" runat="server" Text="yellow" /> 
     <asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" /> 
    </div> 
</form> 

メッセージ作成をサポートするために、彼はボタンのクリックイベントを処理するコードの背後にあるメソッドに従っています:

protected void btnAdd_Click(object sender, EventArgs e) 
{ 
    UserMessages.AddMessage(new Message() {Text = txtMessage.Text, Type = txtType.Text}); 
} 

今重要な部分です。実際にメッセージを表示するには、次のjavascriptのブロックを書きました(ほとんどjqueryを使用していましたが、v1.4.1を使用しましたが、どちらのバージョンを使用することもできます)。タイマーは30秒間隔で設定されます。これは、初めて処理する前に30秒待つことを意味します。ページのロードを直ちに処理するには、setIntervalの直前にCheckMessages();を追加して、ページのロードを即座にチェックします。 setIntervalを終了すると、メッセージが定期的に更新されます。

<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> 
<script type="text/javascript"> 
    $(function() { 
     setInterval('CheckMessages();', 30000); 
    }); 

    function CheckMessages() { 
     UserNotification.MessageService.GetMessages(function (result) { 
      //alert('found ' + result.length.toString() + ' messages.'); 
      $.each(result, function (i, e) { 
       var dv = $('<div />') 
          .css('background-color', e.Type) 
          .css('border', '4px solid white') 
          .css('color', 'white') 
          .css('text-align', 'center') 
          .append('<span>' + e.Text + '</span>') 
          .append(
           $('<button />') 
            .text('Close') 
            .click(function() { $(this).parent().remove(); })); 

       $('#msgArea').append(dv); 

      }); 

     }, function (e) { alert(e._message); }); 
    } 
</script> 

上記のコードブロックで、コード内のプロパティの名前と一致するe.Textとe.Typeを使用していることに注意してください。 e.Typeは私たちの背景色としてここに指定されていますが、実際には他のものに使用される可能性があります。また、現実には、これらのCSS属性はすべてCSSクラス(おそらく各メッセージタイプごとに1つのCSSクラス)に含まれます。私は「閉じる」ボタンを追加しましたが、あなたは言及しませんでしたが、人々は通知を閉じたいと思っていました。

この実装についてのすばらしい点の1つは、セッションの途中ではなく、データベースにメッセージを格納する必要があることを実現していることです。この実装ではスムーズに処理されます。 UserMessages.GetMessagesを変更してdb/otherの場所から取得すると、設定されます。さらに、セッションからユーザーメッセージを読み込むだけでなく、キャッシュからメッセージを読み取ってグローバルメッセージを処理するように設定することもできます。

関連する問題