#jquery #image #asp.net-mvc-3 #content-management-system
#jquery #изображение #asp.net-mvc-3 #система управления контентом
Вопрос:
На моей странице MVC3 _Layout.cshtml я показываю изображение баннера, подобное этому
<body>
<div id="page">
<div id="nonFooter">
<div id="header">
<img id="headerBanner" src="@Url.Content("~/Content/Images/banner.jpg")" alt="Banner" />
</div> ....
Достаточно просто.
Что я хочу сделать, это отобразить другое изображение для каждого клиента, использующего сайт, скорее всего, это будет определяться URL, например: www.mysite.com/clientA/Home (Клиент определяет, какое изображение использовать)
По сути, желаемая функциональность немного похожа на CMS, но нам не нужна полноценная CMS, нам просто нужно заменить несколько изображений и цветов.
Итак, вопрос в том, каков наилучший способ сделать это?
Пока я думаю использовать jQuery для обновления src следующим образом
<script type="text/javascript">
$(document).ready(function () {
$('#headerBanner').attr('src', whatToPutHere? );
});
Но я застрял на «наилучшей практике» для чего бы то ни было.
Должно ли это быть…
- Изображение, помещенное в ViewBag в серверном коде (например. @ViewBag.Изображение баннера)?
- Изображение, помещенное в ViewModel?
- Какой-то серверный вызов для получения / загрузки изображения (логика для определения того, какое изображение использовать, должна быть на стороне сервера)…(будет ли это еще один путь туда и обратно?)?
- …другой подход?
Любая помощь очень ценится 🙂
Ответ №1:
Я бы использовал только серверный код для генерации пользовательского URL-адреса изображения. Я бы не стал использовать ViewBag или model для передачи данных для просмотра, поскольку они находятся на странице _Layout. В приведенном ниже примере для простоты используются статические методы. Если вы беспокоитесь о модульном тестировании, вместо этого потребуется рефакторинг с использованием нестатических методов.
В _Layout.cshtml:
<img src="@AccountServices.BannerUrl" alt="Banner" />
В AccountServices.cs
public class AccountServices
{
public static string BannerUrl
{
get{
// Your code to form the image URL, may be the following:
var bannerPathTemplate = "/images/banners/user-{0}.jpg";
var user = CurrentUser;
if (user != null)
{
return string.Format(bannerPathTemplate, user.Id);
}
return string.Format(bannerPathTemplate, "unauthorized");
}
}
const string sessionKeyUser = "session-current-user";
public static User CurrentUser
{
get{
if (HttpContext.Current.Session[sessionKeyUser]==null){
// HERE insert code to get the current **user** object from db
HttpContext.Current.Session[sessionKeyUser] = user;
}
return (User)HttpContext.Current.Session[sessionKeyUser];
}
}
}
Другой подход для получения HTML-баннера, который я бы использовал, — это @Html.RenderAction («ваше действие», «ваш контроллер»).
Ответ №2:
Я бы не стал этого делать с помощью javascript. Почему бы вам просто не передать путь через ViewBag?
@if(ViewBag.ImagePath!=null)
{
<img id="headerBanner" src="@Url.Content(ViewBag.ImagePath)" alt="Banner" />
}
else
{
<img id="headerBanner" src="@Url.Content("~/Content/Images/default-banner.jpg")" alt="Banner" />
}
Возможно, у вас может быть фильтр действий, чтобы добавить это свойство в ваш ViewBag и украсить ваши контроллеры этим фильтром действий…
Ответ №3:
Определение того, какое изображение использовать, зависит от сервера, верно? ДА. Итак, здесь нет необходимости в javascript. Вы могли бы определить путь к изображению на сервере, в ViewBag или, возможно, ваша ViewModel содержала бы image path(). И вы бы отобразили свой path так, как вы делаете в своем первом примере, но заменили @Url.Content("~/Content/Images/banner.jpg")
на что-то вроде @Url.Content(Model.HeaderBannerImagePath)
или @Url.Content(ViewBag.HeaderBannerImagePath)