Razor and HTML Helpers

2020-02-23 08:32发布

问题:

I'm trying to port the old HTML.Image helper, that I'm sure everyone has used at one point or another, and I'm having issues. The following compiles fine:

@Html.Image("my-id", "~/Content/my-img.png", "Alt Text")

But when I try to use it in a view it simply writes:

<img alt="Alt Text" id="my-id" src="/content/my-img.png" />

And doesn't display the image. Can anyone assist?

Here's the HTML.Image helper code that I'm using:

public static class ImageHelper
{
    public static string Image(this HtmlHelper helper, string id, string url, string alternateText)
    {
        return Image(helper, id, url, alternateText, null);
    }

    public static string Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
    {
        // Instantiate a UrlHelper 
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

        // Create tag builder
        var builder = new TagBuilder("img");

        // Create valid id
        builder.GenerateId(id);

        // Add attributes
        builder.MergeAttribute("src", urlHelper.Content(url));
        builder.MergeAttribute("alt", alternateText);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        // Render tag
        var ret = new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));
        return ret.ToHtmlString();
    }

}

回答1:

The Razor view engine will automatically HTML-escape strings rendered by @-blocks.
To render actual HTML, you need to write an IHtmlString implementation in the @-block.

Change your method to return HtmlString instead of string.



回答2:

    public static HtmlString Image(this HtmlHelper helper, string id, string url, string alternateText)
    {
        return Image(helper, id, url, alternateText, null);
    }

    public static HtmlString Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
    {
        // Instantiate a UrlHelper 
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

        // Create tag builder
        var builder = new TagBuilder("img");

        // Create valid id
        builder.GenerateId(id);

        // Add attributes
        builder.MergeAttribute("src", urlHelper.Content(url));
        builder.MergeAttribute("alt", alternateText);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        // Render tag
        var ret = new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));

        return ret;
    }

just like this tested and works perfect. i needed something like this to concatenate the image name form the model thanks.

and this one works too.

 <img src="@Url.Content("~/Content/Images/Flags/" + c.CountryCode + ".jpg") " alt=""/>


回答3:

I would try wrapping the image url in a call to Url's Content method as so

@Url.Content("~/Content/my-img.png")

that should convert the relative url to absolute when the page is flushed to the browser



回答4:

I had the same problem and i had used MvcHtmlString as return type for these 2 extension method and it works

public static class ImageHelper
{
    public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string alternateText)
    {
        return Image(helper, id, url, alternateText, null);
    }

    public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string alternateText,
                               object htmlAttributes)
    {
        var builder = new TagBuilder("img");

        builder.GenerateId(id);

        builder.MergeAttribute("alt", alternateText);
        builder.MergeAttribute("src",url);

        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
    }
}