MVC Attribute Routing adding Area Querystring Parameter - asp.net-mvc-5

I've tried adding the Route attribute to our controller through various methods.
[Route("Trials/{trialId:int}/Components/{action}")]
public partial class ComponentsController : Controller
{
public virtual ActionResult List(int trialId)
{
return View();
}
}
Or
[RoutePrefix("Trials/{trialId:int}/Components")]
[Route("{action=List}")]
public partial class ComponentsController : Controller
{
public virtual ActionResult List(int trialId)
{
return View();
}
}
are just a few examples.
The links generated going to this controller/action look like this:
http://localhost:50077/Trials/3/Components?Area=
I'm looking to remove the query string parameter. No matter how I place the route configuration with attributes, it never seems to work.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
//routes.MapRoute(
// name: "TrialComponents",
// url: "Trials/{trialId}/Components/{action}/{id}",
// defaults: new {controller = "Components", action = "List", area = "", id = UrlParameter.Optional},
// constraints: new { trialId = "\\d+"}
//);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "UnitGroups", action = "List", area = "", id = UrlParameter.Optional }
);
}
}
The commented out route works and does not apply a querystring to the url.
Can anyone explain why the route method is adding the Area querystring and how I can fix it? I'm stumped.

Area is not a route value that is stored in the RouteData.Values collection, it is instead found on the RouteData.DataTokens collection (as metadata). It is not correct to set a default for area in your RouteCollection because this only gets applied to RouteData.Values of the request.
In short, to remove the Area parameter from your generated URLs, you need to remove it as a default value in your MapRoute.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "UnitGroups", action = "List", id = UrlParameter.Optional }
);

Related

asp.net MVC default action not working in area

I have a project with a setup area declared and a URL that works as long as I explicitly include the "/Index" action. The problem is when I use RedirectToAction("Index") it excludes "/Index" from the URL and I get a 404 Page Not Found. The URLs are:
http://localhost:40078/Setup/Facility/Index - Works
http://localhost:40078/Setup/Facility/ - 404 (with or without trailing /)
RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "T.C.MVCWeb.Controllers" }
);
}
SetupAreaRegistration:
public class SetupAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Setup";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Setup_default",
"Setup/{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "T.C.MVCWeb.Areas.Setup.Controllers" }
);
}
}
Requested Controller
namespace T.C.MVCWeb.Areas.Setup.Controllers
{
public class FacilityController : Controller
{
// GET: FacilitySetup
public ActionResult Index()
{
...
}
}
}
I added Phil Haack's RouteDebugger and can see that the 404 request thinks "Setup" is the controller, but I don't understand why and the rest of the output is confusing me more than it's helping.
Thanks to NightOwn888's comment, I found a route declared via an attribute. The offending route attribute declared Setup/{action} which was intended to allow the area URL itself http://localhost:40078/Setup/ to map to a SetupController.

MVC5 Attribute Routing

I am trying to use Route Attributes to define the MVC Routing.
I have got the following code in the Controller..
[Route("MDT/Detail/{id}")]
public JsonResult Detail(int? id)
{
ITS.Models.ComputerDetail cp = GetDataFromDatabase(id.Value);
return Json(cp, JsonRequestBehavior.AllowGet);
}
If I used this URL (http://localhost:6481/MDT/Detail?id=1245) it returns JSON data.
But If I used (http://localhost:6481/MDT/Detail/1245), it shows the error saying the variable id is Null.
Exception Details: System.InvalidOperationException: Nullable object must have a value.
Could you please help me how I could achieve {Controller}/{Action}/{ID} routing by using Routing Attribute?
Have you enabled attribute routing by adding this line:
routes.MapMvcAttributeRoutes();
in RegisterRoutes?
Please try below code, it might helpful for you,
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

MVC Controller looks for an aspx page by default

I have a solution with one web application which contains Models and Views and the Controllers in a separate class library. I have Razor views in my views folder. When I type in the url (e.g. Home/Index) the constructor correctly finds the correct view index.cshtml, however If If don't enter the actions name, I get an error stating that the Resource can't be found and the requested url is /Home/index.aspx.
How can I make the constructor look for razor views by default. My route config is just the standard default one.
public static void RegisterRoutes(RouteCollection routes){
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
namespaces: new[] { "MyProject.Controllers" },
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
except I have a reference to the Controllers namespace.
Thanks
You're missing a default value for the controller, in your default route.
public static void RegisterRoutes(RouteCollection routes){
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
namespaces: new[] { "MyProject.Controllers" },
defaults: new { action = "Index", controller = "Home", id = UrlParameter.Optional }
);
}

MVC5 Routing change URL to inclide class name attribute rather than ID and with show action

My default route config is declared as follows:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
If I have a teams controller and I want to show the teams the URL is:
http://example.com/Teams/Show/1
Without affecting the rest of the routes is there a means of configuring this so it would just show as:
http://example.com/Teams/Arizona
Yes. One way is to use attribute routing.
http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
In your RouteConfig or equivalent:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
}
And in your controller of interest:
[Route("Teams/{teamName}")]
public ActionResult ShowTeam(string teamName)
{
var teamInfoViewModel = Service.GetViewModel(teamName);
return View(teamInfoViewModel);
}

MVC Route not being used when it should

I am working on an application where I would like a url like so User\1\Class\Create would map to the Class controller and the Create action, but when I apply it, it doesn't pick it up.
Below is how I have the route registered (it is at the top of the list):
routes.MapRoute(
name: "UserClass",
url: "User/{userId}/Class/Create",
defaults: new { controller = "Class", action = "Create", userId= "" },
constraints: new { userId= #"\d+" }
);
(I have also tried it by omitting the userId="" default)
This is paired with this code:
public class ClassController : BaseController
{
public ActionResult Create(int userId)
{
var vm = new ClassEditorViewModel
{
Class = new Class { UserId = userId },
ClassEnrollmentStatuses = new SelectList(Db.ClassEnrollmentStatuses.ToList(), "Id", "Name")
};
return View(vm);
}
}
But this doesn't work. When I use Route Debugger (by Phil Haack) it doesn't use the above route and selects the {*catchall} route.
What am I doing wrong with the route configuration to make it not be used?
Deleted the route and re-typing it resolved the issue.

Resources