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."
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>
Being new to ASP MVC, I met the following problem.
I have a list of "repeating" controls on my page, which are presented by the following Razor code:
#model BankBLL.Interfaces.ISecureFolder
...(some irrelevant code here)
<header><h3 >Commitee list</h3></header>
#foreach (var commitee in Model.Commitees)
{
<a href="#Url.Action("CommiteePage", "SecureFolder", commitee)">
<div class="commiteeButtonImageContainer">#commitee.Name</div>
<img src="~/Images/CommiteeButtonImage.png"/>
</a>
}
Model.Commitees here is a List of ICommitee objects, that means that I am trying to "bind" each Url.Action to a corresponding ICommitee commitee object.
However, when it comes to my controller action:
public ActionResult CommiteePage(ICommitee commitee)
{
return View("CommiteePage", commitee);
}
looks like I am making it a wrong way, because application returns "Cannot create an instance of an interface." error, that means that application is unable to retreive required commitee object when the action link is clicked.
Is there a way to bind each row "item datacontext" (ICommitee object in this case) to correspoding Url.Action?
Unfortunately could not post it earlier due to reputation regulations.
Finally resolved this issue due to good explanation at:
HTML.ActionLink method
When you try to pass an argument from Url.Action or Html.ActionLink - you have to specify explicitly the final "null" argument responsible for html arguments.
In my case the following code works correctly:
slightly changed controller action (now receives just name instead of commitee object itself)
public ActionResult CommiteePage(string commiteeName)
{
return View("CommiteePage", SecureFolder.Commitees.First(o=>o.Name == commiteeName));
}
and changed syntax for html calling this action:
#foreach (var commitee in Model.Commitees)
{
<a href="#Url.Action("CommiteePage", "SecureFolder", new { commiteeName=commitee.Name }, null)">
<div class="commiteeButtonImageContainer">#commitee.Name</div>
<img src="~/Images/CommiteeButtonImage.png"/>
</a>
}
Now view correctly passes the name of selected commitee to controller so that I can redirect to corresponding commitee view.
Thank you all for helping to resolve this issue!
The main problem is that the default model binder cannot create an instance of an interface. Try to be more specific, i.e. public ActionResult CommiteePage(ImplementedCommiteeType commitee). You can also create a CommiteeViewModel: ICommitee class in which you can transport your structures (in Controllers and Views only).
Or you can create your own model binder which knows what to implement. This is slightly more complicated.
I want to pass a parameter to the controller and this is what i did :
<c:out value="${activity.nom_etabl}"/>
The controller :
#RequestMapping(value="/getinfoEtab")
public String getInfoEtablissement(#RequestParam("nomEtab") String nometab,ModelMap model){
model.addAttribute("etabliss", actservice.FicheEtabl(nometab));
return "FicheEtablissement";
}
But the controller with this way doesn't get the parameter.
Is ${pageContext.request.contextPath}/getinfoEtab resolving into the url you are trying to reach?
If your context path is the same as in the url for the page that contains your <a href> tag then you don't need ${pageContext.request.contextPath}. You can directly use <a href="getinfoEtab?nomEtab=. But if its taking you to the controller don't even bother changing it.
Do you see a value in your link where you have <c:out value="${activity.nom_etabl}"/>? If you can see the value, then change your code to <a href="${pageContext.request.contextPath}/getinfoEtab?nomEtab=${activity.nom_etabl}">
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>
Hi; i am a Asp.net software developer. i try to learn asp.net mvc. But i face to face strange thing. My contoller method name must be the same as view name or reverse. this is strange! Look please my _Layout:
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Article", "GetAll", "Article")</li>
</ul>
</nav>
article view page need GetAll method also need GetAll.cshtml. My desire: my view page name must independent of controller class'method name. My Controller:
My solution :
i think that Asp.net mvc is strange. i dislike controller' action name name must the same as view page name? how to make it? i think that View name must independent form any name
You are correct that by default your view name must be the same as your action name. However, this is easy to change. You can just called this overload of the View method in the controller and pass in whatever view name you want:
return View("SomeViewName",articles);
It doesn't have to be the same as the name of your method. By Default MVC3 will look for a View with the same name but you can create a View with ANY name and tell MVC to return that View:
return View("MyView",articles);
I have 2 comments:
GetAll() in MVC would typically be called Index (as in articles index)
You could name your Method something and return a view with a different name,
public ActionMethod GetAll()
{
return View("Index");
}