【问题标题】:Image equivalent of ActionLink in ASP.NET MVCASP.NET MVC 中 ActionLink 的等效图像
【发布时间】:2010-09-17 15:57:14
【问题描述】:

在 ASP.NET MVC 中是否有与 Img 标记的 Html.ActionLink 助手等效的工具?

我有一个输出动态生成的 JPEG 的控制器操作,我想使用相同的 Lambda 表达式链接到它,就像我使用 ActionLink 做 HREF 一样。

另外,仅将 URL 提供给路由的帮助程序(再次使用 Lambda 指定)也是可以接受的。

编辑:我最初指定我使用的是预览版 5,但是我看到已经发布了一个 Beta。所以总而言之,版本号是一个不需要的信息,因为我可能很快就会升级:-)

【问题讨论】:

    标签: asp.net-mvc routing


    【解决方案1】:

    可以使用 URL.Action 方法

    <a href="<%= Url.Action("Create")  %>"><img src="../../Content/Images/add_48.png" /></a>
    

    【讨论】:

    • 这很棒!刚刚传入动作和控制器,它就像一个魅力!谢谢
    • @RichardEverett 那么如何使用 Razor @?你介意提供一个简单的演示代码吗?
    • &lt;%= Url.Action("Create") %&gt; 更改为@Url.Action("Create")
    【解决方案2】:

    这个问题比较老,我最近刚开始使用 ASP.NET MVC,当时 RC 已经出来了,但是对于像我这样后来发现这个问题的人来说,这可能很有趣:

    至少在 RC 中,您也可以将 Url.Action() 与匿名类型一起使用,结果看起来比上面的建议要好得多,我猜:

    <a href="<%= Url.RouteUrl("MyRoute", new { param1 = "bla", param2 = 5 }) %>">
       put in <span>whatever</span> you want, also <img src="a.gif" alt="images" />.
    </a>
    

    当然,RouteUrl 还有许多其他重载。

    【讨论】:

      【解决方案3】:

      Url.Action() 将为您提供大多数 Html.ActionLink 重载的裸 URL,但我认为 URL-from-lambda 功能目前只能通过 Html.ActionLink 获得。希望他们会在某个时候为 Url.Action 添加类似的重载。

      【讨论】:

      • parse-the-lambda 功能在 MvcToolkit 中是一个非常方便的方法,它只是内部的。您可以添加自己的扩展方法,通过反射调用它(或重新编译 MvcToolkit 并将其公开),假设官方将很快替换它。
      • 如果你用这个做一个很好的扩展方法(比如:Html.ActionImage()),它不应该让你的视图混乱:)
      【解决方案4】:

      我使用了一种解决方法来为 ActionLink 放置一个标记而不是文本,然后用我的图像代码替换它。像这样的:

      <%= Html.ActionLink("__IMAGE_PLACEHOLDER__", "Products").Replace("__IMAGE_PLACEHOLDER__", "<img src=\"" + myImgUrl + "\" />")%>
      

      不是最优雅的解决方案,但它确实有效。

      【讨论】:

      • 这就是我正在做的,除了我有一个用于构建 img 标签的扩展方法。将它包含在扩展方法本身中会很棒,我可能会这样做。
      【解决方案5】:

      在 MVC3 中,您的链接如下所示:

      <a href="@Url.Action("Create")"><img src="../../Content/Images/add_48.png" /></a>
      

      【讨论】:

      • 当然,如果可能的话,不要忘记img 元素的alt 属性。
      【解决方案6】:

      在 ASP.NET MVC Beta 中,您可以在 Futures 程序集中使用 Html.BuildUrlFromExpression 方法(不包含在默认的 ASP.NET MVC 安装中,但可从 CodePlex 获得) 使用 lambda 样式的 ActionLink 语法围绕图像(或任何 HTML)创建链接,如下所示:

      <a href="<%=Html.BuildUrlFromExpression<MyController>(c => c.MyAction())%>">
           <%=Html.Image("~/Content/MyImage.gif")%>
      </a>
      

      要使您的图片链接保持无边界,您需要添加这样的 CSS 规则:

      img
      {
           border: none;
      }
      

      【讨论】:

        【解决方案7】:

        您可以使用此控件。它的行为类似于 ActionLink。

        http://agilefutures.com/index.php/2009/06/actionimage-aspnet-mvc

        【讨论】:

          【解决方案8】:

          在 MVC 2 中实现非常简单。我创建了自己的非常简单的扩展方法来支持 Url.Action 助手的 Lambda 表达式。它要求您引用 MVC 2 Futures。
          代码如下:

          using System;
          using System.Linq.Expressions;
          using System.Web.Mvc;
          using System.Web.Routing;
          
          using ExpressionHelperInternal=Microsoft.Web.Mvc.Internal.ExpressionHelper;
          
          namespace Bnv.Bssi.Web.Infrastructure.Helpers
          {
              public static class UrlExtensions
              {
                  public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action) where TController : Controller
                  {
                      RouteValueDictionary routeValuesFromExpression = ExpressionHelperInternal.GetRouteValuesFromExpression<TController>(action);
          
                      return helper.Action(routeValuesFromExpression["action"].ToString(), routeValuesFromExpression);
                  }
              }
          }
          

          这就是你如何使用它:

          <img src="<%= Url.Action<YourController>(c => c.YourActionMethod(param1, param2)); %>" />
          

          【讨论】:

            【解决方案9】:

            我知道我的帖子太晚了,但我想分享:)

            我添加了类似这样的新扩展方法:

            public static class ImageExtensions
            {
                public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string imgSrc, string additionalText = null, string actionName = null, string controllerName = null, object routeValues = null, object linkHtmlAttributes = null, object imgHtmlAttributes = null)
                {
                    var urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
                    var url = "#";
                    if (!string.IsNullOrEmpty(actionName))
                        url = urlHelper.Action(actionName, controllerName, routeValues);
            
                    var imglink = new TagBuilder("a");
                    imglink.MergeAttribute("href", url);
                    imglink.InnerHtml = htmlHelper.Image(imgSrc, imgHtmlAttributes) + " " + additionalText;
                    linkHtmlAttributes = new RouteValueDictionary(linkHtmlAttributes);
                    imglink.MergeAttributes((IDictionary<string, object>)linkHtmlAttributes, true);
            
                    return MvcHtmlString.Create(imglink.ToString());
                }
            
                public static MvcHtmlString Image(this HtmlHelper htmlHelper, string imgSrc, object imgHtmlAttributes = null)
                {
                    var imgTag = new TagBuilder("img");
                    imgTag.MergeAttribute("src", imgSrc);
                    if (imgHtmlAttributes != null)
                    {
                        imgHtmlAttributes = new RouteValueDictionary(imgHtmlAttributes);
                        imgTag.MergeAttributes((IDictionary<string, object>)imgHtmlAttributes, true);
                    }
                    return MvcHtmlString.Create(imgTag.ToString());
                }
            }
            

            希望这会有所帮助。

            【讨论】:

              【解决方案10】:

              Url.Content() 是您要查找的内容吗?

              给它一些类似 Url.Content("~/path/to/something.jpg") 的东西,它会根据应用程序根目录把它变成适当的路径。

              -乔什

              【讨论】:

                【解决方案11】:

                我接受了上述答案并做了一些包装扩展:

                    public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName)
                        {
                            return ActionImageLink(helper, src, altText, url, actionName, controllerName, null, null);
                        }
                
                        public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName, Dictionary<string, string> linkAttributes, Dictionary<string, string> imageAttributes)
                        {
                            return ActionImageLink(helper, src, altText, url, actionName, controllerName, null, linkAttributes, imageAttributes);
                        }
                
                        public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName, dynamic routeValues, Dictionary<string, string> linkAttributes, Dictionary<string, string> imageAttributes)
                        {
                            var linkBuilder = new TagBuilder("a");
                            linkBuilder.MergeAttribute("href", routeValues == null ? url.Action(actionName, controllerName) : url.Action(actionName, controllerName, routeValues));
                
                            var imageBuilder = new TagBuilder("img");
                            imageBuilder.MergeAttribute("src", url.Content(src));
                            imageBuilder.MergeAttribute("alt", altText);
                
                            if (linkAttributes != null)
                            {
                                foreach (KeyValuePair<string, string> attribute in linkAttributes)
                                {
                                    if (!string.IsNullOrWhiteSpace(attribute.Key) && !string.IsNullOrWhiteSpace(attribute.Value))
                                    {
                                        linkBuilder.MergeAttribute(attribute.Key, attribute.Value);
                                    }
                                }
                            }
                
                            if (imageAttributes != null)
                            {
                                foreach (KeyValuePair<string, string> attribute in imageAttributes)
                                {
                                    if (!string.IsNullOrWhiteSpace(attribute.Key) && !string.IsNullOrWhiteSpace(attribute.Value))
                                    {
                                        imageBuilder.MergeAttribute(attribute.Key, attribute.Value);
                                    }
                                }
                            }
                
                            linkBuilder.InnerHtml = MvcHtmlString.Create(imageBuilder.ToString(TagRenderMode.SelfClosing)).ToString();
                            return MvcHtmlString.Create(linkBuilder.ToString());
                        }
                

                无论如何,这对我来说更容易,希望它可以帮助其他人。

                【讨论】:

                • 我喜欢这个扩展,但是,this HtmlHelper helper 是多余的。我将其更改为this UrlHelper url 并使用Url.ActionImageLink(...) 调用它
                • 或者您可以执行var _url = new UrlHelper(htmlHelper.ViewContext.RequestContext).Action(_actionName, _mergedRouteValues); 之类的操作来获取 UrlHelper。我无耻地从@Tobi 提供的链接中偷了这个。
                • @JimGilmartin 我明白了,好主意。我使用 htmlhelper 的唯一原因是我可以像使用任何其他 razor helper 一样使用它,这样我就不用记住它的存储/访问位置了。
                【解决方案12】:

                我尝试将 Html.Image 的输出放入我的 Html.ImageLink 助手中。

                @(new HtmlString(Html.ActionLink(Html.Image("image.gif").ToString(), "myAction", "MyController").ToString().Replace("&lt;", "<").Replace("&gt;", ">")))
                

                对我来说问题是,ActionLink 名称是编码的,所以我有 &lt 而不是 <.>

                我刚刚删除了这个编码,结果对我有用。 (有没有更好的方法来代替使用替换?)

                【讨论】:

                  【解决方案13】:

                  添加到其他帖子:在我的情况下(asp.net mvc 3)我想要一个图像链接作为语言选择器,所以我最终得到:

                    public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string imgSrc, string cultureName, object htmlAttributes, object imgHtmlAttributes, string languageRouteName = "lang", bool strictSelected = false)
                          {
                             UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
                             TagBuilder imgTag = new TagBuilder("img");
                             imgTag.MergeAttribute("src", imgSrc);
                             imgTag.MergeAttributes((IDictionary<string, string>)imgHtmlAttributes, true);
                  
                             var language = htmlHelper.LanguageUrl(cultureName, languageRouteName, strictSelected);                      
                             string url = language.Url;
                  
                             TagBuilder imglink = new TagBuilder("a");
                             imglink.MergeAttribute("href", url);
                             imglink.InnerHtml = imgTag.ToString();
                             imglink.MergeAttributes((IDictionary<string, string>)htmlAttributes, true);
                  
                             //if the current page already contains the language parameter make sure the corresponding html element is marked
                             string currentLanguage = htmlHelper.ViewContext.RouteData.GetRequiredString("lang");
                             if (cultureName.Equals(currentLanguage, StringComparison.InvariantCultureIgnoreCase))
                             {
                                imglink.AddCssClass("selectedLanguage");
                             }
                             return new MvcHtmlString(imglink.ToString());
                          }
                  

                  内部化支持是通过语言路径完成的 - 原始来源 here

                  【讨论】:

                    【解决方案14】:

                    这里有不错的解决方案,但如果您想在操作链接中添加更多图片而不是图片怎么办?我就是这样做的:

                         @using (Html.BeginForm("Action", "Controler", ajaxOptions))
                         { 
                            <button type="submit">
                               <img src="image.png" />            
                            </button>
                         }
                    

                    缺点是我仍然需要对按钮元素进行一些样式设置,但是您可以将所有想要的 html 放在那里。

                    它也适用于 Ajax 助手:https://stackoverflow.com/a/19302438/961139

                    【讨论】:

                      猜你喜欢
                      • 2023-03-12
                      • 1970-01-01
                      • 2012-02-13
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-08-18
                      • 1970-01-01
                      • 2014-02-09
                      • 2013-10-15
                      相关资源
                      最近更新 更多