2012-04-25 67 views
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类的一个实例,像这样的变量:

private static UserMessage _userMessage {get;组; }

我然后有两个公共静态方法,一个用于记录一个消息,该其他显示所有的消息,例如:

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,但我应该怎么纠正呢?提前

感谢 铝

+0

您无法从静态方法访问非静态变量,这就是为什么它在您将_userMessage字段设置为静态后会起作用。 – 2012-04-25 12:38:13

+0

更大的问题是ASP.NET中的'static'意味着每个请求/用户都将使用相同的变量。 – 2012-04-25 12:39:34

回答

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领域,你不能保证为当前用户信息将被显示出来。

+0

会话选项非常适合我的解决方案。谢谢。 – higgsy 2012-04-26 17:17:41

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; 
} 
+0

你从'void'方法返回'UserMessage'类的实例。此外你会怎么做呢? – 2012-04-25 12:40:49

+0

@KarelFrajtak Woops! – asawyer 2012-04-25 12:41:20

+1

@KarelFrajtak在这种情况下,我可能会将他的'DisplayUserMessages'封装在UserMessage类中,并在用户控件中扮演整个角色。 – asawyer 2012-04-25 12:43:19

0

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

简单ACID支持的数据库(在实践中几乎任何市场上)在这种情况下的理想选择。

这样就可以从数据库中拉你需要在你需要的时刻信息,并且不需要对(从这个问题的角度至少)

任何类型的存储问题更省心希望这可以帮助。

0

静态变量将在应用程序域共享 - 即并发请求将共享相同的实例,因此你的方法是有问题的。

您应该考虑将您的用户消息实例放入当前的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