액션 이미지 MVC3 Razor


119

MVC3에서 Razor를 사용하여 링크를 이미지로 바꾸는 가장 좋은 방법은 무엇입니까? 나는 단순히 지금 이것을하고 있습니다.

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

더 좋은 방법이 있습니까?


15
직접 관련이 없지만 BMP 파일 대신 PNG 또는 JPG 파일 (이미지 내용에 따라 다름)을 사용하는 것이 좋습니다. @jgauffin이 제안한 것처럼 응용 프로그램 상대 경로 ( ~/Content)도 사용하십시오. 경로는 ../../Content다른 경로에서 유효하지 않을 수 있습니다 (예를 들어 /, /Home, /Home/Index).
Lucas

고마워 루카스. 나는 png를 사용하지만 URL 사용에 대한 조언은 내가 찾고 있던 것입니다. 투표 :)
davy

답변:


217

HtmlHelper에 대한 확장 메서드를 만들어 CSHTML 파일의 코드를 단순화 할 수 있습니다. 다음과 같은 방법으로 태그를 바꿀 수 있습니다.

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

위 코드의 샘플 확장 메서드는 다음과 같습니다.

// 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);
}

5
훌륭한 스 니펫. T4MVC와 함께 이것을 사용하고 싶은 사람은 단지 타입을 routeValuesto 로 변경 ActionResult하고 url.Action함수에서 변경 routeValues하면됩니다routeValues.GetRouteValueDictionary()
JConstantine

12
@Kasper Skov : 메서드를 정적 클래스에 배치 한 다음 /configuration/system.web/pages/namespaces요소 의 Web.config에서 해당 클래스의 네임 스페이스를 참조합니다 .
Umar Farooq Khawaja 2011 년

4
니스! 대신 alt, 나는 그 익명의 객체를 사용하여 HTML 속성을 수신 할 객체 동의를 var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);마지막으로foreach (var attr in attributes){ imgBuilder.MergeAttribute(attr.Key, attr.Value.ToString());}
guzart

7
Areas를 사용하고 있기 때문에 클래스 네임 스페이스에 대한 참조 (Umar가 지적한대로)를 모든 Areas뿐만 아니라 Views 폴더의 모든 web.config 파일에 추가해야한다는 것을 깨달을 때까지이 작업을 수행 할 수 없었습니다. 최상위 수준 /Views폴더
Mark_Gibson

2
Web.config 파일을 변경하는 대신 단일 페이지에서만 필요한 경우 .cshtml에 @using 문을 추가하고 네임 스페이스를 참조 할 수 있습니다
JML

64

Url.Content물결표 ~를 루트 URI로 변환하므로 모든 링크에 대해 작동 하는 것을 사용할 수 있습니다 .

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

3
이것은 MVC3에서 잘 작동합니다. 감사합니다! <a href="@Url.Action("Index","Home")"><img src="@Url.Content("~/Content/images/myimage.gif")" alt="Home" /></a>
rk1962

24

위의 Lucas의 답변을 바탕으로 이것은 ActionLink와 유사하게 컨트롤러 이름을 매개 변수로 사용하는 과부하입니다. 이미지가 다른 컨트롤러의 작업에 연결될 때이 오버로드를 사용합니다.

// 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);
}

1
여기에 추가에 대한 의견이 없습니다 ... 음 나는 주어진 코드에 대한 좋은 수정을 말합니다. 나에게서 +1.
Zack Jannsen 2013 년

11

글쎄, 당신은 @Lucas 솔루션을 사용할 수 있지만 다른 방법도 있습니다.

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

이제 CSS 파일이나 페이지에이 클래스를 추가합니다.

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

해당 클래스를 사용하면 모든 링크에 원하는 이미지가 있습니다.


2
@KasperSkov 나는이 작은 문제를 잊었다. 어떤 이유로 actionLink 도우미의이 특정 재정의는 위의 예제에서 작동하지 않습니다. 당신은 ControllerName당신의 행동을해야합니다. : 이것처럼@Html.ActionLink("Update", "Update", "*Your Controller*",*object values*, new {@class = "imgLink"})
AdrianoRR

3

이것은 매우 유용한 스레드로 판명되었습니다.

중괄호에 알레르기가있는 사람들을 위해 다음은 Lucas '와 Crake의 답변의 VB.NET 버전입니다.

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

1

이 확장 메서드도 작동합니다 (공용 정적 클래스에 배치됨).

    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)) );
    }

1

Luke가 시작한 모든 Awesome 작업에 추가하기 위해 css 클래스 값을 사용하고 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);
    }

또한 MVC를 처음 접하는 사람에게 유용한 힌트-routeValue의 값은 @ RouteTable.Routes [ "Home"] 또는 RouteTable에있는 "route"ID가 무엇이든 상관 없습니다.
Zack Jannsen 2013 년

1

슬라이드 수정 변경 도우미

     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 클래스

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

링크 만들기는 클래스 이름 만 전달합니다.

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

0

나는 Lucas와 " ASP.NET MVC Helpers, Merging two object htmlAttributes together " 의 답변 과 다음 코드에 controllerName을 추가했습니다.

// 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)
        {
            ///programming/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)
        {
            ///programming/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;
        }
    }
}

0

이것은 매우 잘 작동합니다.

<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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.