1

ASP.Net ページで使用できる非常に単純なヘルパー クラスを作成しました。これは、ページ上のエラーまたは成功 (フォームの検証エラーではない) をログに記録し、それをユーザーに表示するための非常に簡単な方法であると考えられています。

私の public ヘルパー クラスには、以下に示すように、特定のプロパティを持つクラスがあります。

public class UserMessage
{
    public UserMessage()
    {
        Messages = new Dictionary<string, string>();
    }

    public string SummaryMessage;
    public Dictionary<string, string> Messages;
    public bool ShowMessages;
    public bool ShowAsError;
}

次に、次のように、UserMessage クラスのインスタンスを格納するために使用される変数があります。

プライベート静的 UserMessage _userMessage { get; 設定; }

次に、次のように、2 つの public static メソッドを用意します。1 つはメッセージをログに記録し、もう 1 つはすべてのメッセージを表示します。

public static void LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
{
    _userMessage = new UserMessage();
    _userMessage.SummaryMessage = summaryMessage;
    _userMessage.ShowMessages = showIndividualMessages;
    _userMessage.ShowAsError = showAsError;
}

public static string DisplayUserMessages()
{
    if (_userMessage == null)
        return string.Empty;

    StringBuilder messageString = new StringBuilder();
    messageString.AppendFormat("\n");
    messageString.AppendLine(string.Format("<div class=\"messageSummary {0}\">", (_userMessage.ShowAsError) ? "invalid" : "valid"));
    messageString.AppendLine(string.Format("<h3>{0}</h3>", _userMessage.SummaryMessage));
    messageString.AppendLine("</div>");

    return messageString.ToString();
}

私が抱えている問題は、_userMessage 変数が静的変数でなければならないことです。そうしないと、「非静的フィールドにはオブジェクト参照が必要です.......」というエラー メッセージが表示されます。変数が静的であるという問題は、それがメモリに残ることです。そのため、ユーザーがエラー メッセージを受け取り、別のページにアクセスすると、エラー メッセージが表示されたままになります。

これは、OOP 101 を見逃したためだと確信していますが、これをどのように修正すればよいでしょうか?

4

4 に答える 4

1

参照を静的メンバーに引数として渡すか、以下のように新しいインスタンスを返すようにします。

public static UserMessage LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
{
    var userMessage = new UserMessage();
    userMessage.SummaryMessage = summaryMessage;
    userMessage.ShowMessages = showIndividualMessages;
    userMessage.ShowAsError = showAsError;
    return userMessage;
}
于 2012-04-25T12:36:32.500 に答える
1

ユーザーごとにメッセージを保持するために静的変数を使用しないでください。ASP.NET アプリケーションはマルチスレッドであり、静的変数の使用はスレッド セーフではありません。それらをセッションに保存します。

public static void LogSummary(string summaryMessage, ...)
{
   HttpContext.Current.Session["userMessages"] = new UserMessage(); 
   ...
}

public static string DisplayUserMessages()
{
   // get the value from session
   var userMessage = (UserMessage)HttpContext.Current.Session["userMessages"];
   // do the work
   // do the clean up
   HttpContext.Current.Session["userMessages"] = null;
   // the messages will not be displayed on next request
}

各リクエストは異なるスレッドによって処理されるため、ユーザーが_userMessageフィールドを上書きし、現在のユーザーのメッセージが表示されることを保証できません。

于 2012-04-25T12:36:56.363 に答える
0

静的変数はAppDomain内で共有されます。つまり、同時リクエストは同じインスタンスを共有するため、アプローチに問題があります。

HttpContextユースケースで必要に応じてリクエストごとのセマンティクスを取得するには、ユーザーメッセージインスタンスを現在のインスタンスに配置することを検討する必要があります。例えば、

public class UserMessage
{
   public static UserMessage Current
   {
      get { return HttpContext.Current.Items["_User_Message"] as UserMessage; }
   }

   public static void LogSummary(string summaryMessage, bool showIndividualMessages, bool showAsError)
   {
      var userMessage = new UserMessage();
      userMessage.SummaryMessage = summaryMessage;
      ...  

      HttpContext.Current.Items["_User_Message"] = userMessage;
   }

   public static string DisplayUserMessages()
   {
       var userMessage = UserMessage.Current;
       if (userMessage == null ) return string.Empty;

       ...
   }

   // rest of the code
   ...
}

おそらくUserMessageコンストラクターも作成しprivateます。

于 2012-04-25T12:45:51.480 に答える
0

私の意見では、あなたは間違ったアプローチで問題に直面しようとしています。サービス側コンポーネント (ASP.NET) を開発していて、サイトにアクセスするすべてのユーザーを完全に分離する必要があることを考えると、個人的には、すべてのレコードを保持するエラー メッセージにバックエンド データベースを使用しない理由がわかりません。単一のユーザー固有 ID に関連付けることができます。

シンプルなACIDをサポートするデータベース (実際には、市場に出回っているほぼすべてのデータベース) は、この場合に最適です。

このようにして、必要なときに必要なメッセージをデータベースから引き出すことができ、あらゆるタイプのメモリの問題についてこれ以上心配する必要はありません(少なくともこの質問の観点から)

お役に立てれば。

于 2012-04-25T12:37:20.077 に答える