Create a helper function that returns Razor @ tags

2019-04-13 12:10发布

问题:

Struggling to find an answer to my question, as I'm not exactly sure what 'type' a razor tag is.

Essentially I want to create a helper that does something along these lines:

public static xxxxxxx ScriptTag(this HtmlHelper htmlHelper, string url)
{
      return @<script type="text/javascript" src="@Url.Content("~/" + url)" />;
}

The reason I want this is that I am implementing the extension methods that are outlined in this post.

Basically rather than have to do:

@Html.Resource(@<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>, "js")`

I want to be able to do:

@Html.Resource(Html.ScriptTag("Scripts/jquery-1.4.4.min.js"), "js");

Am I reaching beyond the stars here or is this possible?

Chris

回答1:

I don't quite see the usage of the second parameter in your ScriptTag helper (js). The helper is called ScriptTag so it is pretty obvious that it will render a script. Also why do you need those 2 nested helpers like that when you can directly have:

@Html.Resource("Scripts/jquery-1.4.4.min.js", "js")

But anyway if you needed such syntax you could use Razor Templated Delegates:

public static class HtmlExtensions
{
    public static HelperResult ScriptTag(this HtmlHelper htmlHelper, string url, string type)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var script = new TagBuilder("script");
        script.Attributes["type"] = "text/javascript";
        script.Attributes["src"] = urlHelper.Content("~/" + url);
        return new HelperResult(writer =>
        {
            writer.Write(script.ToString(TagRenderMode.Normal));
        });
    }

    public static IHtmlString Resource(this HtmlHelper htmlHelper, HelperResult renderer)
    {
        return renderer;
    }
}

As we can see the Resource extension method in this case doesn't bring much value.



回答2:

You can solve this by creating an extension method for the HtmlHelper type.

For example:

public static MvcHtmlString ScriptTag(this HtmlHelper htmlHelper, string contentPath,
    string scriptType)
{
    var httpContext = htmlHelper.ViewContext.HttpContext;

    var scriptTag = String.Format("<script src=\"{0}\" type=\"{1}\"></script>",
        UrlHelper.GenerateContentUrl(contentPath, httpContext),
        scriptType);

    return new MvcHtmlString(scriptTag);
}

You can then use your custom Html helper method as follows:

@Html.ScriptTag("Scripts/jquery1.6.1.min.js", "javascript/text");


回答3:

When the result of a function is plain HTML, I like to use Razor Helpers.

Within your view file, create a statement like that:

@helper ScriptTag(string url) {
    <script type="text/javascript" src="@Url.Content("~/" + url)"></script>
}

then the usage is like

@ScriptTag("myScript.js")

Razor Helpers return the HTML within the