Как загрузить XML-файл из модели, когда ControllerContext имеет значение null в ASP.Net MVC - PullRequest
1 голос
/ 21 апреля 2009

У меня есть абстрактный класс базового контроллера, который наследуют другие мои контроллеры. Этот класс должен загрузить локальный 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?

Ответы [ 3 ]

3 голосов
/ 21 апреля 2009

Я думаю, что решение вашей проблемы - это сочетание того, что люди упоминали здесь. Override 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 используйте корневой путь приложения к ресурсу (т. Е. Начинайте путь с символа тильды "~") - по этой причине вы видите ошибку Could не найдена часть пути 'c: \ windows \ system32 \ inetsrv \ Content \ Xml \ Buttons.xml'.

Если вы не используете Server.MapPath, любые относительные пути файловой системы относятся к исполняемому процессу, который в этом случае будет IIS. Вызов Server.MapPath преобразует указанный вами ресурс относительно иерархии виртуальных каталогов вашего веб-сайта в путь физической файловой системы.

Что касается вашей дополнительной проблемы с расположением XML-файла, я бы порекомендовал использовать App_Data, поскольку файлы, хранящиеся в этой папке, не обрабатываются по запросу.

2 голосов
/ 21 апреля 2009

Не называйте это в конструкторе. Переопределите метод Initialize. ControllerContext будет не нулевым там. Или используйте ленивый экземпляр.

1 голос
/ 21 апреля 2009

Альтернатива переопределению Initialize, но я думаю, что это лучший метод.

Я использую Server.MapPath для определения пути к корню документа. Я бы также использовал App_Data, чтобы не загружать необработанный файл.

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

** РЕДАКТИРОВАНИЕ: ** на основе вашего комментария вы можете ссылаться на объект Server из HttpContext.Current или перемещать загрузку XML в метод Initialize, как отмечали другие. Я рекомендую последнее, но я обновлю свой ответ первым в качестве альтернативы.

...