Setting the default route for MVC site on IIS 8 - asp.net-mvc

I've setup a site on our webserver using IIS8. The URL is something link ABC.mycompany.com. When I go to ABC.mycompany.com, I get a not found error:
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: /
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929
If I go to ABC.mycompany.com/Home/InstrumentList, it shows the the correct page I want to start on. How do I get it to start at this route?
In Visual Studio 2013, I have Home/InstrumentList set as my start action and that works fine. I've looked at several examples where they reference default and index pages, but my application doesn't have any of these. Also, there are references to .aspx pages, but there are no .aspx pages in my app, just .cshtml Views and .cs Controllers. I also have seen things about adding routes, but I'm unsure where to put them in global.asax.cs (in ApplicationStart? outside it? in a different method? just alone?). I also don't know what to change to work for mine (change index to InstrumentListing or leave it alone). Nothing has worked for me so far.
Here's one of my attempts using global.asax.cs where I tried to add a register route method:
namespace GPC
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{Filtre}",
new { controller = "Home", action = "Index", Filtre = UrlParameter.Optional });
}
}
}
Here are some of the sites I've used, but nothing has worked for me:
http://weblog.west-wind.com/posts/2013/Aug/15/IIS-Default-Documents-vs-ASPNET-MVC-Routes
cannot set Default route for MVC project
http://weblogs.asp.net/imranbaloch/editing-routes-in-mvc
I'd appreciate if someone could show me how to get ABC.mycompany.com/Home/InstrumentList to show when the user goes to ABC.mycompany.com.

I'm not sure, but your RegisterRoutes method should be in RouteConfig class that by default should be in App_Start foulder of MVC project. This is not a method in MvcApplication class that located in Global.asax.cs as i see in your question.
Then you should only change RegisterRoutes method like this to set different default controller action:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{Filtre}",
new { controller = "Home", action = "InstrumentList", Filtre = UrlParameter.Optional });
}

Related

Web API Attribute Routing in MVC area not working

I have an existing MVC project. I added a new area and this area will be web api. My web api routes are not being hit and since routing is still a frustrating thing for me I'm sure I'm doing something wrong.
In my route provider I thought this was all I had to do...
public void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();
}
In my controller:
[RoutePrefix("api/nav")]
public partial class NavigationController : ApiController
{
[HttpGet]
[Route("MainDash")]
public DashboardModel GetDashItems()
{ ...}
}
My MVC area is defined as MyArea,
So in fiddler the following Get request return 404.
/MyArea/api/nav/MainDash
/api/nav/MainDash
Do I still have to define old fashioned conventional routes as well?
When I register my route I do set a default template...but the attribute routing should override...???
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"MyArea_default",
"MyArea/{controller}/{action}/{id}",
new {controller="Home", action = "Index", area = "MyArea", id = "" },
new[] { "Testing.Nav.Controllers" }
);
}
I really don't think this has anything to do with it but I am at a loss for getting my routes figured out.
TIA
Update
Forgot this controller is also NOT in the controllers folder. It is in a folder called Api.
I tried /api/api/nav/GetDashIyems but still didn't work. But I wonder do I need to add the Api folder to the route table as an area to search...???

Glimpse doesn't work with Areas

I'm new to Asp.Net MVC, due to some issues I've been having with Routes I discovered Glimpse and thought I'd give it a go, but I couldn't get the Glimpse.axd config page up, constantly getting a HTTP 404.
I made a new project and tried that, it worked fine. Through trial and error I eventually found that the problem is in the AreaRegistration file for my areas, if I do this:
context.MapRoute(
"SomeArea_default",
"Area/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
It works, I can get to the page, but if I leave out the area part
context.MapRoute(
"SomeArea_default",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
then it doesn't.
I have previously asked whether that part was optional and I thought it was:
Area routing, why is the area name needed?
I'm putting it back in to get things working, whats the actual reason behind this? Should that always be there or is this a Glimpse bug?
What you are describing is actually normal behavior and has everything to do with the order in which routes are being registered.
Let me explain it, based on a green field project as the one you created to pinpoint the problem.
When you create a new MVC project and you add a Test area for instance, then you'll find the following types and methods inside your project:
A TestAreaRegistration class defined as:
public class TestAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Test"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Test_default",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
An Application_Start method inside your global.asax defined as:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
A RouteConfig class inside the App_Start folder defined 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 }
);
}
}
Now it is just a matter of reading through the startup code with regards to registering the routes for the application:
First the areas are being registered AreaRegistration.RegisterAllAreas();
That call will result in TestAreaRegistration.RegisterArea(...) being called which will register the route Test/{controller}/{action}/{id}
Then the call to RouteConfig.RegisterRoutes(RouteTable.Routes) will be made which will register the default {controller}/{action}/{id} route and also registers a route to ignore .axd requests.
now it is important to keep in mind that first all routes defined by the Test area will be checked and then the ones defined by the RouteConfig in case it is not a Test area related route
Now what does this mean when you request /glimpse.axd with this default setup ?
The route that will match is the route that is ignored inside the RouteConfig because the routes that will be handled by your Test area must start with Test/ which is clearly not the case for /glimpse.axd
but if you remove the Test/ part from the Test/{controller}/{action}/{id} route registration inside the Test area registration, then the route that will match the /glimpse.axd request will now be handled by the routes defined by the Test area as it will basically act as a catch all, and since it will not find a match a 404 is returned.
TL;DR
Now you can solve this in 2 ways:
Add context.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); to the top of the TestAreaRegistration.RegisterArea method and the route will be ignored like it is in the default situation
Switch the AreaRegistration.RegisterAllAreas(); with the RouteConfig.RegisterRoutes(RouteTable.Routes) so that the RouteConfig routes will be matched first
Personally I would go for option 1 as it has the least impact.

Attribute Routing not working in areas

Scenario: I have a Forms area in my ASP.NET MVC 5 site.
I'm trying to redirect to the Details Action which uses a custom route defined using the new Attribute Routing feature.
The RedirectToAction:
return RedirectToAction("Details", new { slug });
The action I'm redirecting to:
[HttpGet]
[Route("forms/{slug}")]
public ActionResult Details(string slug)
{
var form = FormRepository.Get(slug);
...
return View(model);
}
I would expect a redirect to http://localhost/forms/my-slug but instead the app is redirecting me to http://localhost/Forms/Details?slug=my-slug.
This means that the attribute routing is not working.
How can this be solved?
I have added the routes.MapMvcAttributeRoutes(); line to my RouteConfig:
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 }
);
}
}
And here's my Application_Start():
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
You are probably combining convention based routing with attribute routing, and you should register your areas after you map the attribute routes.
The line
AreaRegistration.RegisterAllAreas();
should be called AFTER this line:
routes.MapMvcAttributeRoutes();
The explanation (from https://devblogs.microsoft.com/aspnet/attribute-routing-in-asp-net-mvc-5/):
If you are using both Areas with route attributes, and areas with convention based routes (set by an AreaRegistration class), then you need to make sure that area registration happen after MVC attribute routes are configured, however before the default convention-based route is set. The reason is that route registration should be ordered from the most specific (attributes) through more general (area registration) to the mist generic (the default route) to avoid generic routes from “hiding” more specific routes by matching incoming requests too early in the pipeline.
When you create a blank asp.net mvc website, add an area and start using attribute routing, you will encounter this problem because the "Add Area" action in visual studio adds the RegisterAllAreas call in your Application_Start, before the route configuration..
Alternative solution
Perhaps you do not intend to keep using convention based routing and prefer to only use attribute routing.
In this case you can just delete the FormsAreaRegistration.cs file.
Moving the AreaRegistration.RegisterAllAreas() to RouteConfig.cs wasn't enough for me. I also needed to use the AreaPrefix parameter for the RouteArea attibute:
//Use the named parameter "AreaPrefix"
[RouteArea("AreaName", AreaPrefix = "area-name-in-url")]
[RoutePrefix("controller-name-in-url")]
public class SampleController : Controller
{
[Route("{actionParameter}")]
public ActionResult Index(string actionParameter)
{
return View();
}
}
Edit: At some point, I came across a sample solution from Microsoft that nicely showed how to handle attribute routing. It also showed some nice examples of how to translate a SelectList into an array of input[type="radio"] items as well as doing the same with an array of input[type="checkbox"] items (if I recall). This sample solution is probably a better answer to this question--as well as giving some good examples on displaying radio buttons and checkbox items. If anyone knows of this sample solution, please add a comment with a link to it.

Can't access (404) ASPX from a View directory while HTML and (normal) ASPX are accessible

I can access Ping.HTML and Ping.ASPX but when I try to access the view from my MVC (4.0) project (deployed to the same server, the bogus one, by F5), I get 404.
It's a vanilla project created from the template for MVC 4 with a very default view and controller (no model).
Hints on how to resolved it? I'm out of ideas...
EDIT
My RouteConfig.cs is like this
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 }
);
}
}
Controllers folder contains only one, single file called ÄDefault1Controller.cs*. It only does this:
public class Default1Controller : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
return View();
}
}
EDIT
The exact URLs typed in (besides the server name alone, of course) are:
> http://localhost:49642/Index
> http://localhost:49642/Index.aspx
> http://localhost:49642/Home/Index
> http://localhost:49642/Home/Index.aspx
> http://localhost:49642/Default/Index
> http://localhost:49642/Default/Index.aspx
Based on the information you've given, it sounds like a routing problem. The URL you are requesting isn't firing a controller.
EDIT
MVC works by convention, so by naming your controller Default1Controller the matching URL would start with /Default1.
In the example you've given, you can only access the Test() method by navigating to http://localhost:49642/Default1/Test, which will return the view typically located at /Views/Default1/Test.aspx (or /Views/Default1/Test.cshtml for razor-based views).
Please check out the routing overview at ASP.NET for more information about how the route table maps to controllers and actions. I should point out that the link is for the older versions of MVC, but you should get the idea.
Let me know if I can help further.
Matt

ASP.Net MVC 4. Routing a controller in a separate assembly returns error 404

I am trying to perform what looks like a straightforward task - calling a controller from a separate assembly in my project.
However, when I requesting information from that controller I'm getting error 404. I have been fighting with it for last 5-6 hours and I suspect that I may be missing something small and obvious, that is why I hope for an advise.
I found on stakoverflow similar question about routing and error 404, but as I implemented another prototype project where I didn't get such error and use a similar code structure, I believe that the problem they describe is different from mine.
For a general picture - the overall goal of what I want to achieve is implementing an area inside an independent project like it is described here.
I did everything like it is explained in the link for a small prototype (and it works perfectly) and now trying to apply for the real project.
This is how I include an assembly and manage routes:
There is a main project with one of the Areas representing a hidden child project "CommunicationBus"
"CommunicationBus" project contains a class "CommunicationBusAreaRegistration". Registering a route works correctly, I can get here with debugger and also I can see this route when I use routedebugger (see screenshot below). I also played with namespace for this class, tried to add .Areas.CommunicationBus in the end, but it didn't make any difference I could notice.
namespace MBVD.MainProject.UI
{
public class CommunicationBusAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "CommunicationBus";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"CommunicationBus_default",
"CommunicationBus/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "CommunicationBus.Controllers" }
);
}
}
}
In the Global.asax of the main project I register routes the following way:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "MBVD.MainProject.UI.Controllers" }
);
}
If I reference here "CommunicationBus.Controllers", I can no longer open pages of the main application. However, I believe I need to register here only path to the controllers of the main application
Output path for CommunicationBus project is set to bin folder of the main project. Every time I build CommunicationBus I get a fresh .dll in the main project.
I added a simple controllers to the CommunicationBus project:
namespace CommunicationBus.Controllers
{
public class TestController : Controller
{
[HttpGet]
public string Index()
{
return "It works!";
}
}
}
I added a link to the main project
#Html.ActionLink("test","Index","Test", new {Area="CommunicationBus"}, null)
which is:
localhost:63254/CommunicationBus/Test
I use routedebugger and it doesn't show anything suspicious:
I use ASP.NET MVC 4 for both projects.
I would appreciate any ideas on what I can do to figure out why I'm getting this error.
I believe you are getting this error because of your routing order. Since /CommunicationBus/Test matches both /{controller}/{action}/{id} and /CommunicationBus/{controller}/{action}/{id} the first registered route (/{controller}/{action}/{id}) is taking precedence over the desired route, and MVC can't find a controller in the default namespace (MBVD.MainProject.UI.Controllers) called CommunicationBus.
Try registering your Area routes before your default route. Or, you can just skip that business all together and use Attribute Routing (http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx). If you go with Attribute Routing, you will need to ensure you are loading controllers from all namespaces before calling routes.MapMvcAttributeRoutes(); (if you are just including as a reference, this is no problem, it only becomes an issue if you are dynamically loading the reference).

Resources