Где я должен поместить общий код генерации HTML в проект ASP.NET MVC?

У меня есть решение ASP.NET MVC, и у меня есть большое количество классов HtmlHelper в проекте ASP.NET MVC, которые берут данные и генерируют различные фрагменты html для отображения на разных страницах.

Теперь мне нужно запустить кучу запланированных заданий, и многие из этих заданий создают электронные письма. Я переместил все эти задания в отдельный проект в решении (так называемый AdminJob.csproj), но теперь я обнаружил, что мне нужно создать несколько писем с очень похожим HTML, как у меня на моих страницах просмотра. Я стараюсь, чтобы задания администратора не зависели от проекта ASP.NET MVC (поскольку я хотел бы запустить проект adminjob как командную строку, если это необходимо), и я также хочу избежать создания моего проекта ASP.NET MVC имея зависимость от проекта AdminJob (поскольку это просто кажется странным).

Любые предложения о том, как я могу избежать дублирования одного и того же кода рендеринга HTML как в моем проекте ASP.NET MVC, так и в проекте AdminJob?

Единственное, о чем я могу думать, это создать еще один проект в решении под названием "ViewHelpers" или что-то в этом роде и перенести все мои HTMLHelpers в этот проект, чтобы на него можно было ссылаться как мой проект MVC, так и проект AdminJob. Кажется немного переборщиком, чтобы иметь отдельный проект только для этого кода, но я не могу думать о другом решении, которое не создает дублирование.

Любые другие предложения для лучшего способа сделать это и избежать дублирования?

Ответ 1

То, как я смотрю на это, - это тип вида. В моих веб-приложениях (html, email, pdf, rss и т.д.) есть несколько типов просмотров. Существует несколько реализаций этого шаблона: ActionMailer в рубине на рельсах или его порту в asp.net: MvcMailer.

Таким образом, вы можете в полной мере использовать механизм Razor как в своем веб-приложении, так и в ваших письмах, чтобы уменьшить дублирование.

Вы можете размещать свои представления в другом проекте и сообщать ViewEngine о том, где искать представления (см. Представления в отдельных сборках в ASP.NET MVC). Я нахожу это излишним.

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

Если вы хотите визуализировать представления вне веб-приложения, вы можете скомпилировать шаблоны бритвы в консольном приложении, используя один из них:

  • RazorTemplates: https://github.com/volkovku/RazorTemplates
  • RazorEngine: https://github.com/Antaris/RazorEngine
  • с чем-то вроде MvcMailer, вы можете просто делать завитые запросы в запланированных задачах. MvcMailer нужен HttpContext для запуска, поэтому вы не сможете запустить его из консольного приложения. зависание действий mvc будет работать.

Ответ 2

Не полностью исключайте идею о том, что AdminJob зависит от веб-сайта. Это может сработать для вас: Как использовать Razor View Engine в консольном приложении?.

Обратите внимание, что AdminJob, имеющий зависимость от компиляции в проекте MVC, не препятствует запуску AdminJob в качестве консольного приложения. Это может работать нормально.

Проблема, которую я ожидал бы - даже если вы перемещаете связанные с View вещи в общий проект, - это то, что вы можете обнаружить, что все это прерывается во время выполнения при работе за пределами веб-сайта. Под капотом существуют зависимости от материала System.Web, например. HttpContext, который будет нулевым во время выполнения. Некоторые зависимости могут быть заглушены, некоторые не могут.

В отдельном совместном проекте эта проблема вообще не будет устранена, поэтому я не думаю, что движущийся код о чем-то выгоден.

Но типичный подход (т.е. 5 из последних 6 компаний, в которых я работал):

Забудьте о командной строке. Сделайте инструмент Admin частью веб-сайта. Что бы вы ни думали, что хотите запустить из командной строки, запустите его с помощью кнопки на инструменте администратора.

PS

"Электронная почта с очень похожим HTML, как на моих страницах просмотра" - это узел, который вы должны разрезать.

Либо он, либо может быть идентичен страницам просмотра, и в этом случае вы хотите, чтобы AdminJob повторно использовал страницы просмотра; или нет. В этом случае AdminJob должен иметь свой собственный HTML. В этом втором случае возьмите строку, в которой нет такой вещи, как "аналогичный" HTML; если это не одно и то же, оно отличается.

Ответ 3

Я понимаю соблазн повторно использовать html с регулярных страниц веб-сайта в ваш механизм электронной почты. Однако, я думаю, что это хороший пример чрезмерной инженерии. Это создаст гораздо больше ограничений в долгосрочной перспективе, чем преимущества, которые у вас есть в краткосрочной перспективе.

Подумайте о двух вещах:

HTML для электронных писем по дизайну отличается от HTML для страниц. Хотя сегодня они выглядят одинаково, завтра они будут выглядеть по-другому. Вы только что сказали это - "электронная почта с очень похожим HTML, как у меня есть на моих страницах просмотра", вы не сказали "с одним и тем же HTML".

HTML для электронной почты не должен содержать какого-либо продвинутого HTML или какого-либо JavaScript в нем. В идеале он должен иметь встроенный CSS и без JavaScript. CSS, совместимый с почтовыми клиентами, очень ограничен. Правила разметки отличаются от естественного и современного способа написания его для обычных браузеров. Хорошим примером является то, что почтовые клиенты дружат со столами, в то время как в современной сети вы редко используете таблицы в настоящее время, особенно если вы хотите оставаться отзывчивыми (кросс-экран-платформа-браузер). Читайте обо всех ограничениях здесь: email-standards.org

HTML для современной сети не обязательно должен быть таким статическим, как должно быть сообщение электронной почты.

Все эти причины - идея популярных коммерческих отправителей электронной почты в Интернете. Они помогают вам создать список рассылки электронной почты, и они берут головную боль, чтобы создать надлежащий ограниченный HTML на своих плечах. В противном случае, могли бы они существовать? любой может отправлять групповые электронные письма, если не различия разметки.

Мой вывод из всего этого: если вы решили использовать разметку своей веб-страницы для электронных писем, вы ограничиваете их. Вы слишком сложны. Это будет намного проще, если вы не будете повторно использовать обычную разметку страницы в своих сообщениях электронной почты. Я понимаю, что сегодня они похожи, но завтра они не могут быть.

Очевидно, что неплохо иметь шаблонные возможности для вашего механизма электронной почты (не имеет никакого отношения к повторному использованию разметки веб-страниц). Для этого вы можете использовать любой из существующих шаблонных движков, или вы могли бы быстро написать свои (в конце концов, грязная строка. Replace() заменит placeholder значением, если у вас есть шаблон HTML-сообщения в виде строки, загруженный из файла или базы данных).

Другими словами, чтобы прямо ответить на ваш вопрос: не стесняйтесь расходиться по двум путям веб-страниц и электронных писем. Избегайте совместного использования, поскольку они в основном различаются. Рассмотрим два отдельно друг от друга.