1

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!

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
Matthew Hudson
  • 1,306
  • 15
  • 36
  • 5
    Do you have PropertiesController controller, Index action in it and a Views/Properties/Index.cshtml view? – LINQ2Vodka Nov 04 '13 at 12:48
  • @jim Yes I have all of them, and it works fine when hosted on a local IIS, just not the Visual Studio internal/debugging IIS. – Matthew Hudson Nov 04 '13 at 13:18
  • Make sure the port number in your URL is the same as your internal IIS currently working at. – LINQ2Vodka Nov 04 '13 at 13:21
  • Would you mind editing your question to include the relevant controllers and views, so we can take a look? – John H Nov 04 '13 at 13:23
  • @JohnH looks like development IIS server settings or URL error – LINQ2Vodka Nov 04 '13 at 13:24
  • @jim It could well be, but having the code for the controllers and views would allow us to eliminate that portion of the problem entirely. – John H Nov 04 '13 at 13:25
  • @John H I have updated my Question. Still no further to solving it. And even with an explicit route defined, it still ignores it. – Matthew Hudson Nov 06 '13 at 09:22

5 Answers5

3

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.

Community
  • 1
  • 1
Matthew Hudson
  • 1,306
  • 15
  • 36
2

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.

LINQ2Vodka
  • 2,996
  • 2
  • 27
  • 47
  • It is my understanding that [localhost]/Properties should route to the Index action of the Properties controller. However I recieve a 404 Server error unless I manually add /Index to the URL – Matthew Hudson Nov 04 '13 at 15:30
2

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

RouteConfig.RegisterRoutes(RouteTable.Routes);
Whit Waldo
  • 4,806
  • 4
  • 48
  • 70
  • +1: Actually, I think this is right. If the view was missing, it would give that error listing the locations of where it's searched. – John H Nov 04 '13 at 13:02
  • Yes it is, RouteConfig.RegisterRoutes(RouteTable.Routes) is line 23 in root Global.asax. – Matthew Hudson Nov 04 '13 at 13:19
2

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?

John H
  • 14,422
  • 4
  • 41
  • 74
  • No I want Home to be my default controller. Properties is another controller. I have a @Url.Action("Properties", "Index") which generates [Localhost]/Properties/. But when I click on that link it cannot find the page, as it is ignoring the routing for the Index action. – Matthew Hudson Nov 04 '13 at 13:21
  • @MatthewHudson what exact link is displayed on that href in browser? – LINQ2Vodka Nov 04 '13 at 13:33
  • @MatthewHudson I can't think of much else, but have you accidentally decorated your `PropertiesController.Index` action with `[HttpPost]`, or something similar? – John H Nov 04 '13 at 13:40
  • @jim http://[localhost]:53909/Properties is the link it creates, and that which returns a 404 Server error. However if I manually add /Index then it works completely fine. – Matthew Hudson Nov 04 '13 at 15:27
  • @JohnH No this is an empty project. All I've added is an EDMX and Properties Controller w/ Default MVC actions. – Matthew Hudson Nov 04 '13 at 15:28
1

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.

EfrainReyes
  • 1,005
  • 2
  • 21
  • 55