ActionLink ignoring attribute routing settings - asp.net

I have a TextObject controller, which is meant to be accessed by "~/umt/text/{action}/{id?}", as defined in the controller using attribute routing, but the action link:
#Html.ActionLink("Index", "Index", "TextObject")
ignores Attribute Routing and uses the Conventional routing definitions, producing ~/TextObject/ instead of the desired ~/umt/text/
the TextObjectController:
[Authorize]
[RouteArea("umt")]
[RoutePrefix("text")]
[Route("{action=index}/{id?}")]
public class TextObjectController : Controller
{
.....
public async Task<ActionResult> Index()
{
return View(await db.TextObjects.ToListAsync());
}
.....
}
My route config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Enable Attribute Routing
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Is there any additional configuration required on the controller to make the action link work or does it not work with attribute routing?
I'd like to keep it simple, and it routes correctly going directly through the url, but the ActionLink helper seems to not like something about it.

I can't see that you specify your defauld area it RouteConfig so your action link should look like:
#Html.ActionLink("TextObject", "Index", "Index", new { area = "umt" }, null)

Related

How to redirect page from default route to custom one in MVC application?

I would like to know whether there is a way to redirect page from "~/ControllerName/Index" to custom route like "~/example-custom" without using 301 redirect in URL rewrite module.
I have used routing attribute:
[Route("example-custom")]
public ActionResult Index()
{
return View();
}
But with this routing attribute "~/ControllerName/Index" is no more. When users go to "~/ControllerName/Index", page does not exist on that route. I would like redirect users to "~/example-custom" when they want to access page.
So, what I would like in shorter terms is to browser display link "something.com/example-custom" and not "something.com/ControllerName/Index". But also accessing "something.com/ControllerName/Index" would redirect automatically to "something.com/example-custom".
Add custom route into RouteConfig.cs File
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "example-custom",
url: "{example-custom}/{id}",
defaults: new { controller = "YourControllerName", action = "YourActionName", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Alternative to MapPageRoute using the MVC pattern

I want access to some pages of my website with "web.com/software" or "web.com/about", but I'm using the MVC pattern and the MapPageRoute method (inside RouteConfig.cs) only works with pages without controllers.
If Home is my controller and Software the view, I want access with "web.com/software" instead of "web.com/Home/Software".
Is it possible with ASP.NET or I need use rewrites in Web.config (IIS) and .htaccess (Apache)?
namespace MyWebsite
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("SoftwarePage",
"software", // web.com/software
"~/Views/Home/Software");
//routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}

Routing to an aspx page on a project with webforms and MVC

I've added MVC to an existing webforms project that I've been working on as I'm looking to slowly migrate the project, however, during the change over period I need to be able to access both, but have it default to the aspx pages.
When it comes to registering the routing, I currently have this in place:
private void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapPageRoute("Backup", "{*anything}", "~/Default.aspx");
routes.MapRoute(
"MVC",
"{controller}/{action}/{id}",
new { controller = "Test", action = "Index", id = 1 }
);
}
However, when I have it setup like this, even if I put in a URL that I know refers to a controller/action combination (e.g. Test and Index from the last line of this), it still redirects the user to the Default.aspx page.
I've tried changing this over to the following:
private void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"MVC",
"{controller}/{action}/{id}",
new { controller = "Test", action = "Index", id = 1 }
);
routes.MapPageRoute("Backup", "{*anything}", "~/Default.aspx");
}
Here, the user can specify a page or specify a controller/action, but if they do not include any controller/aspx page, it defaults to the default MVC route, whereas I need it to default to the webform Default.aspx.
How would I get around the situation so that if no page/controller is specified, it directs to ~/Default.aspx, and if a controller is specified, it directs to that controller?
I tried experimenting with your scenario where in i have an existing web forms application and have added mvc to it. Basically i have come across two solutions.
First: you can ignore adding routes.MapPageRoute to route config; this is what i have done
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.EnableFriendlyUrls();
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
}
Please notice that i have excluded value for controller in the defaults. Now even if there is a match and if there is not controller present by that name then the request will fall back to the regular ASP.Net pipeline looking for an aspx page. With this approach you could request urls like http://localhost:62871/ or http://localhost:62871/Home/Index or http://localhost:62871/Home/ or http://localhost:62871/About.aspx
Second:: In this approach you can create an area under Areas folder for your new MVC based work and leave the RouteConfig in App_Start to its default so that it looks like following.
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.EnableFriendlyUrls();
}
}
And then in your Area registration class define route as in following example .
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Hope that helps. Thanks.

static routing returning 404?

I'm trying to create a static route as follows:
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Hire",
url: "Hire/{gender}",
defaults: new { controller = "Hire", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
however, when I try access /Hire/Female, for instance, IIS throws a 404 error, as I was reading about routing I noticed routes are usually written as {controller}/{action}/{something}, is it mandatory to have {controller} and {action} on my route?
here's the code for the controller:
public class HireController : Controller
{
[HttpGet]
public ActionResult Index(string gender)
{
return View();
}
}
and I have a file named /Views/Hire/Index.cshtml
what I was trying to achieve is to route requests from /Hire/Male and /Hire/Female to the Index action of my HireController but I have the feeling I'm forgetting something since I've tried in different ways and always have a 404 returned
Update 1
I installed the RouteDebugger from http://www.codeproject.com/Articles/299531/Custom-routes-for-MVC-Application and it just shows the "basic" routes from MVC ({resource}.axd/{*pathInfo} and {controller}/{action}/{id}), it doesn't show the route I mapped
It turns out I added the RegisterRoutes method in the wrong location, I thought I had to include that method inside Global.asax, I guess prior to MVC4 the Global.asax was the right location, however, on MVC4 I have to map the routes using the file located in /App_Start/RouteConfig.cs

MVC 4 Web API Areas 404 Error: "The controller for path '/Jobs/Send' was not found or does not implement IController."

I'm having an issue that is driving me nuts.
I have an MVC 4 WebAPI application that has several Areas defined.
My Jobs Area Send controller (SendController.cs) is defined like so:
namespace TargetAPI.Areas.Jobs.Controllers
{
public class SendController : ApiController
{
[HttpPost]
public HttpResponseMessage Index(SendRequest req)
{
try
{
//blah blah
}
catch (Exception ex)
{
//blah blah
}
}
}
}
My Jobs Area Registration (JobsAreaRegistration.cs) is defined like so:
namespace TargetAPI.Areas.Jobs
{
public class JobsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Jobs";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Jobs_long",
"Jobs/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "TargetAPI.Areas.Jobs.Controllers" }
);
}
}
}
My RouteConfig.cs says:
namespace TargetAPI
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index", id= UrlParameter.Optional },
namespaces: new string[] { "TargetAPI.Controllers" }
);
}
}
}
When I run the route debugger on it I get:
(source: boomerang.com)
But when I try to post to the URL "Jobs/Send" I get:
The controller for path '/Jobs/Send' was not found or does not implement IController.
I've tried so many iterations and combinations my head is spinning. Any ideas?
Thanks!
Turns out the WebAPI does NOT handles Areas! Imagine my surprise. So I found a GREAT post http://blogs.infosupport.com/asp-net-mvc-4-rc-getting-webapi-and-areas-to-play-nicely/. Now I am moving forward.
In addition to not supporting Areas (because MapHTTPRoute doesn't have namespace support), The API controller must use MapHttpRoute, not MapRoute as in this example (after removing area):
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Note the absence of {action}, the Method's are not Actions, put are taken from the HTTP request: Get, Head, etc...
I had the same problem, the solution was simple: I forgot to add files _ViewStart.cshtml and _Layout.cshtml, and can help you

Resources