I want to be able to put a class on an a tag dependant on the current route, can this be done?
I haven't used ActionLinks at the moment but should be able to switch to them if I need to, if possible I'd like to avoid it simply for having to change all the navigation.
For example if I have:
Home
About
etc
If navigate to /About I would want this to change to:
About
If you do not want to switch to HTML Helpers to us ActionLinks you can stick with the classic links you have and use Html.Raw to output raw html.
<a href="/" #Html.Raw("class=\"someclasshere\"")>Home</a>
The conditionally set the class like the current "active" navigation you should be looking at both the controller and the action, something like:
<a href="/" #Html.Raw(ViewContext.RouteData.Values["action"].ToString().Equals("index",StringComparison.CurrentCultureIgnoreCase) && ViewContext.RouteData.Values["controller"].ToString().Equals("home",StringComparison.CurrentCultureIgnoreCase)? "class=\"active\"": "")>Home</a>
Sure, you could do something like this:
#Html.ActionLink(
"linkText",
"actionName",
null, // routeValues
new { #class = // just build an expression here to return the class name }
You want to use ViewContext.RouteData.Values
#Html.ActionLink("About", "About",
new { #class = ViewContext.RouteData.Values["action"] })
This should add the name of the current action as the link's CSS class.
Or, without HtmlHelpers:
<a href="/About" class="#(ViewContext.RouteData.Values["action"])">
About
</a>
Related
I have a scenario, where I have to redirect using hyper link in MVC and there I have to add action name, controller name & object name. When I try to enter the object name, It is not finding that object name. How to get the object name in Url.Action?
My Url in UI has to look like this: localhost:00/area/Controller/ActionMethod/ItemId.
Here I need help how to add the Itemid in Url.Action.
#Url.Action is used inside <a> tag.
<a href="#Url.Action("ActionMethod", "Controller", new { itemId = ItemId })" >LinkName</a>
I was wondering if is it OK to put the controller name as a string, like in the following example.
Also, should I put the action as a string instead?
Is there any better approach?
My concert is that if I change the controller's name for any reason, my best option is to do a "find-replace" in the whole project as it is now.
Many thanks!
In general, we directly use the name of the controller and action as strings, as shown below:
(However, this wording cannot be changed automatically after you change the controller name, you need to modify manually)
<a class="nav-link text-dark" asp-controller="Operation" asp-action="Index"> </a>
1. According to your current wording, you can update the code as follows:
(This will change dynamically as you change the name of the controller)
<a class="nav-link text-dark" asp-controller="#nameof(OperationController).Replace("Controller","")" asp-action="#nameof(OperationController.Index)"> link </ a>
2. As an alternative solution, you can add the Route attribute to the action specified by the a tag and set the route name.
In the a tag, you only need to use asp-route to link the corresponding action.
Please refer to this.
<a class="nav-link text-dark" asp-route="MyRouteName"> link </a>
Controller:
public class OperationController: Controller
{
[Route ("CustomControllerName/Index", Name="MyRouteName")]
public IActionResult Index ()
{
return View ();
}
}
Yes, that is exactly how you use the anchor tag helpers. At least to me that asp-action seems convoluted and I would simply have written it as:
<a asp-controller="Operation" asp-action="Index">...</a>
If you do change your controller name (which should not happen very often), then you would have to update the links.
For further reference see https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/anchor-tag-helper?view=aspnetcore-3.1: "If the asp-controller attribute is specified and asp-action isn't, the default asp-action value is the controller action associated with the currently executing view. [...] If the asp-action attribute value is Index, then no action is appended to the URL, leading to the invocation of the default Index action. The action specified (or defaulted), must exist in the controller referenced in asp-controller."
I have an MVC project that lives on server in /root/folder1/, and a domain name pointing there.
So the url, www.site.com/Home is working fine.
However, all my #Html.ActionLinks and #Url.Action, etc. are rendering as www.site.com/folder1/Home
The links still work, but it is ugly, and I don't want the folder name to be known.
Anyone know why it's doing this and how to stop it?
You should be using something like this for your ActionLinks
#Html.ActionLink("Link Text", "ActionName", "ControllerName") 'NOTE YOU DO NOT NEED TO INCLUDE THE Controller part of the controller name. So for say AdminController you could simply set the controllerName in the ActionLink to `Admin`
You can also setup your ActionLinks like the below if you have to pass an Id or other value to the controller.
#Html.ActionLink("Link Text", "ActionName", "ControllerName", New With {.YourVariableName = "SomeValue"})
If you need to specify and HTML attribute for the control being rendered you can set those with one more overload.
#Html.ActionLink("Link Text", "ActionName", "ControllerName", New With {.YourVariableName = "SomeValue"}, New With {.htmlAttributeName = ""})
If you need to Specify the HTML attribute without a need to pass a value to the controller you can simply replace New With{.YourVariableName = "SomeValue"}withNothing`
Hope this works or at least points you in the right direction. A fresh MVC project out of the box has a Controllers folder. Which means server path looks something like root/controllerFolder/controller/action using the above works fine for me and only produces Url's that follow the standard {controller}/{action}/{id}. Say I have a need to call an Edit Action inside the AdminController which needs an ID so it knows what record I want to edit and I also want to add a class to this button so I can style it or anything else. I would do this
#Html.ActionLink("Edit", "Edit", "Admin", NEW WITH {.ID = #currItem.Id}, NEW WITH{.Class = "MyButtonClass"})
The URL that is generated will look like this
www.mysite.com/Admin/Edit/2
maybe this is a little more than you needed but your question appears to actually follow the standard {controller}/{action}/{id}. Just in-case I am missing something I figured I would try to at least point you in the right direction.
Given the following string:
/MyController/MyAction/4
How do I generate a link within another controller's action to link to the appropriate address?
If I do the following:
#Html.ActionLink("click", Url.Action(item.Link))
// where item.Link is where /MyController/MyAction/4 is stored
I get a link that resembles:
www.localhost.com/CurrentController/CurrentController/MyController/MyAction/4
I need to not have the "CurrentController" part (yes, there are two of them - I think that is because I am doing a #Html.ActionLink and an Url.Action).
How would I get my appropriate link?
If you already have the /MyController/MyAction/4 path you need stored in item.Link, could you just build the <a> tag yourself?
Link Text
Use the RouteUrl() method to achieve what you want. For more information, you can check this page as well.
I think what you are wanting is to link to another controller and action?
You need to do this;
#Html.ActionLink("Click", "ActionName", new {Controller = "ControllerName"})
Then you can add some HtmlAttributes onto that to;
#Html.ActionLink("Click", "ActionName", new {Controller = "ControllerName"}, new { #class= "className" })
Edit
If you are passing this string value in, then why not just use;
Click
So I have a masterpage that has an image whos source is a controller action returning a filestream.
The image will be different for each logged in user.
right now in my masterpage view i have this code wich relies on viewdata.
<img id="dealerlogo" src='/Files/DealerImage/GetDealerLogo/<%=Html.Encode(ViewData["dealerid"]) %>' alt="" />
obviously the problem with this is that I will need to provide the viewdata containing the ID
on everycontroller action returning a view that uses this master page, which is pretty much all of them.
Is there a better way to do this? Like is there a way to get the username right in the view?
Thanks!
You can easily encapsulate this logic in a [ChildActionOnly] Action that returns a partial view and then use new MVC 2 approach
<% Html.RenderAction("GetUserPhoto", "User"); %>
to have it everywhere in your view pages without passing ViewData in all actions.
Here's the solution:
[ChildActionOnly]
public ActionResult GetUserPhoto()
{
ViewData["UserId"] = Page.User.Identity;
return PartialView();
}
And in your view you use the same logic you used to show user image. Also you can directly send a FileResult to partial view to render image for you. In this approach you don't need to repeat ViewData["XXXX"] in all views and you need just to Render the new Partial View in your main Views.
You can use the Page.User.Identity.Name just like in the default logonusercontrol.aspx that is created for you when you create a new asp.net MVC site.
Welcome <b><%= Html.Encode(Page.User.Identity.Name ) %></b>
So for you, you would want something like this:
<img id="dealerlogo" src='/Files/DealerImage/GetDealerLogo/<%=Html.Encode(Page.User.Identity.Name) %>' alt="" />
I assume your GetDealerLogo action method has a parameter of dealerid. It's better to write something like:
<img src="<%= Url.Action("GetDealerLogo", "DealerImage", new { dealerid = ViewData["dealerid"] }) %>" />
Nothing wrong with passing it in via ViewData. You might also consider a strongly-typed View or your own ViewPage base class which exposes a DealerId property.
To make it even cleaner, I really like T4MVC. It would allow you to write:
<img src="<%= Url.Action(MVC.DealerImage.GetDealerLogo(dealerid)) %>" />
And, even further, you might create an Html helper, so you can write:
<%= Html.DealerLogo(dealerid) %>