views:

114

answers:

2

In an MVC2 view, I can't get tags to work at all. They show up as broken pictures. The tag (created by an Html.ImageFor() extension method that I wrote) is a perfectly valid tag, such as this, which I copied from the page source in IE:

<img alt="Picture Display" src="~/Content/Pictures/IMGP0164 (resized).JPG" />

Note that if I don't use the helper method, and just type an tag, with a correct src URL, that ends up broken as well. If I use an tag instead, with the same src URL, that works fine, and the picture shows up as expected.

So for some reason, righteous tags simply aren't working for me from an MVC2 view. I'm very new to MVC2, but not new to ASP.NET or Html. Is there something about tags, when used in an MVC2 view, that I simply haven't found out about yet?

Thanks in advance for a clue!

+3  A: 

Your Html.ImageFor() is broken, because src="~/Content/Pictures/IMGP0164 (resized).JPG" is not a valid URI.

The tilde must be replaced with the virtual path of the site. To do that, you use Url.Content. Since you haven't shown the source for your broken method, I can't fix it, but in plain markup you would write:

<img alt="Picture Display" src="<%= Url.Content("~/Content/Pictures/IMGP0164 (resized).JPG")" />

You can use the same idea inside your helper.

Craig Stuntz
That sounds like a good solution, but I haven't been able to get it to work in the helper method. I haven't found any way to make the Url namespace available there, and Microsoft's "help" isn't very helpful in this case. Thanks, though!
Jerry Houston
Finally got it working! Thanks to the clue you gave me, I modified the controller to put the paths in the model starting with ../../, and nothing else needed to be changed. Thanks again!
Jerry Houston
A: 

Here's the requested helper method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using PictureThis.Models;


namespace System.Web.Mvc.Html
{
    public static class ExtensionMethods
    {
        //  HtmlHelper Extensions

        /// <summary>
        /// Builds an Html image element.
        /// </summary>
        /// <param name="helper">Required target param</param>
        /// <param name="src">Source URL attribute</param>
        /// <param name="alt">Alt text attribute</param>
        /// <returns></returns>
        public static MvcHtmlString ImageFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string alt)  
        {  
            TagBuilder tb = new TagBuilder("img");
            Delegate GetSource = expression.Compile();
            string source = GetSource.DynamicInvoke(html.ViewData.Model).ToString();
            tb.Attributes.Add("src", source);  
            tb.Attributes.Add("alt", alt);  
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));  
        }      
    }
}
Jerry Houston