MVC3 ActionLink с изображениями (но без MvcFutures)? - PullRequest
5 голосов
/ 25 февраля 2011

Мне было интересно, знает ли кто-нибудь, можно ли использовать «встроенные» помощники 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, но я не об этом спрашиваю ...

Ответы [ 3 ]

6 голосов
/ 25 февраля 2011

Я использую следующее для создания ссылок действий:

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 раньше было частью 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;
    }
}
1 голос
/ 25 февраля 2011

Фрагмент, который у вас есть, выглядит неплохо. Вы должны обернуть это в вспомогательный помощник html общего назначения и назвать это днем. Я уверен, что в вашем приложении есть и другие, более интересные аспекты, чем выбор помощников в пользовательском интерфейсе:)

0 голосов
/ 25 мая 2011

Проверьте в нижней части этого сообщения в блоге пример использования методов расширения HTML от Стивена Вальтера

...