#asp.net-mvc-3 #xslt
#asp.net-mvc-3 #xslt
Вопрос:
На моем рабочем месте в настоящее время поддерживается веб-сайт для нескольких клиентов, который написан с использованием классического asp. Каждый клиент требует, чтобы определенные части веб-сайта были написаны специально для него.
Например, клиенту A требуется, чтобы адрес был введен, отображен и сохранен в следующем формате:
Address Line 1
Address Line 2
Address Line 3
Address Line 4
Address Line 5
Postcode
в то время как клиент B требует, чтобы адрес вводился, отображался и сохранялся как:
Street
Town
City
Postcode
и так далее…
Поэтому мое рабочее место пошло по пути сохранения данных в виде xml в базе данных и использования xsl (о котором я в настоящее время мало знаю) для преобразования данных в html.
Итак, если нам требуется информация от пользователя через html-форму, xml преобразуется с использованием xsl. Затем пользователь вводит информацию и отправляет данные через форму. Затем для проверки данных используется страница asp. Эта страница asp относится к странице xsl, используемой для отображения формы. Таким образом, сейчас мы находимся в положении, когда для каждого клиента у нас есть много страниц xsl и много страниц asp, специфичных для клиента (где большая часть кода дублируется).
Меня попросили перенести сайт на asp.net mvc3 и устранить большую часть дублирования, и было интересно, что было бы наилучшим способом удовлетворить эту специфичную для клиента полевую функциональность. Я бы предпочел сохранить данные, хранящиеся в формате xml, поскольку доступ к уровню базы данных осуществляется с использованием com-компонентов, которые я хотел бы повторно использовать без изменений.
Я читал, что я мог бы сохранить страницы xsl и разработать механизм просмотра xslt для отображения html. Однако я не уверен, как я буду проверять данные, когда пользователь отправит форму?
Каков был бы наилучший способ отображения полей, специфичных для клиента, если бы я полностью удалил xsl? Или мне нужно иметь представления, относящиеся к конкретному клиенту, и модели просмотра?
Любые мысли будут высоко оценены.
Ответ №1:
Если вы действительно хотите использовать встроенные функции проверки / модели MVC, я думаю, что лучше всего использовать XmlSerializer или использовать DataContracts для разработки чего-то, что сериализуется в ваш XML и из него (после его извлечения из COM-объектов, поэтому вам не нужно перекодировать их), тогдавы можете использовать эти классы в качестве моделей для MVC и использовать стандартные аннотации данных для использования преимуществ более богатой функциональности модели MVC и полностью пропустить шаг XSL.
Чтобы связать это с пользовательским представлением, я обычно переопределяю механизм представления по умолчанию, чтобы иметь тот, который на самом деле будет пробовать имена, которые более специфичны для клиента / объекта, а затем возвращается к общему.
Этот механизм просмотра позволит вам передавать представление для передачи имени представления (т.Е. FallbackViewEngine.BuildViewName("General", "Customer Name")
и он будет искать «Общие.Сначала «Имя клиента.cshtml», а затем «General.cshtml» в качестве запасного варианта. Таким образом, вы можете фактически использовать представления, специфичные для клиента, в своей папке просмотра.
public class FallbackViewEngine : RazorViewEngine
{
const string NameSeparator = "==";
const string FileSeparator = ".";
public static string BuildViewName(string root, params string[] fallbackList)
{
if (string.IsNullOrWhiteSpace(root)) throw new ArgumentNullException("root");
if (fallbackList == null) throw new ArgumentNullException("fallbackList");
var sb = new StringBuilder(root);
foreach (var s in fallbackList)
{
if (string.IsNullOrWhiteSpace(s)) continue;
sb.Append(NameSeparator);
sb.Append(s);
}
return sb.ToString();
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
if (string.IsNullOrWhiteSpace(viewName)) throw new ArgumentNullException("viewName");
var names = viewName.Split(new string[] {NameSeparator}, StringSplitOptions.None);
var searched = new List<string>();
//iterate from specific to general
for (var i = names.Length; i >= 1; i--)
{
var result = base.FindView(controllerContext, string.Join(FileSeparator, names, 0, i), masterName, useCache);
if (result.View != null)
{
return resu<
}
else
{
searched.AddRange(result.SearchedLocations);
}
}
return new ViewEngineResult(searched);
}
}