Ответ 1
Прежде всего; Я никогда не мог запустить ваш GitHub-код. Следующее основано на моем собственном коде воспроизведения.
Я думаю, что вы получаете Невозможно загрузить файлы или сборку-исключения, потому что когда вы настраиваете десктопную среду AppDomain, которую вы устанавливаете:
adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
Это не будет работать в ASP.NET, потому что сборки находятся в подпапке bin
. Чтобы исправить это, просто сделайте это вместо:
adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
+ "\\bin";
Однако ASP.NET будет по умолчанию сборками теневых копий. Поэтому просто выполнение этого изменения может вызвать другое исключение:
ArgumentException: тип объекта не может быть преобразован в тип цели.
Это потому, что происходит смешение между сборками, загруженными в домене приложения по умолчанию и в песочнице. Те, которые находятся в домене приложения по умолчанию, расположены во временном месте теневой копии, а те, которые находятся в песочнице, находятся в папке bin вашего корня веб-приложения.
Самый простой способ исправить это - отключить теневое копирование, добавив следующую строку под <system.web>
в ваш Web.config:
<hostingEnvironment shadowCopyBinAssemblies="false"/>
Кроме того; Я думаю, что лучше и проще пропустить с помощью RazorDynamicObject
и вместо этого пометить ваши модели с помощью [Serializable]
. На самом деле я никогда не получал RazorDynamicObject
работоспособно.
Остальная часть этого ответа суммирует то, что я сделал, чтобы прийти к такому выводу
Я думаю, что это связано с ошибкой или ограничением в RazorEngine. (я не уверен в этом больше, вполне возможно, что теневое копирование и RazorDynamicObject
не могут работать вместе)
Я потратил пару часов, пытаясь понять, как это сделать, но я всегда получал исключение безопасности из RazorEngine.
Существует, однако, возможное обходное решение: Ditch RazorDynamicObject
и пометьте классы моделей как сериализуемые.
[Serializable]
public class ContentModel
{
public string Html { get; set; }
public string Title { get; set; }
public EditHistory History { get; set; }
}
[Serializable]
public class EditHistory
{
public IReadOnlyCollection<UserDetail> Authors { get; set; }
}
[Serializable]
public class UserDetail
{
public string Name { get; set; }
public string EmailAddress { get; set; }
}
И выполните:
Razor.Run("default.cshtml", typeof(ContentModel), cm); // no RazorDynamicObject
Я не смог запустить ваш репрограммный код, поэтому я создал свой собственный на основе вашего кода:
-
Создайте новое консольное приложение (Visual Studio)
-
В консоли диспетчера пакетов запустите:
install-package razorengine
-
Скопируйте код из вашего репродукции:
-
Линия 25-38 и 43-65 от:
https://github.com/knightmeister/RazorEngineIssue/blob/master/Global.asax.cs -
Все модели от: https://github.com/knightmeister/RazorEngineIssue/blob/master/Models/Models.cs
-
-
Отметьте модели с помощью
[Serializable]
. -
Удалить
RazorDynamicObject
-
Чтобы убедиться, что мы действительно можем отображать данные пользователя из списка авторов, измените тестовый шаблон на:
string template = "@Model.History.Authors[0].EmailAddress";
-
Кроме того, чтобы заставить этот шаблон работать, измените
Authors
вEditHistory
сIReadOnlyCollection<>
наIReadOnlyList<>
Я создал GIST с результирующим кодом:
https://gist.github.com/mwikstrom/983c8f61eb10ff1e915a
Это работает для меня. Он печатает [email protected]
так, как должен.
ASP.NET будет создавать теневые копии сборок по умолчанию, и это вызовет дополнительные проблемы с песочницей.
Чтобы получить эту работу в ASP.NET, вам нужно будет сделать следующие изменения:
-
Отключите теневое копирование ASP.NET, добавив следующее в
<system.web>
в файл Web.config:<hostingEnvironment shadowCopyBinAssemblies="false"/>
-
Добавить
\bin
в базовый путь приложения для песочницы. Итак, вcreateRazorSandbox(...)
do:adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\bin";
Я тестировал это, и он работает нормально. Мой тестовый проект просто:
-
Пустое веб-приложение ASP.NET(созданное с помощью Visual Studio), с
install-package razorengine
-
<hostingEnvironment shadowCopyBinAssemblies="false"/>
в Web.config. -
Следующий
Global.asax.cs
:
https://gist.github.com/mwikstrom/ea2b90fd0d306ba3498c
Здесь есть другие альтернативы (помимо отключения теневого копирования):