.NET MVC3 routing - why so confusing? - asp.net-mvc-3

I don't know why I constantly struggle with this, but can someone explain why this doesn't work?
/ redirects to the index action of the home controller.
/gallery/ throws a 404 not found error.
/gallery/index redirects to the index action of the gallery controller.
From the documentation:
When you define a route, you can assign a default value for a parameter. The default value is used if a value for that parameter is not included in the URL. You set default values for a route by assigning a dictionary object to the Defaults property of the Route class.
I don't understand how this doesn't follow that rule:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
To me it reads:
If a controller is not defined, use Home.
If an action is not defined, use Index.
URL entered contains a controller = gallery and an action is not included in the URL so it should be going to the Index.
Am I missing something or this unnecessarily confusing and silly?
I've always found MVC3 routing problematic but accepted it. Then I started playing with Rails and Node frameworks and they have ridiculously simple routing so now .NET MVC just annoys me when it doesn't work or makes me use convoluted patterns.
For reference in case someone asks, my Gallery controller, Action and View are all defined and working when I browse to /gallery/index.
public class GalleryController : Controller
{
public ActionResult Index()
{
return View();
}
}

You definitively oughta be doing something wrong or there is some code you haven't shown us. Perform the following steps:
Create a new ASP.NET MVC 3 application using the default wizard (Internet Application)
Replace the contents of HomeController.cs with this:
public class HomeController : Controller
{
public ActionResult Index()
{
return Content("home/index");
}
}
public class GalleryController : Controller
{
public ActionResult Index()
{
return Content("gallery/index");
}
}
Hit F5
Here's what happens:
requested url | result
-----------------+---------------
/ | home/index
/home | home/index
/home/ | home/index
/home/index | home/index
/home/index/ | home/index
/gallery | gallery/index
/gallery/ | gallery/index
/gallery/index | gallery/index
/gallery/index/  |   gallery/index
Exactly as expected, isn't it?

Problem was I had a hidden directory (not included in my solution) with the same name as my faulty route: /gallery.
Luckily I'm too tired this morning to punch my monitor.
Thanks everyone for your suggestions, all +1'd for helpful guidance.
PS. To help me investigate the problem I used Phil Haack's routing debugger.

Related

Cannot view my new MVC 4 application

I just created a new basic MVC 4 application in VS 2010. I just clicked the play button to test it came up in the web browser and I'm getting the following page:
I think I need to change my virtual path to something but I don't know what.
EDIT: Can't see what it says properly in the picture:
Server Error in '/' Application.
--------------------------------------------------------------------------------
The resource cannot be found.
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: /
If you created an Empty Project you will need to create a HomeController with an Index Action. You will also need to create a View in ~/Views/Home/ called Index.
The other project templates create this for you but the Empty Project does not.
public class HomeController : Controller
{
public ActionResult Index()
{
return View()
}
}
No one person gave me the full answer. So this is an amalgamation of #MattiVirkkunen and #BrettAlfred
Add this within RouteConfig.cs
routes.MapRoute(
name: "Default",
url: "",
defaults: new { controller = "Home", action = "Home" }
);
Add this within HomeController.cs
public ActionResult Login()
{
return View();
}
Kya Neeta MVC me neyi ho Kya?? I am too :)
I think u have created a start-up page in your applicaition.
Type Http: //localhost:8080/Home/Index in your url
http: //localhost:/ControllerName/ActionName
if that does not work please create a new MVC application from scratch.

Server Error in '/' Application MVC3

im not sure what i messed up, but i just keep getting the following error upon f5.
The resource cannot be found.
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: /
The following is my route, totally default and no changes.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
I have checked my project properties -> web tab, "Specific page" has nth. My project has Home folder with Index page.
Other pages are working only after manually inputting URL. For eg: http://localhost:21183/store/search
Thanks
Things to check:
You have a public class named HomeController that derives from Controller.
This HomeController class has a public Index action.
You have a corresponding view ~/Views/Home/Index.cshtml
You are testing this inside a web server which supports extensionless urls. For example this won't work out of the box in IIS 6.0.
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
return View();
}
}

C# MVC RedirectToAction not working?

So I want to create a new view in my MVC application that allows a user to enter parameters for searching. I want to pass these parameters to another View/Controller and I want the controller to call an action called "Search" to handle these parameters and return the correct data. However, when I try to "Redirect" it is giving me a problem. It says the resource cannot be found,
The view 'Search' or its master was not found or no view engine supports the searched locations.
The following locations were searched:
~/Views/Question/Search.aspx
This is the code.
[HttpPost]
public ActionResult HandleForm()
{
SearchQuery search = new SearchQuery();
if(Request["QuestionID"].Trim()!="")
search.QuestionID = Convert.ToInt32(Request["QuestionID"].Trim());
return RedirectToAction("Search", "Question");
}
However, if I change "Search" to "Index" it loads the page I desire because it opens the view within that page. It does not call the search action. Why is this method returning the View when every example I've read states that the name of the Action needs to be passed?
For those who are wondering this is my global.asax routing info
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
Last but not least, I have yet to look into how to pass these parameters, but I hope it won't be too much extra work once I can figure out why this is not working as desired.
Go to the Views/Questions directory and make sure there is a file called Search.cshtml. If it does exist also then make sure that this view has a corresponding action method, something like:
public class QuestionController : Controller
{
public ActionResult Search()
{
}
}
If you are in same controller then write:
return RedirectToAction("Search");
or if your search action is in other controller then write:
return RedirectToAction("Search","your Controller Name Here");

ASP.NET MVC3 sample project removing home folder

I'm using the ASP.NET MVC3 sample project and would like to have new links added to the page that go directly to the root url
So instead of mydomain.com/Home/About it would do mydomain/About.
This page suggests adding a new route. http://weblogs.asp.net/gunnarpeipman/archive/2011/04/17/asp-net-mvc-defining-short-urls-for-root-level-pages.aspx
Is there another way? Say I have 5 pages that will be on the root do I have to add a special route for each one?
Under the assumption that you are looking to do a bunch of single path requests/respones, and not just redirect home controller actions, then this is an option.
The link you provide is one way to do that. The other is to create 5 controllers using the default route. I'm not sure if I would suggest either is better (due to a lack of what your 5 paths actually are), but they both produce the same out come. If your default route looks like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
It's basically stating that the default controller is home and the default action is index. These values are not mutually inclusive, meaning that neither required the other in order to be a default value.
Thus you could do:
website.com/about with
public AboutController
{
public ActionResult index()
{
return this.View();
}
}
and/or website.com/people with
public PeopleController
{
public ActionResult index()
{
return this.View();
}
}

MVC3 Area +Authorize attribute + Role strange issue

I really don't know what title should I use to describe my problem. To simplify my problem. Here is my test. I create a mvc3 site from scratch. I then add area called "admin". Inside admin, I have a controller named "Search" and has "Authorize" attribute decorated. I then changed my Global.ascx.cs route setting to append my controller namespace. Now I start my test.
Question 1
When I am accessing to http://localhost:xxx/Search page, it redirects me back to /Account/Logon page, it makes me confuse first, why it redirects me to logon page? it shouldn't reach to Admin search controller at all as I understand. If I removed the Authorize attribute, it display the yellow screen said can't find the view as I expected.
Question 2
If I add Authorize attribute with role, e.g. (Roles="Admin"), then I try access to Search page again, no matter login succeed or not, I always get redirect back to logon page. Why it doesn't give me the yellow screen, coz I am trying to request the search controller index view in the main site not the admin area's one. quite confuse.
I am a newbie in MVC development, can someone give me a solution regarding to my problem?
Thanks
Global.ascx.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[]{"TestAreaRouting.Controllers"}
);
}
You could constrain the default controller factory to look only inside the specified namespace for controllers in the RegisterRoutes method of Global.asax by setting the UseNamespaceFallback data token to false:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "TestAreaRouting.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;
}
If you don't do this when you request /search the admin area route doesn't match because the url doesn't start with the Admin prefix.
So it is the default route that matches. The default controller factory starts scanning the assembly for a class called SearchController that derives from Controller and since it finds one it instantiates it and uses it to serve the request. Obviously it doesn't find a corresponding Index view because it looks in ~/Views/Search/Index.cshtml which obviously doesn't exist. The actual view is located in the area.
Now that we have constrained the controllers to their respective locations you could decorate them with the Authorize attribute and it should behave consistently.

Resources