#c# #asp.net #.net
#c# #asp.net #.net
Вопрос:
Я знаю, что это невозможно; я действительно ищу обходной путь. У меня есть куча классов в . файл dll, который наследует один и тот же абстрактный HtmlGenerator
класс. Все, что они делают, это генерируют HTML-контент для частей страницы на основе определенных пользовательских настроек. У меня также есть JavascriptGenerator
и CssGenerator
, которые делают практически то же самое. Очень похоже на UserControl
😉
Все эти элементы управления либо отображаются на странице, либо могут быть загружены с помощью вызовов AJAX.
Проблема, с которой я сталкиваюсь, заключается в том, что строки содержат много "
, и вставлять строки становится немного некрасиво. Было бы неплохо, если бы я мог поместить их в файлы .ascx.
Я понимаю, что ascx файлы не могут быть помещены в библиотеку классов, потому что ссылки на другие файлы, такие как изображения, не будут работать. Но все мои файлы сгенерированы в формате HTML на основе определенных данных профиля. Нет никаких изображений и не выполняется никаких действий, таких как редактирование значений в базе данных.
Вы можете наследовать UserControl
и переопределить Render
метод в библиотеке классов, но есть ли способ скомпилировать файл ascx в библиотеке классов? Или есть достаточно приличный обходной путь? Возможно, мне следует поместить HTML-код в файл ресурсов?
Комментарии:
1. Да, вы можете, но какая версия ASP.NET используете ли вы?
2. @James 2.0 на сервере, я думаю. Довольно старый сервер, но у меня есть VS2010, и я пишу сайт на .NET 3.5
3. @SLaks, я часто видел Razor, но я никогда не заглядывал в него раньше. Я сам избегал необходимости в этом (кажется, до сих пор). Не могли бы вы дать мне пару полезных советов или ссылок? Есть быстрые указания?
Ответ №1:
Попробуйте:
- Закрыть VS.NET 2005.
- Откройте каталог
C:Program FilesMicrosoft Visual Studio 8WebWebNewFileItemsCSharp
(при условии установки по умолчанию VS.NET ). - Откройте файл CSharpItems.vsdir в блокноте. Выделите текст и скопируйте его в буфер обмена.
- Теперь откройте файл
C:Program FilesMicrosoft Visual Studio 8VC#CSharpProjectItemsCSharpItems.vsdir
и вставьте содержимое буфера обмена под существующий текст. - Теперь скопируйте содержимое
C:Program FilesMicrosoft Visual Studio 8WebWebNewFileItemsCSharp
(исключая CSharpItems.vsdir) в папкуC:Program FilesMicrosoft Visual Studio 8VC#CSharpProjectItems
.
Вот сообщение от Скотта Гатри, которое тоже может помочь:
http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx
Комментарии:
1. Извините, Джеймс, я действительно не понимаю, к чему вы здесь клоните. Что это должно делать?
2. Это дает вам доступ к веб-элементам управления из библиотеки классов.
3. Может немного отличаться для VS2010. Вот почему я спросил, какая версия ASP.NET вы использовали. Я полагаю, следовало спросить, какую версию VS вы использовали.
4. Я сказал, что использую VS2010 😉 Я все равно попробую. Я должен быть в состоянии разобраться с различиями
Ответ №2:
Я создал кое-что почти точно для этой цели. Проект называется eView и размещен на GitHub под лицензией BSD. Код не самый читаемый (весь он помещен в один файл T4 для работы как с Mono, так и с .Net), но он работает для меня на моем веб-сайте.
Он использует T4 для создания статически скомпилированных «представлений». Итак, вы просто создаете папку с именем «Шаблоны» (или что-то еще), помещаете EViewGenerator.tt файл в нем и добавьте HTML-файлы (или любые файлы, которые вы хотите). Он обработает их в очень простой для отображения C # обычный старый объект. Например, вы могли бы разместить TestFile.html в нем с этим содержимым:
{@ Title as string; @}
<html><head>
<title>{=Title=}</title>
<body>
Hey check out the dynamic title
</body>
</html>
а затем, когда вы переходите к рендерингу его в виде текста, вы просто делаете что-то вроде:
var view=new TestFile();
view.Title="Some Title";
Response.Write(view.EViewRender()); //render returns a string
Я создал его, чтобы решить почти точно проблему, которую вы описываете, поэтому я подумал, что, возможно, на это стоит взглянуть, даже если это не самое «полное» решение.
Некоторые вещи, которые недостаточно хорошо документированы, включают функциональность foreach:
Foreach test: <br />
{#
var strings=new String[]{"Foo","Bar","Biz"};
#}
{!foreach s in strings!}
s is equal to {=s=} <br />
{!end!}
а также «макеты», похожие на мастер-страницы
MasterLayout.html:
{@
Content as IEView;
Comments as IEView;
Title as string;
@}
<html>
<head><title>{=Title=}</title></head>
<body>
<div class="content">
{= Content =}
</div>
<div class="comments">
{= Comments =}
</div>
</body>
</html>
и затем пример содержимого.
MyContent.html:
{!layout MasterLayout!}
{!layout_field Content!}
This is some example content!
И для визуализации:
var v=new MyContent();
v.Layout.Title = "My content";
v.Layout.Comments = new SomeCommentView();
Response.Write(v.EViewRender());
Комментарии:
1. Выглядит довольно мило. Хотя это очень похоже на razor. Однако мне нужна одна важная функция; есть ли у нее какая-то возможность цикла foreach?
2. @Connell документации немного не хватает (хотя документация скучная! 🙂 ) но я включил пример цикла foreach.
Ответ №3:
Я нашел хороший способ сделать это сам, которым я поделюсь со всеми. Тем не менее, я ценю ответы.
Я изменил свой HtmlGenerator
на интерфейс, близкий к следующему:
public interface IHtmlGenerator
{
void Load(User user);
void RenderControl(HtmlTextWriter writer);
}
Затем я изменил код, который считывает HTML в виде строки, чтобы создать HtmlTextWriter
из StringWriter
объекта, который может быть заполнен HTML с помощью RenderControl
метода.
На самом деле это было довольно просто.. Я добавил еще один веб-проект, получил все UserControl
классы для наследования IHtmlGenerator
. У UserControl уже есть определение для void RenderControl(HtmlTextWriter writer)
, так что это был просто случай добавления Load
метода.