Не удается загрузить ресурс манифеста с помощью GetManifestResourceStream()

Я создал пользовательский раздел конфигурации, используя XSD. Чтобы проанализировать файл конфигурации, который следует за этой новой схемой, я загружаю ресурс (мой файл.xsd) с этим:

public partial class MonitoringConfiguration
    {
        public const string ConfigXsd = "MonitoringAPI.Configuration.MonitoringConfiguration.xsd";
        public const string ConfigSchema = "urn:MonitoringConfiguration-1.0";

        private static XmlSchemaSet xmlSchemaSet;

        static MonitoringConfiguration()
        {
            xmlSchemaSet = new XmlSchemaSet();
            Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
            XmlReader schemaReader = XmlReader.Create(xsdStream);
            xmlSchemaSet.Add(ConfigSchema, schemaReader);
        }

    }

Кстати, мой ресурс: MonitoringConfiguration.xsd. И пространство имен другого частичного класса (который представляет код позади файла.xsd) MonitoringAPI.Configuration,

Проблема находится здесь:

 Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);

Значение xsdStream равно нулю, поэтому я думаю, что ресурс не найден! Но почему?

Спасибо

8 ответов

Решение

Название ресурса всегда:

<Base namespace>.<RelativePathInProject>.<FileName>

Поэтому, если ваш ресурс находится в "Resources/Xsd/", а пространство имен вашего проекта по умолчанию - "MonitoringAPI.Configuration", имя ресурса будет следующим:

"MonitoringAPI.Configuration.Resources.Xsd.MonitoringConfiguration.xsd"

Также убедитесь, что для действия сборки для вашего ресурса установлено значение "Встроенный ресурс".

Простой и правильный способ получить фактическое имя вашего встроенного ресурса:

string[] resourceNames =
    Assembly.GetExecutingAssembly().GetManifestResourceNames();

Затем просто проверьте массив resourceNames, и вы точно будете знать, что передать методу GetManifestResourceStream.

В моем случае,

Когда вы пытаетесь получить доступ к файлу через GetManifestResourceStream(), Вы получите ошибку из-за неверного пути к файлу, и поток будет нулевым.

Решение:

Щелкните правой кнопкой мыши файл, который вы добавили в решение, и выберите Свойства.

Выберите Build Action как Embedded Resource, (Вместо Content - по умолчанию)

Свойство Build Action установлено на встроенный ресурс

По умолчанию Visual Studio не встраивает xsd-файл, поэтому вы должны убедиться, что свойство "Build Action" для xsd-файла установлено в "Embedded Resource", чтобы оно работало.

Просто добавьте свои ресурсы в form1.resx -> добавить существующие элементы

дважды щелкните по ресурсам, которые вы добавили в папке Resources.go в свойствах, и выберите "Встроенные ресурсы" вместо "нет".

Затем попробуйте отладить строку:

string[] resourceNames=Assembly.GetExecutingAssembly().GetManifestResourceNames();

проверьте, что ресурсы, которые вы добавили, находятся в массиве. затем скопируйте имя ресурса именно из этого массива и попробуйте вставить имя в ваш код.. он работает отлично!!

Вы можете получить поток ресурсов, передав имена ресурсов, как показано ниже...

  1. Получить имя ресурса, например.

    Assembly objAssembly = Assembly.GetExecutingAssembly ();

    string [] strResourceNames = objAssembly.GetManifestResourceNames ();

  2. Передать имена ресурсов в...

    Stream strm = objAssembly.GetManifestResourceStream (strResourceNames);

Теперь у вас есть Stream, вы можете делать все, что хотите...

В моем случае это было что-то совершенно другое:

Мое приложение UWP правильно скомпилировано в конфигурации Debug и Release, но GetManifestResourceStream вернул конфигурацию Release только для Null.

Проблема заключалась в том, что в файле конфигурации сборки UWP (и только там) был включен параметр "Компилировать с цепочкой инструментов.NET Native". После отключения GetManifestResourceStream работал как положено.

У меня была проблема, когда я встраивал целую кучу файлов.xsd в разные сборки; все работало (GetManifestResourceNames возвращал файлы, которые я ожидал увидеть), кроме одного. Тот, который не был назван:

Something.LA.xsd

Я не имел дело с конкретными культурами, и бит.LA в конце имени файла выбирался компилятором, так как этот файл был для культуры LA - имя файла в манифесте входило как Something.xsd (под культурой ЛА) - следовательно, я не смог найти его (он оказался в сателлитной сборке). Я избежал этой проблемы, переименовав файл - возможно, можно явно указать культуру данного встроенного ресурса.

На самом деле, быстрый Google показывает: как я могу предотвратить настройку встроенного файла ресурсов на основе его имени файла

Согласно этому ответу, вы должны заниматься хакерскими делами - так что, возможно, переименование файла не так уж и плохо:)

Другие вопросы по тегам