1

I am building a site that will eventually pull images from a separate domain. That domain doesn't exist yet, nor has its name even been concluded upon, so for the time being I need to access images from a local directory. To avoid manually changing every single image tag later on, I want to use a global variable that I can change once and affect every single image tag on the website.

I have found one solution thus far, which is to set a key/value pair in Web.config's appSettings like so...

<appSettings> <add key="ImageSource" value="/some/local/directory" /> </appSettings> 

Then, in each view, at the top, I add...

@{ string imgsrc = System.Configuration.ConfigurationManager.AppSettings["ImageSource"]; } 

And in the HTML I use...

<img src="@imgsrc/my_image.jpg" alt="my image" /> 

This works but it still requires me to assign the variable in every single view template that I create. In the spirit of DRY, I am looking for some way that I can assign the variable once and have its presence implicit in every page, regardless of model, controller, or view.

2 Answers 2

1

I like using extension methods on the built-in HtmlHelper class for this type of thing. You can have an HtmlHelper extension such as:

 public static MvcHtmlString ImageReference( this HtmlHelper html, String id, String altText, String imageNameAndExtension) { var baseUrl = [go get the setting value]; String src = String.Concat(baseUrl, imageNameAndExtension); var img = new TagBuilder("img"); if (String.IsNullOrEmpty(id) == false) img.MergeAttribute("id", id); if (String.IsNullOrEmpty(altText) == false) img.MergeAttribute("alt", altText); img.MergeAttribute("src", src); return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing)); } 

Then consume like:

@Html.ImageReference("TheImage", "A Cool Image", "doublerainbow.png") 

Usually you end up with a few overrides flowing through a single method (e.g. no id parameter, etc.) There are some really nice side-effects, too. If the whole team uses these, you end up with very standardized markup.

More Info: http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs

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

4 Comments

I like this idea but, due to my inexperience, I have spent the last two hours failing to implement it. Based on what you said, I found a handful of tutorials on creating custom HtmlHelper extensions but not a single one of them worked. Even the one in the link you gave me failed to work. I am sure that I'm doing something wrong but, obviously, I don't know what that is...
I had a feeling that if I gave up and posted something the answer would hit me in the face—and so it did. It turns out that I wasn't importing the namespace. Once I did that, the HtmlHelper that I created showed up in the list. But this means that I still have to include something on every page in order to have this work. That's what I'm trying to avoid so I don't think this is what I'm looking for, though I appreciate the suggestion all the same.
Yeah - this is not obvious - in the web.config file in Views folder, add the namespace to the <system.web.webPages.razor> section. Magically, it's available on all pages. It's sort of like a global imports for all your razor views.
Ah, that fixed it! Since my request was for a way to do this regardless of model, controller, or view, and since this does exactly that (it's defined in a Helpers folder), and since the other answer was defined in the controllers, I'm marking this answer as my accepted answer. Thanks!
0

The easiest way would be to inject your logic into the request pipeline which gets executed each time so you just have to set it in one place. You would then need to set ImageSource in a place where it would be available to the views.

In the following example, I create a base controller that other controllers inherit from. Then override the OnActionExecuting method and set the ViewBag.

Now this value is available to all views where the controller inherits from BaseController.

public abstract class BaseController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { ViewBag.ImageSource = System.Configuration.ConfigurationManager.AppSettings["ImageSource"]; } } 

1 Comment

This looks like it's going to work! What I really like about this approach is that it allows me to still use the img tag so that anyone else reading through will be able to see what I'm doing. Thanks a lot!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.