1

我创建了一个非常简单的帮助类,可以在我的 ASP.Net 页面中使用。这个想法是,它应该是一种非常简单的方法来记录页面错误或成功(不是表单验证错误),然后将其显示给用户。

在我的公共助手类中,我有一个具有某些属性的类,如下所示:

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 { 获取;放; }

然后我有两个公共静态方法,一个记录消息,另一个显示所有消息,如下所示:

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 应用程序是多线程的,使用静态变量不是线程安全的。将它们存储在 Session 中。

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

看来,你试图用错误的方法来面对问题。考虑到您正在开发服务端组件(ASP.NET)并且您必须在每个访问您的站点的用户之间进行完美隔离,我个人认为没有任何理由不使用后端数据库来保存每条记录的错误消息可以关联到单个用户唯一 ID。

简单的ACID支持的数据库(实际上市场上几乎所有的数据库)都非常适合这种情况。

通过这种方式,您可以在需要的时候从数据库中提取您需要的消息,并且不需要更多担心任何类型的内存问题(至少从这个问题的角度来看)

希望这可以帮助。

于 2012-04-25T12:37:20.077 回答
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 回答