Reputation: 1828
I was wondering what the best practice was for specifying an action on a certain controller.
Parts of the code I've been working on are specifying a url as:
<a href="/controller/action"/>
I'm generally not a big fan of this style. I've preferred to use:
<a href='@Url.Action("Action", "Controller")'/>
1) What is the best practice in forming urls for internal actions in this case? Both work, just wondering what is better.
2) Is there a benefit to using one versus the other?
Upvotes: 4
Views: 1289
Reputation: 656
I created a static class to store all the controller types in my BaseController and I use nameof() for the action to ensure no silent errors from typos or action name changes.
public static class CONTROLLERS
{
public const string
Cat = nameof(Cat),
Dog = nameof(Dog),
Mouse = nameof(Mouse);
}
So my links would look like this:
<a href="@Url.Action(nameof(CatController.Index), CONTROLLERS.Cat)"></a>
Upvotes: 0
Reputation: 239390
@hutchonoid sort of touched on this, but virtual paths are just one part of the benefit. While the default route pattern is controller/action/id?
, it doesn't have to be that way. Especially if you're using attribute routing in MVC5+, the URL could be literally anything, and may not even include the controller or action name.
By handling all your links using Url.Action
or Html.ActionLink
, you abstract the view's knowledge of the URL, which is a very good thing. True separation of concerns, which is fundamental to MVC, requires pieces to be as "dumb" as possible, only knowing or caring about the things that it needs to.
If you do end up using attribute routing, I would go a step further and actually recommend naming all your routes, and then using Url.RouteUrl
/Html.RouteLink
instead of the action-centric versions. This provides even greater abstraction, as you could then have a completely different action or even controller handle that named route, without changing any of your views. You could also technically do this with standard routing, but naming routes with standard routing would require you to manually define each route, instead of relying on a default route or set of default routes.
Upvotes: 2
Reputation: 54638
You can also create StronlyTyped ActionLinks if you really wanted too.
@(Html.ActionLink<CustomersController>(x => x.Index(), "Customers"))
Upvotes: 3
Reputation: 33306
Of the two options I would say the second is the better approach as it will work with virtual paths/directories:
<a href='@Url.Action("Action", "Controller")'/>
I prefer to use ActionLinks though:
@Html.ActionLink("text", "action", "controller")
Upvotes: 4