ASP MVC url/link generation on Area produces empty - asp.net-mvc

I am using ASP MVC 5 and trying to generate a link in my view inside the "ControlPanel" Area
my view rootfolder/Areas/ControlPanel/Views/CourseCategory/Index.cshtml
#Html.ActionLink("edit", "Edit", new { id = item.Id }, new { #class = "btn btn-default btn-xs" })
#Html.ActionLink("delete", "Delete", new { id = item.Id }, new { #class = "btn btn-danger btn-xs" })
my AreaRegistration
public class ControlPanelAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "ControlPanel";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.LowercaseUrls = true;
context.MapRoute(
name: "ControlPanel.CourseCategory",
url: "controlpanel/course-categories/{id}",
defaults: new { controller = "CourseCategory", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Website.Areas.ControlPanel.Controllers" }
);
}
}
RouteConfig file
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.LowercaseUrls = true;
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "HomePage",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
}
}
my controller
namespace Website.Areas.ControlPanel.Controllers
{
public class CourseCategoryController : ControlPanelController
{
public CourseCategoryController(IUnitOfWork uow)
:base(uow)
{
}
public ActionResult Index()
{
return View(_uow.Repository<CourseCategory>().GetAllOrderByCode());
}
}
}
now the output html produces empty href
<a class="btn btn-default btn-xs" href="">edit</a>
<a class="btn btn-danger btn-xs" href="">delete</a>
what is the correct way of generating link on Html.ActionLink or Url.Action and Url.RouteUrl in this case?

It looks like you are missing the controller in your route values (I noticed you are not specifying one anywhere in your #Html.ActionLink)
#Html.ActionLink("edit", "Edit", new { controller="CourseCategory", id = item.Id }, new { #class = "btn btn-default btn-xs" })
Or - an alternative overload of the Html.ActionLink
#Html.ActionLink("edit", "Edit", "CourseCategory", new { id = item.Id }, new { #class = "btn btn-default btn-xs" })
Lastly, it never hurts to include the area name as part of the RouteValues dictionary, but this is not required.
EDIT
It looks like you updated your question with some additional information. This does not look right (having a blank value for URL)
routes.MapRoute(
name: "HomePage",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
By default, it should look something like this
routes.MapRoute(
name: "HomePage",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
I would assume having a blank URL is definitely something that could cause a blank URL to be created in an Html.ActionLink. These helpers looks at your route config to generate the URL and this one seems to be taking over probably everything since it matches everything.

Try to do this area name along with id
#Html.ActionLink("edit", "Edit", new { id = item.Id, area = "ControlPanel" }, new { #class = "btn btn-default btn-xs" })
#Html.ActionLink("delete", "Delete", new { id = item.Id, area = "ControlPanel" }, new { #class = "btn btn-danger btn-xs" })

I think the problem is with the defaults which points to the Index action and action is not bound on the route!??

Related

ASP.NET MVC 5 Actionlink ignores actionname

This:
#Html.ActionLink(linkText: Txt.Get("rsTerugNaarOverzicht"),
actionName: "Index",
controllerName: "OfferteOverzicht",
routeValues: new { is10Days = true, maand = Model.OverzichtMaand, jaar = Model.OverzichtJaar },
htmlAttributes: new { #class = "wijzigen" })
is rendered as:
<a class="wijzigen" href="/OfferteOverzicht?is10Days=True&maand=3&jaar=2021">Terug naar overzicht</a>
I was expecting this:
<a class="wijzigen" href="/OfferteOverzicht/Index?is10Days=True&maand=3&jaar=2021">Terug naar overzicht</a>
What am I doing wrong here?
Resolved it.
It was caused by an entry in the routeconfig:
routes.MapRoute(
name: "Root",
url: "{action}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I needed to remove the first one.
Now, eventhough not visible in the link, the action is called and executed.

Action link to absolute url (remove the ?) and keep the parameter

i'm trying to get an absolute url after sending a parameters from action link and I need it to be like
http://MySite/Controller/View/CityName
so I will be able to preform a search on the results page and no losing the first parameter (e.g.)
http://MySite/Controller/View/NewYork?Lecture=bobdillen
code :
#foreach (var city in #ViewBag.City)
{
#Html.ActionLink((string)#city, "LectureIn", new { #city }, null)
}
the action(LectureIn) code :
#using (Html.BeginForm("Search", "Lecture"))
{
<div class="form-group">
<div id="searchLecture" class="input-group">
#Html.TextBoxFor(m => m.SearchTerm, new { #class = "form-control", placeholder = "" })
<span class="input-group-addon">
<button type="submit"> <i class="glyphicon glyphicon-search"></i></button>
</span>
</div>
</div>
}
and in the controller :
public ActionResult LectureIn(string search = null)
{
// Do Staf
return View();
}
I have tried to change the routes but it didn't change
routes.MapRoute(
"lectureIn",
"{controller}/{action}/{id}",
new { controller = "TMaps", action = "lectureIn", City = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

ASP.NET MVC Search Results Page MapRoute Doesn't Work

How can i set mapRoute for search results page? My code doesn't work.
Global.asax.cs
routes.MapRoute(
name: "SearchResults",
url: "{action}/{Keyword}",
defaults: new { controller = "Home", action = "Search" }
);
Search Form
#using (Html.BeginForm("Search", "Home", FormMethod.Get))
{
#Html.TextBox("Keyword",null , new { #class = "SearchBox" })
<input type="submit" value="Search" />
}
HomeController.cs
public ActionResult Search(string Keyword)
{
GamesContext db = new GamesContext();
var SearchResults= (from i in db.Games where i.GameName.Contains(Keyword) || i.GameDesc.Contains(Keyword) select i).Take(20).ToList();
return View(SearchResults.AsEnumerable());
}
This one works for me (should be before default route):
routes.MapRoute(
"SearchResults",
"Search/{Keyword}",
new { controller = "Search", action = "SearchAction" }
);
Creating an ActionLink and MapRoute that there is a constant name in it
And there's a point to use new controller for search instead of home with this route.

MVC Area - How to Link to Root folder in BeginForm

I need to define a link to LogOff controller which is in my Root shared folder; within BeginForm tag.
#using Microsoft.AspNet.Identity
#if (Request.IsAuthenticated) {
using (Html.BeginForm("", "", FormMethod.Post, new { id = "logoutForm", action = "Account/LogOff"}))
{
#Html.AntiForgeryToken()
#Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
#: | Log off
}
}
else {
#Html.ActionLink("Register", "Register", "Account")
#: |
#Html.ActionLink("Login", "Login", "Account")
}
Above works fine if I'm in root folder. But if clicked from Areas, it gives me The resource cannot be found error.
Requested URL: /MyApp/Area/Account/LogOff
The correct link should be /MyApp/Account/LogOff
I saw examples using #HTML.ActionLink but would prefer to keep define it in BeginForm, so the URL is not revealed to user.
I solved the problem with the following code.
First I mapped a route as follows
//Route config for logging off from areas.
routes.MapRoute(
name: "LogOff",
url: "Account/LogOff/",
defaults: new { controller = "Account", action = "LogOff" }
);
Then calling the route to logout, I used the following
#using (Html.BeginRouteForm("LogOff", FormMethod.Post, new { id = "logoutForm" })) {
#Html.AntiForgeryToken()
Log off
}
It may be easier to just add the Area routevalue to the BeginForm parameters. Leave it blank to point it to the root area, like this: new { Area = "" }
using (Html.BeginForm("LogOff", "Account", new { Area = "" }, FormMethod.Post, new { id = "logoutForm", #class = "navbar-right" }))
{
#Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>Log off</li>
</ul>
}
This is using MVC 5

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" })

Resources