Matthew Hudson
Matthew Hudson

Reputation: 1316

New MVC 4 Project. Default routes are getting ignored

I just created a new MVC 4 project, and added an EDO.NET Entity Data Model using Database First. I'm not sure exactly why, but things don't seem to be functioning correctly as they used to. I had to manually add the EF Code Generation item to generate the entity classes.

Anyway, the main problem I have is that the default routing seems to be ignored. My route config is the default, which is as follows:

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 }
        );
    }
}

However [LOCALHOST]/Properties/ doesn't find /Properties/Index, it merely returns a 404 Server Error in '/' Application. The resource cannot be found.

I wouldn't put it past me to have made some silly mistake or forgotten something crucial, but I've searched StackOverflow and the interwebs for similar problems and none of the solutions are of any help. If anyone knows why, I'd be grateful for a prod in the right direction.

Requested Edits:

I have 3 Controllers:

  1. Home - Untouched
  2. Account - Untouched
  3. Properties - w/ Default MVC CRUD Actions (Index, Details, Create, Edit)

It works fine when hosted on IIS but not on VS's internal debugging IIS.

@Html.ActionLink("Properties", "Index", "Properties") generates http://[localhost]:53909/Properties when run. However clicking the generated link gives me a "Server Error in '/' Application. The resource cannot be found."

PropertiesController.cs (only Index action)

public class PropertiesController : Controller
{
    private PropertyInfoEntities db = new PropertyInfoEntities();

    //
    // GET: /Properties/

    public ActionResult Index()
    {
        //Mapper.CreateMap<Property, PropertiesListViewModel>()
            //.ForMember(vm => vm.MainImageURL, m => m.MapFrom(u => (u.MainImageURL != null) ? u.MainImageURL : "User" + u.ID.ToString()))
        //    ;
        //List<PropertiesListViewModel> properties =
        //    Mapper.Map<List<Property>, List<PropertiesListViewModel>>(db.Properties.ToList());
        return View(db.Properties.Include(p => p.Currency).Include(p => p.Type).Include(p => p.Province).Include(p => p.Region).Include(p => p.SaleType).Include(p => p.Source).Include(p => p.Town).ToList());
    }
}

_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - My ASP.NET MVC Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <header>
        <div class="content-wrapper">
            <div class="float-left">
                <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
            </div>
            <div class="float-right">
                <section id="login">
                    @Html.Partial("_LoginPartial")
                </section>
                <nav>
                    <ul id="menu">
                        <li>@Html.ActionLink("Home", "Index", "Home")</li>
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Properties", "Index", "Properties")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
                </nav>
            </div>
        </div>
    </header>
....

Edit 2: Even with a specific route it is still ignored

namespace ProjectName
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Properties",
                "Properties/{action}/{id}",
                new { controller = "Properties", action = "Index", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Cheers!

Upvotes: 1

Views: 1192

Answers (5)

Matthew Hudson
Matthew Hudson

Reputation: 1316

I tried changing the name of PropertiesController to Properties1Controller, and the routing worked for it completely fine. After some further digging I discovered that it's because Properties is a Windows Reserved Keyword.

Anyhow, the solution to the problem: Do not use reserved keywords as controller names.

Strangely routing for /Properties/Index works completely fine, and routing for /Properties/ works completely fine on production IIS, just not for development. This made it much harder to work out the problem but managed to get there in the end.

Thank-you all for your assistance.

Upvotes: 3

EfrainReyes
EfrainReyes

Reputation: 991

Does the namespace of the Properties controller match the "ProjectNamespace.Controllers" convention? If you copied the code from another source you may have forgotten to change the namespace of the controller class.

Upvotes: 1

LINQ2Vodka
LINQ2Vodka

Reputation: 3036

Default route means that every [localhost]/foo/bar request is forwarded to FooController and its Bar action that must return some existing View. Probably you don't have some of them.
"defaults" parameter sets default controller and action names in case they are not specified in request (i.e. http://[localhost]/) so in your case this will search for HomeController and its Index action.

Upvotes: 2

John H
John H

Reputation: 14655

Visiting localhost/properties is explicitly saying that you want to invoke PropertiesController. If you mean you want that to be your default route, then you need to change your route config to the following:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Properties", action = "Index", id = UrlParameter.Optional }
);

That would allow you to invoke it directly from localhost. However, it sounds as though you are missing the .cshtml file. Have you made sure ~/Views/Properties/Index.cshtml exists?

Upvotes: 2

Whit Waldo
Whit Waldo

Reputation: 5207

In your Global.asax.cs file, have you registered the routes? For example:

RouteConfig.RegisterRoutes(RouteTable.Routes);

Upvotes: 2

Related Questions