1

On my MVC3 _Layout.cshtml page I show a banner image like this

    <body>
    <div id="page">
        <div id="nonFooter">
            <div id="header">
               <img id="headerBanner" src="@Url.Content("~/Content/Images/banner.jpg")" alt="Banner" />
            </div> ....

Simple enough.

What I want to do is display a different image for each client using the site, most likely this will be determined by the url, eg: www.mysite.com/clientA/Home (clientA determines which image to be used)

Essentially the desired functionality is a bit CMS like but we don't need a full blown CMS, we just need to replace a few images and colors.

So the question is what is the best way to do this?

My thinking so far is to use jQuery to update the src like this

<script type="text/javascript">
$(document).ready(function () {
    $('#headerBanner').attr('src', whatToPutHere? );
});    

But I'm stuck on 'best practice' for the whatToPutHere.

Should it be...

  • An image put in the ViewBag in the serverside code (eg. @ViewBag.BannerImage)?
  • An image put in the ViewModel?
  • Some kind of server call to get/load the image (logic to determine which image to use must be server side)...(would this be another round trip though?)?
  • ...another approach?

Any help much appreciated :-)

3 Answers 3

2

I would use only server side code to generate the user specific image URL. I would not use ViewBag or model to pass the data to View, since it's in the _Layout page. In the example below there are static methods for simplicity. If you bother about unit testing it need refactoring with non-static methods instead.

In _Layout.cshtml:

<img src="@AccountServices.BannerUrl" alt="Banner" />

In 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];
       }
   }

}

Another approach to get the banner HTML I would use is @Html.RenderAction("your action", "your controller").

Sign up to request clarification or add additional context in comments.

Comments

1

I wouldn't do this with javascript. Why don't you just pass the path via de 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" />
}

Maybe you can have an action filter to add this property to your ViewBag and decorate your controllers with this action filter...

Comments

1

The determination of which image to use, depends on server, right? Yes. So, no need for javascript here. You could determine image path on server, in the ViewBag or maybe your ViewModel would contain image path(). And you would render your path as you do in your first example, but replace the @Url.Content("~/Content/Images/banner.jpg") with something like @Url.Content(Model.HeaderBannerImagePath) or @Url.Content(ViewBag.HeaderBannerImagePath)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.