5

我想知道是否有人知道是否可以使用任何“开箱即用”的 ASP.NET MVC3 助手来生成“链接按钮”......我目前使用以下内容:

<a class="button" title="My Action" href="@Url.Action("MyAction", "MyController", new { id = item.Id })">
    <img alt="My Action" src="@Url.Content("~/Content/Images/MyLinkImage.png")" />
</a>

我试图避免使用 MvcFutures,但即使我能够使用它们,我也不认为那里有一个扩展方法可以实现这一点。(我相信在这种情况下的解决方案是滚动自定义助手,如此处所示

最后,这篇文章也有一个通过 CSS 处理这个问题的好主意,但这不是我要问的......

4

3 回答 3

6

我正在使用以下内容生成操作链接:

using System;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using Fasterflect;

namespace StackOverflow.Mvc.Extensions
{
    public static class HtmlExtensions
    {
        #region ActionImage
        // href image link
        public static string ActionImage( this HtmlHelper helper, string href, string linkText, object htmlAttributes,
                                          string alternateText, string imageSrc, object imageAttributes )
        {
            var sb = new StringBuilder();
            const string format = "<a href=\"{0}\"{1}>{2}</a>";
            string image = helper.Image( imageSrc, alternateText, imageAttributes ).ToString();
            string content = string.IsNullOrWhiteSpace( linkText ) ? image : image + linkText;
            sb.AppendFormat( format, href, GetAttributeString( htmlAttributes ), content );
            return sb.ToString();
        }

        // controller/action image link
        public static string ActionImage( this HtmlHelper helper, string controller, string action, string linkText, object htmlAttributes,
                                          string alternateText, string imageSrc, object imageAttributes )
        {
            bool isDefaultAction = string.IsNullOrEmpty( action ) || action == "Index";
            string href = "/" + (controller ?? "Home") + (isDefaultAction ? string.Empty : "/" + action);
            return ActionImage( helper, href, linkText, htmlAttributes, alternateText, imageSrc, imageAttributes );
        }

        // T4MVC ActionResult image link
        public static string ActionImage( this HtmlHelper helper, ActionResult actionResult, string linkText, object htmlAttributes,
                                          string alternateText, string imageSrc, object imageAttributes )
        {
            var controller = (string) actionResult.GetPropertyValue( "Controller" );
            var action = (string) actionResult.GetPropertyValue( "Action" );
            return ActionImage( helper, controller, action, linkText, htmlAttributes, alternateText, imageSrc, imageAttributes );
        }       
        #endregion

        #region Helpers
        private static string GetAttributeString( object htmlAttributes )
        {
            if( htmlAttributes == null )
            {
                return string.Empty;
            }
            const string format = " {0}=\"{1}\"";
            var sb = new StringBuilder();
            htmlAttributes.GetType().Properties().ForEach( p => sb.AppendFormat( format, p.Name, p.Get( htmlAttributes ) ) );
            return sb.ToString();
        }       
        #endregion
    }
}

请注意,GetAttributeString 方法依赖于 Fasterflect 库来简化反射任务,但如果您不想使用额外的依赖项,则可以将其替换为常规反射。

Image helper 扩展曾经是 MvcContrib 的一部分,但似乎已被删除,很可能是因为该功能现在已内置到 MVC 中。无论如何,为了完整起见,我将其包含在下面:

public static class ImageExtensions {
    public static MvcHtmlString Image(this HtmlHelper helper, string imageRelativeUrl, string alt, object htmlAttributes) {
        return Image(helper, imageRelativeUrl, alt, new RouteValueDictionary(htmlAttributes));
    }

    public static MvcHtmlString Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
        if (String.IsNullOrEmpty(imageRelativeUrl)) {
            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
        }

        string imageUrl = UrlHelper.GenerateContentUrl(imageRelativeUrl, helper.ViewContext.HttpContext);
        return MvcHtmlString.Create(Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing));
    }

    public static TagBuilder Image(string imageUrl, string alt, IDictionary<string, object> htmlAttributes) {
        if (String.IsNullOrEmpty(imageUrl)) {
            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageUrl");
        }

        TagBuilder imageTag = new TagBuilder("img");

        if (!String.IsNullOrEmpty(imageUrl)) {
            imageTag.MergeAttribute("src", imageUrl);
        }

        if (!String.IsNullOrEmpty(alt)) {
            imageTag.MergeAttribute("alt", alt);
        }

        imageTag.MergeAttributes(htmlAttributes, true);

        if (imageTag.Attributes.ContainsKey("alt") && !imageTag.Attributes.ContainsKey("title")) {
            imageTag.MergeAttribute("title", (imageTag.Attributes["alt"] ?? "").ToString());
        }
        return imageTag;
    }
}
于 2011-02-24T23:00:53.987 回答
1

你的片段看起来相当不错。您应该将它包装在一个通用的 html 帮助程序中,然后就可以收工了。我确信您的应用程序还有其他更有趣的方面,而不是对 UI 助手的挑剔:)

于 2011-02-25T08:51:33.693 回答
0

在这篇博文的底部查看Stephen Walther 的 HTML 扩展方法示例

于 2011-05-25T14:43:31.603 回答