2009-04-21 23 views
1

我有一个基础控制器抽象类,我的其他控制器继承。这个类需要加载一个本地xml文件,以便为母版页创建一些按钮。鉴于此阶段ControllerContext为null,加载文件的最佳做法是什么? (如果在Web服务器上运行,我得到以下错误:找不到路径的一部分“C:\ WINDOWS \ SYSTEM32 \ INETSRV \内容\ XML \ Buttons.xml”如何在Controller.Net中ControllerContext为空时从模型加载xml文件MVC

当前的代码

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类加载的,但为了简洁起见,我已经将其省略了。

作为一个侧面的问题,你会把内容或App_Data中的XML文件?

回答

2

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

1

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

我使用Server.MapPath来解析文档根的路径。我也会使用App_Data,以便原始文件不能下载。

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

**编辑:**基于您的评论,你可以引用从HttpContext.Current Server对象或将XML的加载到初始化方法,其他人指出。我建议后者,但我会更新我的答案与前者作为替代。

+1

服务器对象为空,大概是因为它在基础控制器的构造函数中。 – darasd 2009-04-21 12:17:46

3

我认为你的问题的解决方案是人们在这里提到的组合。覆盖在此处初始化并加载您的XML文档。服务器属性应该在此时有效。此外,请使用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,因为存储在该文件夹中的文件在请求时不会被提供。