I am practicing ASP.NET MVC using vs 2013, and writed a simple project, with one controller and view.
controller code:
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public ActionResult ShowMyHome()
{
return View("MyHome");
}
}
"MyHome" view Code:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Hello World</title>
</head>
<body>
<div>
Welcome my first MVC page
</div>
</body>
</html>
RouteConfig code:
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 }
);
routes.MapRoute(
name: "Home",
url: "Home",
defaults: new { controller = "Home", action = "ShowMyHome", id = UrlParameter.Optional }
);
}
}
when i run and set url line on "http://mySite/Home/ShowMyHome", it works well.
but when i run and set url line on "http://mySite/Home", i get a error:
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
It looks like the "Home" routing doesn't work.
Your Home route isn't being reached because when navigating to ~/Home the default route is matched, given that your controller name is HomeController.
If your desired result is to map ~/Home to ShowMyHome() explicitly then you will need to move your custom route above the default one.
You don't need to define a separate route for each controller actions you create, 9 times out of 10, the default route is fine.
The problem isn't routing, it's that ASP.NET can't find your Index.cshtml view. You need to add a view for Index().
You still have the default route pointing to the 'Index' view and action, which doesn't exist. Place your custom route before the default route and your problem should be solved.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Home",
url: "Home",
defaults: new { controller = "Home", action = "ShowMyHome", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
routes.MapRoute(
name: "Home",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "ShowMyHome", id =UrlParameter.Optional }
);
You will need to create a view for Index. In the Controller, right-click on Index() and choose "Add View".
Then, complete the wizard for how you want that view to behave.
Edit: Based on the answers I'm seeing, I believe there may be a small misunderstanding. You should not need to create a new route for every Controller you make. You should generally use the default route and use Index as your home page. Custom routes tend to come into play when you need to provide more information to your controller than just /action/id.
Related
This doesn't make sense to me, why does it look for the index within an equipment folder?!?!?
I get this warning message in the windows application event logs usually at least once a day.
Exception type: InvalidOperationException
Exception message: The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Equipment/Index.aspx
~/Views/Equipment/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Equipment/Index.cshtml
~/Views/Equipment/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
I have the following structure:
Controllers (folder)
Service.cs (file)
View (folder)
Services (folder)
Equipment.cshtml
There are only links to the equipment URL are:
#Html.ActionLink("Equipment", "equipment", "services", null, new { #class = "dropdown-item" })
and
#Html.ActionLink("Equipment", "equipment", "services", null, new { #class = "green" })
In case it is relevant this is the view code for Equipment within the Services.cs file:
[Route("equipment")]
public ActionResult Equipment()
{
return View();
}
P.S. Using MVC 5.2.9, Razor 3.2.9 and .Net Framework 4.7.2
EDIT: As requested by Victor here is the RegisterRoutes method, there is nothing special occuring.
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 }
);
routes.MapRoute(
"Error", // Route name
"Error", // URL with parameters
new { controller = "Error", action = "Index" });
}
For Yiyi You, here is the code for ServicesController.cs:
[RoutePrefix("services")]
public class ServicesController : Controller
{
[Route]
public ActionResult Index()
{
return View();
}
[Route("equipment")]
public ActionResult Equipment()
{
return View();
}
}
For the error,you can try to change the folder name and cshtml file name:
View (folder)
Equipment (folder)
Index.cshtml
Or you can try to share more code in Service.cs.
At least one problem exists in the code. The "default" route is universal - the second "Error" will never used. Fix to:
routes.MapRoute(
"Error", // Route name
"Error", // URL with parameters
new { controller = "Error", action = "Index" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
I have an MVC project using C#.
I have been using only one view, Views/Home/Index.cshtml to do most of the stuff I need the app to do.
Today I was asked to add a new page, that will serve as an "Admin" type of page to allow some basic crud operations to a record.
I am having trouble understanding how to navigate to a page other than the Home/Index.cshtml, actualy I do not even navigate to that page in the browser, since that is the default routing, the url looks like: http://localhost:51225/Meetings/Agenda/ -- this is how I can see the Index.cshtml page.
So far what I have done, in the HomeController, I added this code below the Index View:
// GET: Home
public ActionResult Index()
{
return View();
}
//GET: Admin
public ActionResult Admin()
{
return View(); -- I right clicked, and added a new view named "Admin"
}
My folders now look:
Views
Home
Admin.cshtml
Index.cshtml
I have not changed the RouteConfig class:
public class RouteConfig
{
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 = "" } // Parameter defaults
);
}
}
I can still open my app, and see the Index.cshtml when I go to:
http://localhost:51225/Meetings/Agenda
But I do not know how to access the Admin.cshtml
So far I know it is not by simply adding Admin at the end
http://localhost:51225/Meetings/Agenda/Admin
Nor
http://localhost:51225/Meetings/Agenda/Home/Admin
Nor
http://localhost:51225/Meetings/Agenda/Home/Admin.cshtml
Is it possible to ask for help in trying to learn how and what needs to chane in my solution in order to navigate to a different page that Index in the Home folder?
Add Custom route to the RegisterRoutes method in Route confige before default route:
routes.MapRoute(
name: "AgendaRoute",
url: "Meetings/Agenda/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Final RouteConfig:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "AgendaRoute",
url: "Meetings/Agenda/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Result :
http://localhost:51225/Meetings/Agenda => Index.html
http://localhost:51225/Meetings/Agenda/index => Index.html
http://localhost:51225/Meetings/Agenda/index/1 => Index.html
http://localhost:51225/Meetings/Agenda/admin => Admin.html
http://localhost:51225/Meetings/Agenda/admin/1 => Admin.html
the default routing convention of ASP.NET MVC is Controllername/Action/parameter.
Lets say for example you have a Route like Products/Create, ASP.NET will search for an Action named Create in ProductsController and the view will be Create.cshtml inside the Products directory.
I suggest you follow that convention and create an AdminController and put Index action on the controller. Which you can Access by localhost:51225/Admin/Index. For the views, the convention is it searches for a view with the same name as the action,, that is you create a folder named Admin and put Index.cshtml inside it
You can always access anything by /ControllerName/ViewName/ParametersIfNeeded. I suggest you to add a button on the navigation bar which will be visible only for admins, and so that only they can visit that page. In your case the admin View can be accessed with http://localhost:51225/Home/Admin.
I thought I could have friendly URLs for all routes in my mixed ASP.NET + MVC application, but it is not working as I expect. Here is my routing definition setup:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapPageRoute("Design-Fancy", "Design/Fancy/{*queryvalues}", "~/Design/example10.aspx", true);
routes.MapPageRoute("Design-Simple", "Design/Simple/{*queryvalues}", "~/Design/example5.aspx", true);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
While this works to route to the *.aspx pages, Any Razor action tags on the same page that are defined for example as "Home" for the controller and "About" for the Action actually are rendered in the page source as 'http://..../Design/Fancy?action=About&controller=Home'. So, this breaks all the navigation menu URLs, etc. I must be doing it wrongly!
Here is the solution I settled on. I installed the NuGet Microsoft.AspNet.FriendlyUrls package. Then I named the .aspx page with a page name that would look good without the extension. Then I set up the routing as follows:
public static void RegisterRoutes(RouteCollection routes)
{
FriendlyUrlSettings aspxSettings = new FriendlyUrlSettings();
aspxSettings.AutoRedirectMode = RedirectMode.Off; // default=Off
routes.EnableFriendlyUrls(aspxSettings);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapPageRoute("Design-Fancy", "Design/Fancy/{*queryvalues}", "~/Design/Fancy.aspx", true);
routes.MapPageRoute("Design-Simple", "Design/Simple/{*queryvalues}", "~/Design/Simple.aspx", true);
}
This gives the effect I wanted, and works with my MVC routing, and results in routing to .aspx pages while removing the .aspx extension.
Greetings New to MVC ...
I am creating my first MVC Application, and I have created it as follows:
CustomUtilities/Controllers/GCItemRetrievalController.cs
CustomUtilities/Views/GCItemRetrieval/GCRetrieve.cshtml
CustomUtilities/Views/Web.config
I want to pull up "GCRetrieve.cshtml in my browser ... but I keep getting a 404 Error
http://mainsite/CustomUtilities/GCItemRetrieval/GCRetrieve
what am I doing wrong? I created the folders for the controllers, models, and Views in a seperate folder on the main system.
Your controller should look something like this:
public class GCItemRetrievalController : Controller
{
public ActionResult GCRetrieve()
{
return View();
}
}
When you navigate to the following url:
http://mainsite/CustomUtilities/GCItemRetrieval/GCRetrieve
It should find the controller's GCRetrieve method and execute it. The return View() call will look for a .cshtml file named GCRetrieve.cshtml, as that is the name of the method.
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 }
);
}
}
When you create a MVC application a class file named as RouteConfig.cs is created in App_Start directory. It has default routing as
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 }
);
}
}
In the above default routing:
if you want call a view CustomUtilities/Views/GCItemRetrieval/GCRetrieve.cshtml
I think CustomUtilities is your project name then use following
http://mainsite/GCItemRetrieval/GCRetrieve
that is
[domanin]/[controllername]/[actionname]
For default routing detail you can refer to http://www.niceonecode.com/Q-A/DotNet/MVC/routing-in-mvc-4/20190
In my website, I have the following default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When I access the Index page from the Home controller, I get the following address:
http://localhost/MyWebsite/
Everything is okay, however, I would like to add another default route for the following Controller and Page:
http://localhost/MyWebsite/Profile/Index/8
For the link above, I would like to have the following route:
http://localhost/MyWebsite/Profile/8
Without showing the "Index" page name.
How is it possible?
Inside the RouteConfig, set enable to route Actions via Attribute:
routes.MapMvcAttributeRoutes();
After that, add the Attribute Route above the Action name:
[Route("Perfil/{id}")]
public ActionResult Index(int? id)
{
return View();
}