Как динамически загружать изображение в ASP.NET-MVC3 с помощью jQuery

#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)