В моем предыдущем посте я рассмотрел создание статических ссылок на контент, которые мы используем в ASP .Net с использованием шаблонов T4. Было несколько вопросов, на которые я указал, и некоторые другие, которые мне указали.
<head runat="server">
<link href="<%= Url.Content(Content.Site) %>" rel="stylesheet" type="text/css" />
</head>
Мой код неверный
Более чем одним способом. Посмотрите на сгенерированный код:
public static class Content
{
public static class Images
{
public const string Add = "~/Content/Content/Images/Add.png";
public const string Check = "~/Content/Content/Images/Check.png";
public const string Delete = "~/Content/Content/Images/Delete.png";
public const string Edit = "~/Content/Content/Images/Edit.png";
public const string FolderBackground = "~/Content/Content/Images/FolderBackground.gif";
public const string FolderBottom = "~/Content/Content/Images/FolderBottom.gif";
public const string FolderTop2 = "~/Content/Content/Images/FolderTop2.gif";
public const string Guy = "~/Content/Content/Images/Guy.png";
public const string Mail = "~/Content/Content/Images/Mail.png";
public const string Papers = "~/Content/Content/Images/Papers.jpg";
}
public const string Site = "~/Content/Content/Site.css";
}
Да, я пропустил это — сгенерированные ссылки на самом деле не так. Я очевидно был слишком взволнован, что это действительно работало (после борьбы с монстрами T4 в течение долгого времени). Это легко исправить. Корневой путь должен просто измениться с
void GenerateLinksForFolder(Project mainProject, string folderName)
{
var projectItem = GetProjectItem(mainProject, folderName);
RecursivelyIterateThroughFolder(projectItem, string.Format("~/{0}/", folderName));
}
в
void GenerateLinksForFolder(Project mainProject, string folderName)
{
var projectItem = GetProjectItem(mainProject, folderName);
RecursivelyIterateThroughFolder(projectItem,"~/");
}
Рендеринг ссылок в разделе заголовка
Следующая ошибка, которую я сделал, была связана с отображением тега ссылки для таблицы стилей.
<head runat="server">
<link href="<%= Url.Content(Content.Site) %>" rel="stylesheet" type="text/css" />
</head>
Предоставленная ссылка выглядит так:

Дэвид Эббо указал на происходящее, а также на очевидный обходной путь.
Когда вы используете выражение с двойными кавычками, анализатор запутывается, потому что они конфликтуют с двойными кавычками для атрибута href. Поэтому он не рассматривает тег ссылки как нечто особенное. Но с улучшенным выражением нет двойных кавычек. Обходной путь? Добавить + »». Я знаю, не красиво, может быть, лучше.
Проблема относится только к разделу head — если я поместил точно такой же код в раздел body, то отрендеренный код будет правильным.
В моем предыдущем посте я также упоминал, что я не заменяю весь вызов Url.Content — я просто пытаюсь удалить зависимость от строк. Однако в этом случае я думаю, что замена всего тега ссылки будет лучшим вариантом. Я просто добавил 2 метода расширения .
public static class ContentLinkHelpers
{
public static string Stylesheet(this UrlHelper helper, string content)
{
return string.Format("<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />", helper.Content(content));
}
public static string Script(this UrlHelper helper, string content)
{
return string.Format("<script src=\"{0}\" type=\"text/javascript\"></script>", helper.Content(content));
}
}
Это позволяет нам отображать таблицу стилей (и сценарии), используя вспомогательные методы.
<head runat="server">
<%= Url.Stylesheet(Content.Site) %>
<%= Url.Script(Scripts.Jquery132) %>
</head>
Я обычно предпочитаю не использовать помощников, которые генерируют полные HTML-элементы, поскольку (на мой взгляд) это делает код менее читабельным, но в этом случае синтаксис работает очень хорошо.
Санировать вход
Что-то, что я не упомянул (что на самом деле работает правильно, * вздох *) — это необходимость дезинфицировать входные данные. Например, сценарию с именем Jquery-1.3.2-Vsdoc.js требуется имя переменной, похожее на Jquery132Vsdoc . Я сделал преобразование с помощью регулярного выражения .
return Regex.Replace(name, "[^a-zA-Z0-9_]", string.Empty);
Хотя это будет работать для примера Jquery-1.3.2-Vsdoc.js , нам все равно нужно исключить все ключевые слова C #. Например, изображение с именем « lock » будет генерировать ошибки компиляции, поскольку « lock » является зарезервированным словом.
К сожалению, нет способа получить программный доступ к списку ключевых слов C # — лучшее, что мы можем сделать, — это поддерживать список в коде и проверять этот список.
foreach(var keyword in keywords)
{
if (keyword.Equals(sanitized))
{
return "@" + sanitized;
}
}
return sanitized;
Это будет правильно генерировать имена переменных для любого содержимого.
public const string @lock = "~/Content/Images/lock.png";
Использование шаблонов MVC T4
Как я уже упоминал, следующий очевидный шаг — для одного шаблона, который можно включить в любой проект. Благодаря Дэвиду Эббо шаблон MVC T4 (теперь называемый T4MVC) теперь доступен на CodePlex, как одна из загрузок на странице исходного кода ASP.NET MVC v1.0 .
Свежие комментарии