I am trying to add a css class to a #html.actionlink and do not want to use the text that does in the link. I want to use a graphic instead.
Here is my code:
#Html.ActionLink("Edit", "PopupReferenceEdit", new { id = item.VolunteerReferenceID }, new { #class = "Grid-editor" })
When I delete the"Edit" I get an error. Is it possible to use this statement and have an icon/image for the link?
Thanks for answers to this newbie question.
Andy
i think that a more nicer approach for this would be to create an extension method for it with these overloads in your helper folder and then use it in your views. just depends upon the personal preference
public static class ImageActionLinkHelper
{
public static string ImageActionLink(this HtmlHelper helper, string ImageUrl, string altText, string actionName, object routeValues)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", ImageUrl);
builder.MergeAttribute("alt", altText);
builder.MergeAttribute("title", altText);
var link = helper.ActionLink("[replaceme]", actionName, routeValues, new { #class = "imgicon" });
return link.ToString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing));
}
public static string ImageActionLink(this HtmlHelper helper, string ImageUrl, string altText, string actionName, object routeValues, string Id, string display)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", ImageUrl);
builder.MergeAttribute("alt", altText);
builder.MergeAttribute("title", altText);
var link = helper.ActionLink("[replaceme]", actionName, routeValues, new { #class = "imgicon", id = Id, style = display });
return link.ToString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing));
}
using it
#Html.ImageActionLink("../../Content/images/edit.png", "Edit", "Edit", new { id = item.UserId})
Related
I'm using an extension method to maintain a css class on active links on the menu.
However I've got an issue where the htmlAttributes and the object values are causing errors.
I have the below in my Razor page but I don't understand how I'm meant to be parsing the htmlAttributes.
#Html.MenuLink("Summary", "Summary", "Graphs", null, new { #class = "dropdown-toggle caret", data_target = "#", data_toggle = "dropdown" })
From looking at the HtmlHelper the method should have IDictionary<object, string> as the type for the htmlAttributes. The new { #class = "dropdown-toggle caret", data_target = "#", data_toggle = "dropdown" } syntax isn't typical for dictionaries so is this correct?
Obviously I'm doing something wrong as it's returning the below error:
Argument 6: cannot convert from '<anonymous type: string class, string data_target, string data_toggle>' to 'System.Collections.Generic.IDictionary<object, string>'
Extension method I'm trying to get working below:
public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string text, string action, string controller, RouteValueDictionary routeValues, IDictionary<object, string> htmlAttributes)
{
var routeData = htmlHelper.ViewContext.RouteData.Values;
var currentController = routeData["controller"];
var currentAction = routeData["action"];
if (string.Equals(action, currentAction as string, StringComparison.OrdinalIgnoreCase) &&
string.Equals(controller, currentController as string, StringComparison.OrdinalIgnoreCase))
{
return htmlHelper.ActionLink(text, action, controller, null, new { #class = "currentMenu" });
}
return htmlHelper.ActionLink(text, action, controller);
}
Change the parameter from IDictionary<object, string> htmlAttributes to object htmlAttributes since your passing the attributes as an object.
You can then convert the object using
var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
However, no where in your extension method do you ever use the attributes. All your generating is class = "currentMenu" depending on the current controller and action names. If you intention is to add the attributes plus the class name (depending on the condition), you can then use
attributes.Add("class", "currentMenu");
Your complete method to allow defining both route values and html attributes, and to conditionally include the "currentMenu" class name should be
public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string text, string action, string controller, object routeValues, object htmlAttributes)
{
var routeData = htmlHelper.ViewContext.RouteData.Values;
string currentController = (string)routeData["controller"];
string currentAction = (string)routeData["action"];
if (string.Equals(action, currentAction, StringComparison.OrdinalIgnoreCase) && string.Equals(controller, currentController, StringComparison.OrdinalIgnoreCase))
{
if (htmlAttributes == null)
{
return htmlHelper.ActionLink(text, action, controller, routeValues, new { #class = "currentMenu" });
}
else
{
// convert object to RouteValueDictionary
var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (attributes.ContainsKey("class"))
{
// append the class name
attributes["class"] = string.Format("{0} currentMenu", attributes["class"]);
}
else
{
// add the class name
attributes.Add("class", "currentMenu");
}
return htmlHelper.ActionLink(text, action, controller, new RouteValueDictionary(routeValues), attributes);
}
}
return htmlHelper.ActionLink(text, action, controller, routeValues, htmlAttributes);
}
Side note: You should also consider including other overloads to accept RouteValueDictionary routeValues and IDictionary<String, Object>) htmlAttributes as per the in-built ActionLink() methods and you can inspect the source code to see how the various overloads fall through to the other overloads.
I am trying to understand how I can add an extra parameter to URL.Action, and have it as part of the resultant link.
Lets assume the following:
myParm = "myTestParameterValue";
#Url.Action("Edit", "Order", new { id=item.Id}, null,myParm)
which would result in:
/Order/Edit/1/myTestParameterValue
I would really appreciate some sample code of the extension method for this Action Sample to see how the parameters are taken in and how the link is generated.
I guess it would start something like:
public static MvcHtmlString Action(this HtmlHelper helper, string actionName, string controllerName, object routeValues, boolean IsHashRequired)
If (IsHashRequired)
{
String myHash = GetHash();
}
// Pseudocode .... string myNewLink = ... + myHash
Many thanks in advance
EDIT
I need to calculate hash to add to resultant link. A better parameter would be a boolean. I have edited code accordingly.
EDIT2:
public static IHtmlString Action(this UrlHelper urlHelper, string actionName, string controllerName, object routeValues, string protocol, bool isHashRequired )
{
if (isHashRequired)
{
routeValues["hash"] = "dskjdfhdksjhgkdj"; //Sample value.
}
return urlHelper.Action(???); // Resultant URL = /Order/Edit/1/dskjdfhdksjhgkdj
}
EDIT3:
Struggling with :
return urlHelper.Action(actionName, controllerName, routeValues, protocol);
Apparently needs converting to IHtmlString??
EDIT4:
public static String Action(this UrlHelper urlHelper, string actionName, string controllerName, object routeValues, string protocol, bool isHashRequired )
{
RouteValueDictionary rvd = new RouteValueDictionary(routeValues);
if (isHashRequired)
{
string token = "FDSKGLJDS";
rvd.Add("urltoken", token);
}
return urlHelper.Action(actionName, controllerName, rvd, protocol); //rvd is incorrect I believe
}
EDIT5
return urlHelper.Action(actionName, controllerName, rvd, protocol,null);
where
rvd is the RouteValueDictionary
hostname is null.
Thanks...
You should consider modifying your routes
Where you have your routing configured add something like this:
routes.MapRoute(
"hash", // Route name
"{controller}/{action}/{id}/{hash}", // URL with parameters
new { controller = "Home", action = "Index", id = "", hash = "" } // Parameter defaults
);
And use URL.Action like this:
myParm = "myTestParameterValue";
#Url.Action("Edit", "Order", new { id=item.Id, hash = myParm}, null);
You can easily add this with a new extension method class
public static class MyExtensions
{
public static IHtmlString ActionWithHash(this UrlHelper urlHelper, ....)
{
if (hashRequired)
{
routeParameters["hash"] = ...
}
return urlHelper.Action(...);
}
}
I'm using MVC3 with Razor.
I have the following helper:
public static class ImageActionLinkHelper
{
public static string ImageActionLink(this AjaxHelper helper, string imageUrl, string actionName, object routeValues, AjaxOptions ajaxOptions)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("src", imageUrl);
builder.MergeAttribute("alt", "");
var link = helper.ActionLink(builder.ToString(TagRenderMode.SelfClosing), actionName, routeValues, ajaxOptions);
return link.ToHtmlString();
}
}
and in my view I have:
#Ajax.ImageActionLink("../../Content/Images/button_add.png", "JobTasksNew", "TrackMyJob",new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "tmjDynamic" }))
and this is what i get when the page gets rendered
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#tmjDynamic" href="/TrackMyJob/JobTasksNew?Length=10">&lt;img alt=&quot;&quot; src=&quot;../../Content/Images/button_add.png&quot;&gt;&lt;/img&gt;</a>
Microsoft has an example with ajax.actionlink.Replace but I don't have this method.
Can you help me get the correct html string?
Thank you in advance.
Please try this:
public static class ImageActionLinkHelper {
public static MvcHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, string actionName, object routeValues, AjaxOptions ajaxOptions) {
var builder = new TagBuilder("img");
builder.MergeAttribute("src", imageUrl);
builder.MergeAttribute("alt", "");
var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions);
var html = link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing));
return new MvcHtmlString(html);
}
}
To get the URL's I wanted i created a simple Link Creator helper for my search results.
But it wont let me use server urlencode in it and some of the details passed are French/Czech/Swedish words commas and apostrophes;
Is there a quick function that will strip all this garbage out before hand?
Create custom HTML helper for this. Generate HTML markup using TagBuilder and use UrlEncode where you want. For example:
public static string SearchActionLink(this HtmlHelper html, string linkText, string actionName, object routeValues)
{
var innerHtml = html.ViewContext.HttpContext.Server.UrlEncode("....");
TagBuilder tagBuilder = new TagBuilder("a") {
InnerHtml = innerHtml;
};
var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
var url = urlHelper.Action(actionName, routeValues);
tagBuilder.MergeAttribute("href", url);
return tagBuilder.ToString(TagRenderMode.Normal);
}
UPDATED:
Something like this?:
public static string SearchActionLink(this HtmlHelper html, string linkText, System.Web.Routing.RouteValueDictionary routeValues)
{
var ref = html.ViewContext.HttpContext.Server.UrlEncode(routeValues["ref"]);
routeValues["ref"] = "_REF_";
TagBuilder tagBuilder = new TagBuilder("a") { InnerHtml = linkText; };
var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
var url = urlHelper.RouteUrl(routeValues).Replace("_REF_", ref);
tagBuilder.MergeAttribute("href", url);
return tagBuilder.ToString(TagRenderMode.Normal);
}
The Html.RouteLink() HtmlHelper works great for text links. But what's the best way to link an image?
<img src="..." alt="..." />
Here is mine, it`s the core function make some overloads
public static string ImageLink(this HtmlHelper htmlHelper, string imgSrc, string alt, string actionName, string controllerName, object routeValues, object htmlAttributes, object imgHtmlAttributes)
{
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
string imgtag = htmlHelper.Image(imgSrc, alt,imgHtmlAttributes);
string url = urlHelper.Action(actionName, controllerName, routeValues);
TagBuilder imglink = new TagBuilder("a");
imglink.MergeAttribute("href", url);
imglink.InnerHtml =imgtag;
imglink.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);
return imglink.ToString();
}
This is an updated version that I have from MiniScalope answer above. I'm using VS2010 and ASP.Net MVC 2 Preview
public static string ImageLink(this HtmlHelper htmlHelper, string imgSrc, string alt, string actionName, string controllerName, object routeValues, object htmlAttributes, object imgHtmlAttributes)
{
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
TagBuilder imgTag = new TagBuilder("img");
imgTag.MergeAttribute("src", imgSrc);
imgTag.MergeAttributes((IDictionary<string, string>) imgHtmlAttributes,true);
string url = urlHelper.Action(actionName, controllerName, routeValues);
TagBuilder imglink = new TagBuilder("a");
imglink.MergeAttribute("href", url);
imglink.InnerHtml = imgTag.ToString();
imglink.MergeAttributes((IDictionary<string, string>)htmlAttributes, true);
return imglink.ToString();
}
<%= Html.ActionLink(Html.Image(imageUrl, imageAlt), actionName, controllerName) %>
could work, the image extension is from the futures assembly.
Or make your own extention.
Create your own helper extension.
public static string Image(this HtmlHelper helper, string src, string alt)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes.Add("src", helper.Encode(src));
tb.Attributes.Add("alt", helper.Encode(alt));
return tb.ToString(TagRenderMode.SelfClosing);
}
I don't have enough SO swagger to add a comment, but this is a comment on
MiniScalope's comment above:
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
I would suggest making this an HtmlHelper extension method in itself (and simplify it), for reuse:
private static UrlHelper Url(this HtmlHelper helper)
{
return new UrlHelper(helper.ViewContext.RequestContext);
}
<%= Html.RouteLink("PLACEHOLDER", ...).Replace("PLACEHOLDER", "<img src=""..."" alt=""..."" />")%>
this code has been tested on mvc4...
public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string imgSrc, string alt, string actionName, string controllerName, object routeValues, object htmlAttributes, object imgHtmlAttributes)
{
UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url;
var imgTag = new TagBuilder("img");
imgTag.MergeAttribute("src", imgSrc);
imgTag.MergeAttributes((IDictionary<string, string>)imgHtmlAttributes, true);
string url = urlHelper.Action(actionName, controllerName, routeValues);
var imglink = new TagBuilder("a");
imglink.MergeAttribute("href", url);
imglink.InnerHtml = imgTag.ToString();
imglink.MergeAttributes((IDictionary<string, string>)htmlAttributes, true);
return MvcHtmlString.Create(imglink.ToString());
}