1

我有一个基本控制器抽象类,我的其他控制器继承了它。此类需要加载本地 xml 文件以便为母版页创建一些按钮。鉴于此阶段 ControllerContext 为空,加载文件的最佳做法是什么?(在网络服务器上运行时,我收到以下错误:找不到路径的一部分 'c:\windows\system32\inetsrv\Content\Xml\Buttons.xml'。)

当前代码是

using System.Web.Mvc;
using Site1.Models;

namespace Site1.Controllers
{

    [SkyArts.Models.Master]
    public abstract class BaseController : Controller
    {
        public BaseController()
        {
            XDocument buttonsXmlDoc = XDocument.Load("Content/Xml/Buttons.xml");
        }
    }
}

该文档实际上是从 Model 类加载的,但为简洁起见,我忽略了这一点。

作为一个附带问题,您会将 xml 文件放在 Content 中还是 App_Data 中?

4

3 回答 3

3

我认为解决您的问题的方法是结合人们在这里提到的内容。覆盖 Initialize 并在那里加载您的 XML 文档。Server 属性此时应该是有效的。此外,使用Server.MapPath从您的网站目录层次结构中检索资源。

using System.Web.Mvc;
using Site1.Models;

namespace Site1.Controllers
{

    [SkyArts.Models.Master]
    public abstract class BaseController : Controller
    {
        protected override void Initialize(RequestContext rc)
        {
            base.Initialize(rc);

            XDocument buttonsXmlDoc = XDocument.Load(
                Server.MapPath("~/Content/Xml/Buttons.xml"));
        }
    }
}

此外,请注意,在调用 Server.MapPath 时,请使用应用程序根路径到资源(即以波浪字符“~”开头的路径)——这就是您看到错误的原因路径“c:\windows\system32\inetsrv\Content\Xml\Buttons.xml”。

当您不使用 Server.MapPath 时,任何相对文件系统路径都相对于正在执行的进程,在这种情况下是 IIS。调用 Server.MapPath 会将您指定为相对于您网站的虚拟目录层次结构的资源转换为物理文件系统路径。

至于您关于 XML 文件位置的附带问题,我建议使用 App_Data ,因为存储在该文件夹中的文件在请求时不提供。

于 2009-04-21T12:57:42.990 回答
2

不要在构造函数中调用它。重写 Initialize 方法。ControllerContext 在那里将是非空的。或者使用惰性实例化。

于 2009-04-21T12:38:57.280 回答
1

替代覆盖初始化,但我认为这是最好的方法。

我使用 Server.MapPath 来解析文档根目录的路径。我还会使用 App_Data 以便无法下载原始文件。

var buttonsXmlDoc = XDocument.Load( HttpContext
                                      .Current
                                      .Server
                                      .MapPath( "~/App_Data/Buttons.xml" ) );

**编辑:**根据您的评论,您可以从 HttpContext.Current 引用 Server 对象,或者将 XML 的加载移动到 Initialize 方法,正如其他人所指出的那样。我推荐后者,但我会用前者更新我的答案作为替代方案。

于 2009-04-21T12:12:28.840 回答