0

有人可以向我解释为什么我收到以下错误:当我导入类时,IIS 服务器的当前上下文中不存在名称“Messanger”,甚至 Visual Studio 都没有检测到错误?

xxxxx.Models.Messanger:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace XXXX.Models
{
    public class Messanger
    {
        private Messanger()
        {
        }
        public static Messanger Instance
        {
            get
            {
                var output = HttpContext.Current.Session["MessangerInstance"] as Messanger;
                if (output == null)
                {
                    output = new Messanger();
                    HttpContext.Current.Session["MessangerInstance"] = output;
                }
                return output;
            }
        }
        private List<string> Success = new List<string>();
        private List<string> Info = new List<string>();
        private List<string> Warning = new List<string>();
        public void addSuccess(string message)
        {
            Success.Add(message);
        }
        public void addSuccess(List<string> messages)
        {
            Success.AddRange(messages);
        }
        public void addInfo(string message)
        {
            Info.Add(message);
        }
        public void addInfo(List<string> messages)
        {
            Info.AddRange(messages);
        }
        public void addWarning(string message)
        {
            Warning.Add(message);
        }
        public void addWarning(List<string> messages)
        {
            Warning.AddRange(messages);
        }
        public List<string> getSuccess()
        {
            return Success;
        }
        public List<string> getInfo()
        {
            return Info;
        }
        public List<string> getWarning()
        {
            return Warning;
        }
        public void addMessage(IMessageType message)
        {
            if (message.getType() == "success")
            {
                Success.Add(message.getMessage());
            }
            else if (message.getType() == "warning")
            {
                Warning.Add(message.getMessage());
            }
            else Info.Add(message.getMessage());
        }
        public void addMessage(List<IMessageType> messages)
        {
            foreach (IMessageType message in messages)
            {
                addMessage(message);
            }
        }
        public int getMessageCount()
        {
            return Success.Count + Info.Count + Warning.Count;
        }
        public bool ThereAreMessages()
        {
            return (getMessageCount() > 0);
        }
    }
    public interface IMessageType
    {
        string getType();
        string getMessage();
    }
    public abstract class Message : IMessageType
    {
        private string MessageStore;
        private string Type;
        public Message(string message, string type)
        {
            this.MessageStore = message;
            this.Type = type;
        }
        string IMessageType.getType()
        {
            return Type;
        }
        string IMessageType.getMessage()
        {
            return this.MessageStore;
        }

    }
    public class SuccessMessage : Message
    {
        public SuccessMessage(string message)
            : base(message, "success")
        {

        }

    }
    public class InfoMessage : Message
    {
        public InfoMessage(string message)
            : base(message, "info")
        {

        }
    }
    public class WarningMessage : Message
    {
        public WarningMessage(string message)
            : base(message, "warning")
        {

        }
    }

}

我的 _Layout.cshtml Razor 视图是:

@using XXXXX.Models
<!DOCTYPE html>
<html>
  <head>
    <title>XXXXX - @ViewBag.Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Bootstrap -->
    <link href="@Url.Content("/css/bootstrap.css")" rel="stylesheet" media="screen">
    <link href="@Url.Content("/css/bootstrap-glyphicons.css")" rel="stylesheet">
  </head>
  <body>
      <div class="navbar navbar-inverse">
      <div class="container">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">Project name</a>
        <div class="nav-collapse collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li class="divider"></li>
                <li class="nav-header">Nav header</li>
                <li><a href="#">Separated link</a></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
          </ul>
          <form class="navbar-form form-inline pull-right" method="post" action="@Url.Action("Login", "Account", new {ReturnUrl = ViewBag.ReturnUrl})">
              @Html.AntiForgeryToken()
              <input type="text" name="UserName" autofocus placeholder="Username">
              <input type="password" placeholder="Password" name="Password">
              <input type="hidden" value="true" name="RememberMe">
              <button type="submit" class="btn btn-default">Log in</button>
          </form>
            </div><!--/.nav-collapse -->
            </div>
        </div>
      <div class="container">
          @if (Messanger.Instance.ThereAreMessages())
          {
              if(Messanger.Instance.getWarning().Count > 0)
              {
                  <div class="row" style="text-align: center;">  
                        <div class="alert alert-danger">
                        <button type="button" class="close" data-dismiss="alert">&times;</button>
                        @foreach (string message in Messanger.Instance.getWarning())
                        {
                            @message;<br>
                        }
                        </div>               
                  </div>
              }
              if (Messanger.Instance.getSuccess().Count > 0)
              {
                <div class="row">
                    <div class="alert alert-success">
                    <button type="button" class="close" data-dismiss="alert">&times;</button>
                    @foreach (string message in Messanger.Instance.getSuccess())
                    {
                        @message;
                    }
                    </div>
                </div>
              }
              if (Messanger.Instance.getInfo().Count > 0)
              {
                <div class="row">
                    <div class="alert alert-info">
                    <button type="button" class="close" data-dismiss="alert">&times;</button>
                    @foreach (string message in Messanger.Instance.getInfo())
                    {
                        @message;
                    }
                    </div> 
                </div>
              }
          }
          @RenderBody()
      </div>
    <!-- End of content-->
    <script src="@Url.Content("/js/jquery-2.0.3.min.js")"></script>
    <script src="@Url.Content("/js/bootstrap.js")"></script>
  </body>
</html>

尝试在第 49 行访问 XXXXX.Models.Messanger.ThereAreMessages() 时出现错误。

编辑:我设法通过使模型类静态来修复第一个错误。之后我遇到了一个奇怪的错误,但我意识到我在视图文件的 webconfig 中添加了 System.Models 导致错误。

现在我有另一个问题。我使用 Messanger 在整个站点中获取消息。我有一个登录表单,如果提交的数据无效,我会将错误推送到 Messanger,然后显示它们。问题在于,当数据无效时,错误会按预期显示,但每次刷新后,相同的消息会一次又一次地堆积。ASP.NET 是无状态的,每次刷新后,类应该再次实例化,我没有将消息存储到数据库中,但它们仍然保持堆叠。有人可以帮我解决吗?

4

1 回答 1

1

到你最后一次更新。你的Messanger课是静态的。Asp.Net 不是无状态的,但它处理的 http 请求是无状态的。当一个类是静态的时,每个应用程序域都存在该类的一个实例。当部署到 Web 服务器时,IIS 将为每个 Web 应用程序创建至少一个应用程序域(称为应用程序池),并且可以服务于许多请求。但是,如果 IIS 确定请求负载太高,它可能会选择启动一个新的应用程序域来处理它们。您将体验到的是,系统的每个用户都会看到完全相同的消息实例,即使他们没有创建该消息。

如果处理不当,Web 环境中的静态类和成员可能会非常危险。

解决您的问题的一种可能方法是将实例包装在会话中。从您的中删除所有静态修饰符Messanger并添加以下属性:

public static Messanger Instance
{
    get
    {
        var output = HttpContext.Current.Session["MessangerInstance"] as Messanger;
        if (output == null)
        {
            output = new Messanger();
            HttpContext.Current.Session["MessangerInstance"] = output;
        }
        return output;        
    }
}

您也可以选择将构造函数设为Messanger私有。

现在,当您访问时,Messanger请这样做:

Messanger.Instance

每个用户,每个会话将始终是一个。

于 2013-08-06T20:55:17.090 回答