Why can't ASP.NET MVC URL routing find my controller? - asp.net-mvc

In my Global.asax.cs file in RegisterRoutes method, I put
routes.MapRoute("messages",
"Message/{id}",
new { controller = "Archive", action = "Message", id = 0 });
Then I created this controller:
namespace TestingApp.Controllers
{
public class ArchiveController : Controller
{
public string Message(int id)
{
return "testing: you will receive the message: " + id.ToString();
}
}
}
But in my browsser when I go to:
http://.../Message/34
I get a 404.
What else do I need to define so that the routing finds my controller?

Try defining your specific route before the Default one:
routes.MapRoute(
"messages",
"Message/{id}",
new { controller = "Archive", action = "Message", id = 0 });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });

I think your Message method should return an ActionResult instance:
public ActionResult Message(int id)
{
return new ContentResult {
Content = "testing: you will receive the message: " + id.ToString()
};
}

Related

ASP.NET MVC Overriding Index action with optional parameter

I want to accept /User/ and /User/213123
Where 213123 is a parameter (user_id)
Here is my RouteConfig.cs:
routes.MapRoute(
name: "user",
url: "{controller}/{action}/{username}",
defaults: new { controller = "User", action = "Index", username = UrlParameter.Optional }
);
And my UserController.cs:
public ActionResult Index()
{
ViewData["Message"] = "user index";
return View();
}
[Route("user/{username}")]
public ActionResult Index(string username)
{
ViewData["Message"] = "!" + username + "!";
return View();
}
This works in .net-core 1.0 but not in mvc5. What am I missing?
Thank you
EDIT:
Having just this in my UserController.cs also doesn't work (returns 404):
public ActionResult Index(string username)
{
if (!String.IsNullOrEmpty(username))
{
ViewData["Message"] = "Hello " + username;
}
else
{
ViewData["Message"] = "user index";
}
return View();
}
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /user/asd
EDIT2:
Updated RouteConfig.cs:
routes.MapRoute(
"userParam", "user/{username}",
new { controller = "user", action = "IndexByUsername" },
new { username = #"\w+" }
);
routes.MapRoute(
name: "user",
url: "user",
defaults: new { controller = "User", action = "Index"}
);
/User/ now calls IndexByUsername with Index as the username
/User/asd still returns 404
EDIT4: Current code:
RouteConfig.cs:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute("userParam", "user/{username}", new { controller = "user", action = "Index"});
routes.MapRoute("user", "{controller}/{action}/{username}", new { controller = "User", action = "Index", username = UrlParameter.Optional });
UserController.cs:
public class UserController : Controller
{
public ActionResult Index(string username)
{
if (!String.IsNullOrEmpty(username))
{
ViewData["Message"] = "Hello " + username;
}
else
{
ViewData["Message"] = "user index";
}
return View();
}
}
You need only one action method with the signature
public ActionResult Index(string username)
and in that method you can check if the value of username is null or not.
Then you route definitiosn needs to be (note the user route needs to be placed before the default route)
routes.MapRoute(
name: "user",
url: "user/{username}",
defaults: new { controller = "User", action = "Index", username = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

How to display only name in url instead of id in mvc.net using routing

I am getting url like http://localhost:49671/TestRoutes/Display?f=hi&i=2
I want it like http://localhost:49671/TestRoutes/Display/hi
I call it from Index method.
[HttpPost]
public ActionResult Index(int? e )
{
// return View("Display", new { f = "hi", i = 2 });
return RedirectToAction("Display", new { f = "hi", i = 2 });
}
Index view
#model Try.Models.TestRoutes
#using (Html.BeginForm())
{
Model.e = 5 ;
<input type="submit" value="Create" class="btn btn-default" />
}
Display Action method
// [Route("TestRoutes/{s}")]
public ActionResult Display(string s, int i)
{
return View();
}
Route config file
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{id}/{name}", // URL with parameters
new { controller = "TestRoutes", action = "Display", s = UrlParameter.Optional, i = UrlParameter.Optional
});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional
});
You need to change your route definition to
routes.MapRoute(
name: "Professional",
url: "TestRoutes/Display/{s}/{i}",
default: new { controller = "TestRoutes", action = "Display", i = UrlParameter.Optional }
);
so that the names of the placeholders match the names of the parameters in your method. Note also that only the last parameter can be marked as UrlParameter.Optional (otherwise the RoutingEngine cannot match up the segments and the values will be added as query string parameters, not route values)
Then you need to change the controller method to match the route/method parameters
[HttpPost]
public ActionResult Index(int? e )
{
return RedirectToAction("Display", new { s = "hi", i = 2 }); // s not f
}
change your route as
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{name}", // URL with parameters
new
{
controller = "TestRoutes",
action = "Display"
} // Parameter defaults
);
and your action as
public ActionResult Display(string name)
{
//action goes here
}
Remove the maproute code:
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{id}/{name}", // URL with parameters
new { controller = "TestRoutes", action = "Display", s = UrlParameter.Optional, i = UrlParameter.Optional
});
Use attribute routing code:
[Route("TestRoutes/{s}/{i?}")]
public ActionResult Display(string s, int? i)
{
return View();
}
You can also try using Attribute Routing. You can control your routes easier with attribute routing.
Firstly change your RouteConfig.cs like that:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
//);
}
}
After that change your controller files like that:
namespace YourProjectName.Controllers
{
[RoutePrefix("Home")]
[Route("{action}/{id=0}")]
public class HomeController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
[Route("ChangeAddress/{addressID}")]
public ActionResult ChangeAddress(int addressID)
{
//your codes to change address
}
}
You can also learn more about Attribute Routing in this post:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
Another way to solve this problem is to put the proper route before the default route, as follows:
routes.MapRoute(name: "MyRouteName", url: "Id", defaults: new { controller= "Home", action = "Index",id= Id });
Default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{Id}",
defaults: new { controller = "Home", action = "Index",id= Id }
);

MVC Route static value

I'm not sure if this is possible using mvc routing, I haven't been able to find a similar example.
I have about 5~ controller actions that are the same method, so I'd like to refactor them into a single action. I'd like to pass an enum value to the controller to tell it what path it should pass to lower layers.
Example:
public ActionResult ViewPage(int id, PageEnum page) {
var model = MyService.GetModelForTemplate(id, page);
return ("ViewPage", model);
}
Then the user could access this either through /PagesTypeOne/ViewPage/, or /PagesTypeTwo/ViewPage/. Both routes leading to the same endpoint.
Route table attempt:
routes.MapRoute(
name: "typeOne",
url: "PagesTypeOne/{action}/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional, page = PageEnum.TypeOne, }
);
routes.MapRoute(
name: "typeTwo",
url: "PagesTypeTwo/{action}/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional, page = PageEnum.TypeTwo, }
);
This obviously isn't working.
Is there a way I can do something like this? It would make my code much more concise.
screen != page, so if the property on the anonymous type matches the parameter it will work:
public ActionResult ViewPage(int id, PageEnum screen) {
var model = MyService.GetModelForTemplate(screen);
return ("ViewPage", model);
}
Updated: Created a empty application and it work flawlessly:
namespace MvcApplication6
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Test1",
"PagesTypeOne/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional,
page = PageEnum.PageOne } // Parameter defaults
);
routes.MapRoute(
"Test2",
"PagesTypeTwo/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional,
page = PageEnum.PageOne } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}
public enum PageEnum
{
Undefined,
PageOne,
PageTwo
}
Controller:
namespace MvcApplication6.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult ViewPage(int id, PageEnum page)
{
var debug = 1; // break point
return new EmptyResult();
}
}
}
you can make it completely dynamic with one route definition:
// the route must be defined as the first route
routes.MapRoute(
name: "typeTwo",
url: "{page}/ViewPage/{id}",
defaults: new { controller = "Pages", action = "ViewPage", id = UrlParameter.Optional },
new { page= getPageTypes() }
);
the getPageTypes method:
private static string getPageTypes()
{
var pageTypes = Enum.GetNames(typeof(PageEnum));
return string.Join("|", pageTypes );
}
but PagesTypeOne/ViewPage/4 part must match the enum's name.

Custom Route Not Working in mvc 4

I have created one custom route
routes.MapRoute("Exams",
"Exams/{id}/{name}",
new { controller = "Exam", action = "SingleExam", id = "", name = (string) null },
new[] { "MockTests.FrontEnd.Controllers" }
);
For this I am creating link as
http://localhost:61575/Exams/12/maharashtra+mba+common+entrance+test
But his gives error as
The resource cannot be found
SingleExam code
public ActionResult SingleExam(int id,string name)
{
return View();
}
Other Routes
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "User", action = "Register", id = UrlParameter.Optional },
new[] { "MockTests.FrontEnd.Controllers" }
);
What wrong I am doing ?

MVC routing problems - url generation

I what to create a url that looks like website.com/sea/season/23/team
Here is the MapRoute
routes.MapRoute(
"SeaTeam",
"sea/season/{seasonId}/team/{action}/{name}",
new { controller = "Team", action = "Index", name = UrlParameter.Optional }
);
The Html.ActionLink looks like
#Html.ActionLink("Add Team", "Index", "SeaTeam", new { seasonId = seasons.id }, null)
But its generating the following url
Add Team
Any insights? Thanks...
Update
Here is the controller
public class TeamController : Controller
{
//
// GET: /Team/
public ActionResult Index()
{
//get the seasons of the loged user
var loadedTeam = tempFunctions.getSeasonsOf(CustomHelper.UserGuid(User.Identity.Name));
return View("Team/ManageTeam", loadedTeam);
}
try:
#Html.ActionLink(
"Add Team", // linkText
"Index", // Action
"Team", // Controller
new { seasonId = seasons.id },
null)
I don't see a SeaTeam Controller

Resources