2

ASP.NET(C#)を使用してサーバーに送信しているときに、クライアントで送信された電子メールの数を表示するにはどうすればよいですか?

だから私のシナリオを見てみましょう:

  • UpdatePanel内にボタンがあります。
  • このボタンは、私のユーザー(サーバーサイド)にいくつかの電子メールを送信する必要があります。
  • そのボタンをクリックすると、次のようなこともしたいと思います。

    1. 不透明度の低いモーダルdivを表示し、中央にラベルを付けます(そのラベルのテキストは「0」です)。
    2. メールの送信を開始します。
    3. そのラベルのテキストは、送信されたすべての電子メールを反映するように更新する必要があります(これはカウンターです)(0-> 1-> 2-> ...)
    4. メール送信の最後に、そのモーダルdivを非表示にします

そして私のコード:

ASPX:

<asp:UpdateProgress ID="UpdateProgress1" runat="server">
  <ProgressTemplate>
    <asp:Image ID="imgAjax" runat="server" ImageUrl="~/Images/ajax-loader.gif" />
  </ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
  <ContentTemplate>
    <div id="RadbtnSendEmails_Container">
      <telerik:RadButton ID="RadbtnSendEmails" runat="server" EnableEmbeddedSkins="False"
        Skin="BlackByMe" Text="Send Mails" Width="150px" OnClick="RadbtnSendEmails_Click"
        Font-Bold="True" Font-Names="Tahoma" ValidationGroup="A">
      </telerik:RadButton>
    </div>
  </ContentTemplate>
</asp:UpdatePanel>
<div id="OffDiv">
</div>
<div id="CounterContainer">
  <asp:Image ID="imgWhiteCircle" runat="server" ImageUrl="~/Images/WhiteCircle.png" />
  <asp:Label ID="lblCounter" runat="server" Text="0" Font-Bold="True"
    Font-Size="50px" ForeColor="#6600CC">
  </asp:Label>
</div>

C

protected void RadbtnSendEmails_Click(object sender, EventArgs e) {
  ScriptManager.RegisterStartupScript(this, this.GetType(), "Show_Counter", 
    "Show_Counter();", true);

  //int Counter=0;
  //Send Mail Codes in for()
  //Counter++; in every send
  //Change that label'text to new counter -> i do n't know how can i do that

  //ScriptManager.RegisterStartupScript(this, this.GetType(), "Hide_Counter", 
    "Hide_Counter();", true);
}

ただし、このC#コードには問題があります。

そのボタンをクリックすると、UpdateProgress内の画像が表示され、このブロックが電子メールの送信を終了した後、モーダルdivを表示できますが、プロセスの開始時は表示されません。

また、そのカウンターを実装する方法がわかりません!クライアント側のコードからサーバー側のコードにジャンプするか、サーバー側のコードからクライアント側のコードにジャンプする必要があります。

これらの電子メールアドレスは、SQLServer2008R2データベースにあります。したがって、プロセスサーバー側のその部分を実行する必要があります。

私は本当にこの問題を解決する方法を学びたいと思っています、そしてこのシナリオは素晴らしいと思います、それで私がそれについて良い考えを得るのを手伝ってください。

4

3 に答える 3

4

したがって、直面している問題は、サーバー側で作業を行う必要があるが、そのクライアント側を表示したいということです。問題の最初の部分は、HTTPがステートレスコネクションレスプロトコルであるため、サーバーに詳細情報(更新)を要求し続ける必要があることです。

したがって、必要なのはいくつかのリソースです。

サーバーが送信された電子メールの現在の数を知る方法(たとえば、アクセスできるパブリックカウンター)、電子メールを送信するためにサーバーが実行する方法(これは通常、バックグラウンドスレッドで実行する必要があります)ただし、注意してください。クラッシュしたバックグラウンドスレッド(たとえば、未処理の例外によるもの)は、アプリプール全体を折りたたむ)と、クライアントからプロセスを初期化する方法(すでにこの部分があります)。

次に、クライアントで、要求を開始する方法、更新を確認して完了したことを知る方法、およびその他すべての必要なことを管理する方法が必要です。

jQuery(javascriptの上にあるライブラリですが、javascriptを置き換えるものではないため、学習する必要があるようです)を使用していると仮定し、ここに基本的なコードを記述します。また、ページ上でMicrosoft ASP.NETライブラリが実行されていることを前提としています(コードはScriptManagerを参照しているため、かなり安全です)。

C#から始めましょう:(これはあなたのページにあります、私はすべてを書くつもりはありません、それの大部分だけを書きます)

//this is a class you need to write, see below
//this way other code can access this variable too
public MySpecialMailerClass mailer;

[WebMethod] //this may require a include, you're on your own for that 
            //for now (System.Web.Services)
public void StartEmails(){
  //do some stuff here to start the email process?
  //create a class that can run the db scripts uninterrupted, 
  //and provide it a public member that can be accessed for the current
  //count, and the expected max count (set to -1 on init so you know 
  //that you haven't finished initting this yet)
  
  mailer = new MySpecialMailerClass();
  new Thread( mailer.Start ) { IsBackground = true }.Start( );
}

[WebMethod]
public int GetMaxCount(){
  return mailer.MaxCount;
}

[WebMethod]
public int GetCurrentCount(){
  return mailer.CurrentCount;
}

今のところ、これが実際に追加する必要のあるすべてのC#コードになります。

Javascript:

var checkingOnEmailsSentIntervals,
    checkingOnMaxMessagesIntervals,
    maxMessages = 0;

function SuccessHandler(){
  //Note that you should do something here to handle the success each
  //time or that you should write a separate "SuccessHandler" 
  // for each one that you want to execute _when the server call is done_
  // Note that this is what I do (one success per call)
  // But in this case a generic one is sometimes handy, such as here
}

function FailHandler() {
  //Note that you should do something here to handle the failure each time
}

function startScript(){
  PageMethods.StartEmails(StartEmailsSuccessHandler,FailHandler);
}

function StartEmailsSuccessHandler(){
  //this will get triggered when the emails have started sending, 
  // so this is where you create the boxes you wanted earlier, etc.
  $('#counter-span-identifier').show();
  checkingOnEmailsSentIntervals = setInterval(CheckForMoreMessages,100);
  checkingOnMaxMessagesIntervals = setInterval(CheckForMaxMessages,10);
}

function CheckForMoreMessages() {
  PageMethods.GetCurrentCount(CheckForMoreMessagesSuccessHandler,FailHandler);
}

function CheckForMoreMessagesSuccessHandler(result) {
  var currentCount = result;
  $('#counter-span-identifier').text(currentCount + ' messages sent');
  if (currentCount == maxMessages) {
    //we have finished now, so we can display another message or hide our div
    clearInterval(checkingOnEmailsSentIntervals);
    $('#counter-span-identifier').hide();
  }
}

function CheckForMaxMessages() {
  PageMethods.GetMaxCount(CheckForMaxMessagesSuccessHandler,FailHandler);
}

function CheckForMaxMessagesSuccessHandler(result) {
  maxMessages = parseInt(result); //parseInt not really needed here, 
                                  //shown as example of coercion
  if (maxMessages > -1){
    clearInterval(checkingOnMaxMessagesIntervals);
  }
}

これで、ここでケースをかなりきれいにまとめることができます。これは、JavaScriptに2つのループ(setInterval)があり、MaxMessages(したがって-1を返す)とCurrentCountをチェックするためです。また、必要な情報を取得したら、各ループを停止するコードもあります。

あなたがしなければならない部分は、メンバー変数と1つのメソッドに公開する別のクラスに電子メールを送信するコードを配置することです(そして、要件に一致するように私の例の名前を変更します)。

そして、私はそれを行う必要があると思うので、ここにMySpecialMailerClassあなたを始めるためのC#があります:

public class MySpecialMailerClass {
  public MySpecialMailerClass() {
    MaxCount = -1;
    CurrentCount = 0;
  }
  public int MaxCount {get;set;}
  public int CurrentCount {get;set;}
  public void Start(){
    //do something to get the MaxCount from the database
    //do something to get the messages
    var messages = mailerDbClass.GetMessagesToBeSent();
    MaxCount = messages.Count;
    
    //send the messages
    foreach(message in messages) {
      SendMessage(message);
      CurrentCount += 1;
    }
  }
}
于 2012-06-15T21:26:11.663 に答える
1

クライアントのボタンをクリックすると、サーバーにリクエストが送信されます。更新パネルを使用している場合、このリクエストはajaxで送信されます。サーバーがリクエストを受信すると、ボタンクリックイベントハンドラーにあるコードが実行されます。クリックハンドラーのコードが終了するまで、ページを更新するための応答をクライアントに送り返しません。

あなたがやろうとしていること(少なくともクライアント側のカウンター)は、更新パネルを使用するだけではほぼ不可能になります。あなたがそれを持っていないことを乗り越えることができるならば、私はそれをスキップすると言うでしょう。

私が考えることができる1つの可能性は、Webサービス(.asmx)とカスタムjavascriptでのajax呼び出しの使用を含むでしょう。個々の電子メール要求をWebサービスに送信し、サービスが応答したら、モーダルをカウントで更新してから、次の要求をWebサービスに送信することができます。

于 2012-06-15T21:02:19.680 に答える
1

ブラウザはサーバーコードを直接実行できないことを理解する必要があります。また、サーバーがブラウザで直接コードを実行することもできません。最善の策は、何らかの方法(Webサービス)でHTTPを介してブラウザーから実行したいメソッドを公開することです。次に、javascriptとjQueryを使用してそれらを呼び出し、説明した方法でUIを変更します。

于 2012-06-15T21:02:31.370 に答える