Action Image MVC3 Razor

在 MVC3中使用 Razor 将链接替换为图像的最佳方法是什么。我现在只是这样做:

<a href="@Url.Action("Edit", new { id=MyId })"><img src="../../Content/Images/Image.bmp", alt="Edit" /></a>

还有更好的办法吗?

133811 次浏览

您可以使用 Url.Content,它为所有链接工作,因为它将波浪形 ~转换为根 uri。

<a href="@Url.Action("Edit", new { id=MyId })">
<img src="@Url.Content("~/Content/Images/Image.bmp")", alt="Edit" />
</a>

您可以为 HtmlHelper 创建一个扩展方法,以简化 CSHTML 文件中的代码。你可以用这样的方法替换你的标签:

// Sample usage in CSHTML
@Html.ActionImage("Edit", new { id = MyId }, "~/Content/Images/Image.bmp", "Edit")

Here is a sample extension method for the code above:

// Extension method
public static MvcHtmlString ActionImage(this HtmlHelper html, string action, object routeValues, string imagePath, string alt)
{
var url = new UrlHelper(html.ViewContext.RequestContext);


// build the <img> tag
var imgBuilder = new TagBuilder("img");
imgBuilder.MergeAttribute("src", url.Content(imagePath));
imgBuilder.MergeAttribute("alt", alt);
string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);


// build the <a> tag
var anchorBuilder = new TagBuilder("a");
anchorBuilder.MergeAttribute("href", url.Action(action, routeValues));
anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);


return MvcHtmlString.Create(anchorHtml);
}

嗯,你可以用@Lucas 的方法,但是还有另外一种方法。

 @Html.ActionLink("Update", "Update", *Your object value*, new { @class = "imgLink"})

Now, add this class on a CSS file or in your page:

.imgLink
{
background: url(YourImage.png) no-repeat;
}

有了这个类,任何链接都会有你想要的图像。

这个扩展方法也可以工作(放置在一个公共静态类中) :

    public static MvcHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, object routeValues, AjaxOptions ajaxOptions)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", imageUrl);
builder.MergeAttribute("alt", altText);
var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions);
return new MvcHtmlString( link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)) );
}

基于 Lucas 上面的答案,这是一个以控制器名称作为参数的重载,类似于 ActionLink。当图像链接到不同控制器中的 Action 时,请使用此重载。

// Extension method
public static MvcHtmlString ActionImage(this HtmlHelper html, string action, string controllerName, object routeValues, string imagePath, string alt)
{
var url = new UrlHelper(html.ViewContext.RequestContext);


// build the <img> tag
var imgBuilder = new TagBuilder("img");
imgBuilder.MergeAttribute("src", url.Content(imagePath));
imgBuilder.MergeAttribute("alt", alt);
string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);


// build the <a> tag
var anchorBuilder = new TagBuilder("a");


anchorBuilder.MergeAttribute("href", url.Action(action, controllerName, routeValues));
anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);


return MvcHtmlString.Create(anchorHtml);
}

这是一条非常有用的线索。

对于那些对卷曲牙套过敏的人,下面是 VB.NET 版本的 Lucas 和 Crake 的回答:

Public Module ActionImage
<System.Runtime.CompilerServices.Extension()>
Function ActionImage(html As HtmlHelper, Action As String, RouteValues As Object, ImagePath As String, AltText As String) As MvcHtmlString


Dim url = New UrlHelper(html.ViewContext.RequestContext)


Dim imgHtml As String
'Build the <img> tag
Dim imgBuilder = New TagBuilder("img")
With imgBuilder
.MergeAttribute("src", url.Content(ImagePath))
.MergeAttribute("alt", AltText)
imgHtml = .ToString(TagRenderMode.Normal)
End With


Dim aHtml As String
'Build the <a> tag
Dim aBuilder = New TagBuilder("a")
With aBuilder
.MergeAttribute("href", url.Action(Action, RouteValues))
.InnerHtml = imgHtml 'Include the <img> tag inside
aHtml = aBuilder.ToString(TagRenderMode.Normal)
End With


Return MvcHtmlString.Create(aHtml)


End Function


<Extension()>
Function ActionImage(html As HtmlHelper, Action As String, Controller As String, RouteValues As Object, ImagePath As String, AltText As String) As MvcHtmlString


Dim url = New UrlHelper(html.ViewContext.RequestContext)


Dim imgHtml As String
'Build the <img> tag
Dim imgBuilder = New TagBuilder("img")
With imgBuilder
.MergeAttribute("src", url.Content(ImagePath))
.MergeAttribute("alt", AltText)
imgHtml = .ToString(TagRenderMode.Normal)
End With


Dim aHtml As String
'Build the <a> tag
Dim aBuilder = New TagBuilder("a")
With aBuilder
.MergeAttribute("href", url.Action(Action, Controller, RouteValues))
.InnerHtml = imgHtml 'Include the <img> tag inside
aHtml = aBuilder.ToString(TagRenderMode.Normal)
End With


Return MvcHtmlString.Create(aHtml)


End Function


End Module

为了增加 Luke 开始的所有令人惊叹的工作,我又发布了一个使用 css class 值并将 class 和 alt 作为可选参数的文章(在 ASP.NET 3.5 + 下有效)。这将允许更多的功能,但减少所需的重载方法的数量。

// Extension method
public static MvcHtmlString ActionImage(this HtmlHelper html, string action,
string controllerName, object routeValues, string imagePath, string alt = null, string cssClass = null)
{
var url = new UrlHelper(html.ViewContext.RequestContext);


// build the <img> tag
var imgBuilder = new TagBuilder("img");
imgBuilder.MergeAttribute("src", url.Content(imagePath));
if(alt != null)
imgBuilder.MergeAttribute("alt", alt);
if (cssClass != null)
imgBuilder.MergeAttribute("class", cssClass);


string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);


// build the <a> tag
var anchorBuilder = new TagBuilder("a");


anchorBuilder.MergeAttribute("href", url.Action(action, controllerName, routeValues));
anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);


return MvcHtmlString.Create(anchorHtml);
}

修改幻灯片助手

     public static IHtmlString ActionImageLink(this HtmlHelper html, string action, object routeValues, string styleClass, string alt)
{
var url = new UrlHelper(html.ViewContext.RequestContext);
var anchorBuilder = new TagBuilder("a");
anchorBuilder.MergeAttribute("href", url.Action(action, routeValues));
anchorBuilder.AddCssClass(styleClass);
string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);


return new HtmlString(anchorHtml);
}

CSS Class

.Edit {
background: url('../images/edit.png') no-repeat right;
display: inline-block;
height: 16px;
width: 16px;
}

Create the link just pass the class name

     @Html.ActionImageLink("Edit", new { id = item.ID }, "Edit" , "Edit")

我已经将 Lucas 和“ NET MVC 帮助程序,将两个对象 htmlAttribute 合并在一起”的答案以及 controller 的名称加入到以下代码中:

//CSHTML 中的示例用法

 @Html.ActionImage("Edit",
"EditController"
new { id = MyId },
"~/Content/Images/Image.bmp",
new { width=108, height=129, alt="Edit" })

以及上面代码的扩展类:

using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;


namespace MVC.Extensions
{
public static class MvcHtmlStringExt
{
// Extension method
public static MvcHtmlString ActionImage(
this HtmlHelper html,
string action,
string controllerName,
object routeValues,
string imagePath,
object htmlAttributes)
{
//https://stackoverflow.com/questions/4896439/action-image-mvc3-razor
var url = new UrlHelper(html.ViewContext.RequestContext);


// build the <img> tag
var imgBuilder = new TagBuilder("img");
imgBuilder.MergeAttribute("src", url.Content(imagePath));


var dictAttributes = htmlAttributes.ToDictionary();


if (dictAttributes != null)
{
foreach (var attribute in dictAttributes)
{
imgBuilder.MergeAttribute(attribute.Key, attribute.Value.ToString(), true);
}
}


string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);


// build the <a> tag
var anchorBuilder = new TagBuilder("a");
anchorBuilder.MergeAttribute("href", url.Action(action, controllerName, routeValues));
anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);


return MvcHtmlString.Create(anchorHtml);
}


public static IDictionary<string, object> ToDictionary(this object data)
{
//https://stackoverflow.com/questions/6038255/asp-net-mvc-helpers-merging-two-object-htmlattributes-together


if (data == null) return null; // Or throw an ArgumentNullException if you want


BindingFlags publicAttributes = BindingFlags.Public | BindingFlags.Instance;
Dictionary<string, object> dictionary = new Dictionary<string, object>();


foreach (PropertyInfo property in
data.GetType().GetProperties(publicAttributes))
{
if (property.CanRead)
{
dictionary.Add(property.Name, property.GetValue(data, null));
}
}
return dictionary;
}
}
}

这将是非常好的工作

<a href="<%:Url.Action("Edit","Account",new {  id=item.UserId }) %>"><img src="../../Content/ThemeNew/images/edit_notes_delete11.png" alt="Edit" width="25px" height="25px" /></a>