Can I add a class to an HTML.ActionLink in MVC3 - asp.net-mvc

I have this code and would like to add a class to the link. Is it possible to do this in MVC3?
Html.ActionLink("Create New", "Create")

Yes, you can just add another parameter with object representing css class:
Html.ActionLink("Create New", "Create", CONTROLLERNAME, null, new { #class= "yourCSSclass"} )
It can be translated to:
Html.ActionLink(link text, action name, controller name, route values object, html attributes object)
Edit:
To add custom styles, use this:
Html.ActionLink(
"Create New",
"Create",
CONTROLLERNAME,
null,
new { #class= "yourCSSclass", #style= "width:100px; color: red;" }
)

#Html.ActionLink("ClickMe", // link text
"Index", // action name
"Home", // controller
new { id = 2131 }, // (optional) route values
new { #class = "someClass" }) // html attributes

Html.ActionLink("Create New", "Create", null, htmlAttributes: new { #class = "className" })

You can use the ActionLink overload which takes an htmlAttributes parameter to add a class to the generated element:
Html.ActionLink("Create New", "Create", new {}, new { #class = cssClass });

According to the documentation, this should do the trick:
Html.ActionLink("LinkText", "Action", "Controller", new { }, new {#class="css class"})
Edit: Thanks for noticing Dampe, I updated the code sample.

Related

Wrong parameter in Query ActionLink MVC [duplicate]

I'm VERY confused as to why this code
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })
results in this link:
<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>
The hidefocus part is what I was aiming to achieve, but where does the ?Length=4 come from?
The Length=4 is coming from an attempt to serialize a string object. Your code is running this ActionLink method:
public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)
This takes a string object "Home" for routeValues, which the MVC plumbing searches for public properties turning them into route values. In the case of a string object, the only public property is Length, and since there will be no routes defined with a Length parameter it appends the property name and value as a query string parameter. You'll probably find if you run this from a page not on HomeController it will throw an error about a missing About action method. Try using the following:
Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })
The way I solved this is was adding a null to the fourth parameter before the anonymous declaration (new {}) so that it uses the following method overload: (linkText, actionName, controllerName, routeValues, htmlAttributes):
Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })
You forgot to add the HTMLAttributes parm.
This will work without any changes:
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)
The parameters to ActionLink are not correct, it's attempting to use the "Home" value as a route value, instead of the anonymous type.
I believe you just need to add new { } or null as the last parameter.
EDIT: Just re-read the post and realized you'll likely want to specify null as the second last parameter, not the last.
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })
This will take the overload:
string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes
Just remove "Home" (name of the controller) so that the code would be:
Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })
Kindly use right overloaded method with five (5) parameters. Example:
#using (#Ajax.BeginForm("Register", "Account", null,
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnSuccess",
OnFailure = "OnFailure",
OnBegin = "OnBegin",
OnComplete = "OnComplete"
}, new { #class = "form-login" }))
This worked fine
#Html.ActionLink("Informationen", "About", "Home", new { area = "" }, new { #class = "nav-link" })
added new { area = "" }.
As Jonathon Watney pointed out in a comment, this also goes for
Html.BeginForm()
methods. In my case, I was in a Create.cshtml targeting the post request of the corresponding controller + Create action and had
using (Html.BeginForm("Create")) {
#Html.AntiForgeryToken()
...
}
which was adding the querystring "?Length=6" to the form action when rendered. Hinted by roryf's approved answer and realizing the string length of "Create" is 6, I finally solved this by removing the explicit action specification:
using (Html.BeginForm()) {
#Html.AntiForgeryToken()
...
}
With attribute names:
#Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)
Perhaps others had the same issue and need to supply a class value via HTMLAttributes parm.
Here's my solution:
#Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", #class = "nav-item nav-link" })
Search for an answer to my question landed me here, basically it's the selection of correct overload of #Html.ActionLink
which matters.
I was selecting an overload which didn't exist, (without the last null), and MVC had no such overload, resulting in a false URL something like the OP mentioned.
A personal note: you can use anonymous types doesn't mean you can use any of the overloads- which do not exist? - make certain: it has to be defined!
- Came here in times of MVC 5.2

ViewModel not storing values when Ajax.ActionLink calling controller

When I'm clicking ActionLink and setting ViewModel values in controller I can see changes when View being rendered. But same values comes as null into Controller when I'm clicking ActionLink second time.
How do I store the value, so it comes into controller ?
View:
#Ajax.ActionLink("Click me", "AjaxTest", "Controller", new AjaxOptions()
{
UpdateTargetId = "updatePanel",
HttpMethod = "POST",
OnSuccess = "A()"
})
<div id="updatePanel">
#Html.Partial("~/Views/Shared/_UpdatableContent.cshtml", this.Model)
</div>
Controller:
[HttpPost]
public ActionResult AjaxTest(MyViewModel model)
{
model.A = "A"
return PartialView("_UpdatableContent", model);
}
Partial view _UpdatableContent:
#Html.HiddenFor(x => x.A)
#if (Model.A == "A")
{
//Draw
}
Try adding this.Model to your ActionLink following:
#Ajax.ActionLink("Click me", "AjaxTest", "Controller", this.Model, new AjaxOptions() { UpdateTargetId = "updatePanel" })
This method passes the model back into the request, which should allow the update to happen.
Probably my biggest gripe with ASP.NET MVC is the fact that the various "Helper" functions are overloaded to the nth-degree, and not always consistently in terms of the order the arguments appear...
Hope that helps :)
I had this very same problem. Setting HttpMethod = "Post" in the AjaxOptions fixed it for me, thanks Sergejs.
My final, working code is as follows
#{
AjaxOptions ajaxOptions = new AjaxOptions
{
HttpMethod = "Post",
LoadingElementId = "product-adding-" +#Model.Product.Id,
LoadingElementDuration = 100,
OnSuccess = "AddedToCart"
};
}
<div>
#Ajax.ActionLink("Add to cart",
"AddToCart",
"Cart",
new { id = Model.Product.Id, returnUrl = Request.Url.PathAndQuery },
ajaxOptions,
new { #class = "button" })
<img id="product-adding-#Model.Product.Id" src="~/Images/ajax_loader.gif" />
</div>

MVC Html.BeginForm using Areas

I'm using MVC areas and on a view that's in an area called "Test" I would like to have a form that posts to the following method:
area: Security
controller: AccountController
method: logon
How can I make this happen with Html.BeginForm? Can it be done?
For those of you that want to know how to get it to work with the default mvc4 template
#using (Html.BeginForm("LogOff", "Account", new { area = ""}, FormMethod.Post, new { id = "logoutForm" }))
Try this:
Html.BeginForm("logon", "Account", new {area="Security"})
Try specifying the area, controller, action as RouteValues
#using (Html.BeginForm( new { area = "security", controller = "account", action = "logon" } ))
{
...
}
Use this for area with HTML Attributes
#using (Html.BeginForm(
"Course",
"Assign",
new { area = "School" },
FormMethod.Get,
new { #class = "form_section", id = "form_course" }))
{
...
}
#using (Html.BeginForm("", "", FormMethod.Post, new { id = "logoutForm", action = "/Account/LogOff" }))
{#Html.AntiForgeryToken()
<a class="signout" href="javascript:document.getElementById('logoutForm').submit()">logout</a>
}
For Ajax BeginForm we can use this
Ajax.BeginForm("IndexSearch", "Upload", new { area = "CapacityPlan" }, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = updateTarget }, new { id = "search-form", role = "search" })

Why does Html.ActionLink render "?Length=4"

I'm VERY confused as to why this code
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })
results in this link:
<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>
The hidefocus part is what I was aiming to achieve, but where does the ?Length=4 come from?
The Length=4 is coming from an attempt to serialize a string object. Your code is running this ActionLink method:
public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)
This takes a string object "Home" for routeValues, which the MVC plumbing searches for public properties turning them into route values. In the case of a string object, the only public property is Length, and since there will be no routes defined with a Length parameter it appends the property name and value as a query string parameter. You'll probably find if you run this from a page not on HomeController it will throw an error about a missing About action method. Try using the following:
Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })
The way I solved this is was adding a null to the fourth parameter before the anonymous declaration (new {}) so that it uses the following method overload: (linkText, actionName, controllerName, routeValues, htmlAttributes):
Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })
You forgot to add the HTMLAttributes parm.
This will work without any changes:
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)
The parameters to ActionLink are not correct, it's attempting to use the "Home" value as a route value, instead of the anonymous type.
I believe you just need to add new { } or null as the last parameter.
EDIT: Just re-read the post and realized you'll likely want to specify null as the second last parameter, not the last.
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })
This will take the overload:
string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes
Just remove "Home" (name of the controller) so that the code would be:
Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })
Kindly use right overloaded method with five (5) parameters. Example:
#using (#Ajax.BeginForm("Register", "Account", null,
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnSuccess",
OnFailure = "OnFailure",
OnBegin = "OnBegin",
OnComplete = "OnComplete"
}, new { #class = "form-login" }))
This worked fine
#Html.ActionLink("Informationen", "About", "Home", new { area = "" }, new { #class = "nav-link" })
added new { area = "" }.
As Jonathon Watney pointed out in a comment, this also goes for
Html.BeginForm()
methods. In my case, I was in a Create.cshtml targeting the post request of the corresponding controller + Create action and had
using (Html.BeginForm("Create")) {
#Html.AntiForgeryToken()
...
}
which was adding the querystring "?Length=6" to the form action when rendered. Hinted by roryf's approved answer and realizing the string length of "Create" is 6, I finally solved this by removing the explicit action specification:
using (Html.BeginForm()) {
#Html.AntiForgeryToken()
...
}
With attribute names:
#Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)
Perhaps others had the same issue and need to supply a class value via HTMLAttributes parm.
Here's my solution:
#Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", #class = "nav-item nav-link" })
Search for an answer to my question landed me here, basically it's the selection of correct overload of #Html.ActionLink
which matters.
I was selecting an overload which didn't exist, (without the last null), and MVC had no such overload, resulting in a false URL something like the OP mentioned.
A personal note: you can use anonymous types doesn't mean you can use any of the overloads- which do not exist? - make certain: it has to be defined!
- Came here in times of MVC 5.2

Html.BeginForm and adding properties

How would I go about adding enctype="multipart/form-data" to a form that is generated by using <% Html.BeginForm(); %>?
As part of htmlAttributes,e.g.
Html.BeginForm(
action, controller, FormMethod.Post, new { enctype="multipart/form-data"})
Or you can pass null for action and controller to get the same default target as for BeginForm() without any parameters:
Html.BeginForm(
null, null, FormMethod.Post, new { enctype="multipart/form-data"})
You can also use the following syntax for the strongly typed version:
<% using (Html.BeginForm<SomeController>(x=> x.SomeAction(),
FormMethod.Post,
new { enctype = "multipart/form-data" }))
{ %>
I know this is old but you could create a custom extension if you needed to create that form over and over:
public static MvcForm BeginMultipartForm(this HtmlHelper htmlHelper)
{
return htmlHelper.BeginForm(null, null, FormMethod.Post,
new Dictionary<string, object>() { { "enctype", "multipart/form-data" } });
}
Usage then just becomes
<% using(Html.BeginMultipartForm()) { %>

Resources