Does ASP.NET MVC create default routes for areas - asp.net-mvc

I have a couple of areas in my MVC 3 application Auth and Users. I am using Phil Haacks Route Debugging tool to view a list of my routes and see which one gets selected based on my url.
However there are a couple of routes present that I have not created in either my AreaRegistration file or Globalasax and I don’t know where they have come from or how to get rid of them. The routes are highlighted in yellow below.
You can also see that I have created a default route in my Auth area (highlighted in green) which simply points to the Login action of my Auth controller. I have debugged the RouteTable and it gets added when the AreaRegistration.RegisterAllAreas(); method is called. However it does not get added in the AreaRegistration as have stepped through this also.
Does ASP.NET MVC add this as a default and if so can I remove it somehow?

I don’t like to answer my own question but after a day of trying to solve this problem I thought I would post the answer in case anyone else has the same issue.
In the end I got rid of all my areas from my application and just had the basic Global.asax routing. When I ran the app I could see in the route debugger that the routing collection was still being populated with the routes from now non existing areas. After trying many things including deleting everything from my ASP.NET temp files, messing around with IIS AppPools and cleaning out browser data I finally came across the answer.
I deleted everything from the websites bin folder, did a rebuild and low and behold, the routes were gone. I reinstated my areas with the config described and everything is working as it should.
I have no idea why my MVC app was holding onto and populating the old routes but as soon as my bin was cleared and new dll’s created everything worked as it should. If anybody out there knows why this may be then I would be very interested.

Yes, each area has it's own AreaRegistration file that defines area routes. Look for it in your area root folder.
For your User area, look in Areas -> User -> UserAreaRegistration.cs
It should contain something like this:
public class UserAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "User";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"User_default",
"User/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}

Did you rename your project? It loads the routes by reflection, probably by scanning everything in the bin folder. So if you refactored your code and changed the assembly name, you could have easily had old code being picked up and registering those routes.
JB

Related

How to see all the views in mvc application

I added a default MvcApplication (MVC 4) (its name is MvcApplication3 matching the name of my solution's) width Home views (About, Index, Contact) and that will be my startup (bold in VS solution explorer's interface) project. Then I added another project (MvcApplication, but this time an empty one) called MvcApplication2 to the solution. Then I added the latter project as a reference to the first. I also added a controller called TestController (green line) to the referenced project and generated a view for its Index (red arrow) method. However, when I go to a link /Test or /Test/Index, the view I am expecting (red arrow) is not shown. Then I added the same folder Test with Index.cshtml (blue arrow) to the main project and now I am seeing its contents rather than the project's where my controller sits in.
Is it possible to make the application look for the views in the other project rather than the startup one?
I am adding the image of the structure to make it easier to follow.
P.S.: probably related: the breakpoint IS being hit in the Index method of TestController.
tldr; blue view is used instead of a red one
I think your problema is that you have set MvcApplication3 as startup Project and is causing you to open the view off that Project.
Is it possible to make the application look for the views in the other
project rather than the startup one?
Yes its posible, you can redirect your application the url. Think this your application have a url http://localhost:(someport) you can set redirect to the port of the second application.
I put a link to for better understanding a routing system of MVC: Documentation of routing system
As far as I know, you can't link to projects together like that. Each project becomes its own website with its own address. The reason you might put multiple projects together in one solution is to share things like classes, services, etc. I think what you're needing is areas:
http://www.codeproject.com/Articles/714356/Areas-in-ASP-NET-MVC
With some ideas from me and a friend of mine and a link about overriding RazorViewEngine I finally got what I wanted working exactly how I was expecting it to:
I created a folder named ViewsBase in the main project.
I rewrote RazorViewEngine this way: I only changed the place that was needed for me, leaving everything else like I found in the constructor of RazorViewEngine:
public class MyCustomViewEngine : RazorViewEngine
{
public MyCustomViewEngine()
{
...
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml",
"~/ViewsBase/{1}/{0}.cshtml",
"~/ViewsBase/{1}/{0}.vbhtml"
};
...
(I find it rather disturbing how I am unable to format the code properly. Can someone give me a hand please?)
and in Global.asax of the main project I added:
ViewEngines.Engines.Clear();
var ourViewEngine = new
ViewEngines.Engines.Add(ourViewEngine);
AreaRegistration.RegisterAllAreas();
...
I added a post-build event command:
xcopy /s "$(ProjectDir)Views\*.*" /Y "$(SolutionDir)$(SolutionName)\ViewsBase\"
It started looking for the views in the expected order
I added a ViewStart file to the base project to make it render the Layout too.

ASP.NET MVC AttributeRouting doesn't generate any route

I installed AttributeRouting via nuget, for an ASP.NET MVC 4 project, in which previously I mapped routes lowercase with a MapRouteLowercase extension, but I don't really think this could be causing the problem, because when I disabled my older route mappings in Global.asax, the attribute based routes were still not working.
[GET("Sample")]
public ActionResult Aszadba()
{
... do whatever
}
But when I check the routes.axd, the route is not present, nor it is working : (
Didn't touch any of the basic configurations that the package made at install. If I put a breakpoint into the AttributeRoutingConfig class it gets hit, so it seems the mapping function is called properly.
I also tried mapping with the [Route("Lofasz",HttpVerbs.GET)] format, without success.
Any help or hint would be appreciated!
I believe you need to use the latter [Route(Directory/Page)] attribute syntax, although I haven't seen the Get attribute before and it may be a valid alternative.
Crucially you need to add-
routes.MapMvcAttributeRoutes();
To your RouteConfig.cs file before your first mapped rotue.

MVC view throwing 500.19 error when using the direct url, but not when routed via the controller?

I have two views in my mvc application. They are both stored within area, A, and within folder, home.
I recently was changing the properties of my project and it asked to reconfigure my site configs in iis as always I clicked yes. Since then I have been getting a 500.19 error saying that my configuration file has incorrect data.
At this point I was thoroughly confused. I compared my web.configs against other application web.configs and there really was no difference. So, I then changed my routing so that inputting this. :
http://stackoverflow/myarea/home
Actually returns my view of. :
http://stackoverflow/myarea/home/index
So, when I just input. :
http://stackoverflow/myarea/home/index => this errors with 500.19
but when I use. :
http://stackoverflow/myarea/home => this works with no error but brings up the same view as the above would
I have tried a lot of things blowing away my application in iis and recreating it, numerous iis resets, deleting my view and recreating it. Nothing has came close to working.
Now what is really odd is I have another view in the same folder. :
http://stackoverflow/myarea/home/myotherview
When I go directly to this url above it works perfectly no issues, no 500.19.
So, it is as if something is tying my one view to this issue. I know that this is an odd one, but I am lost on what to try next. Hoping someone has seen something like this before. I know a 500.19 is usually an issue within the web.config, but after the other page works I think it is some sort of setting I am just unaware of.
500.19 is a configuration issue.
See here http://blogs.msdn.com/b/webtopics/archive/2010/03/08/troubleshooting-http-500-19-errors-in-iis-7.aspx
I suspect that you do not have the routes in the global.asax or in the areas registration asax file setup properly. Without seeing your routes I cannot help you more specifically. But you might need to setup something like this in
public static void RegisterRoutes(RouteCollection routes)
routes.MapRoute(
"DefaultIndexRoute",
"{controller}/{action}/{id}",
new {controller = "Home", action="Index", id=UrlParameter.Optional}
);
}
in the AreaRegistrations.asax file it will be
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"DefaulAreatIndexRoute",
"MyArea/{controller}/{action}/{id}",
new {controller = "Home", action="Index", id=UrlParameter.Optional},
new [] {"My.Area.Namespace.Controllers"} // optional namespace in case there is a conflict
);
}
this is a catch-all kind of route. MVC will choose your route based on the first one that matches. So you will want this at the bottom of the list most likely. With more specific routes specified above it.
Basically if mvc cannot find an adequate route it will throw it back to IIS to figure out in which you will most likely get an error.
Please post your route configs so we can help you a bit more. Thanks.

T4MVC not picking up the Views in Areas (ASP.NET MVC 3 RTM)

T4MVC is working fine everywhere except in Areas.
In Areas, it picks up the Controllers and the Actions, but not the Views.
So, I cannot write, in my controller:
return View(MVC.MyArea.MyController.Views.MyView);
Outside of the Areas, I CAN write:
return View(Views.MyOtherView);
I can also refer to actions in my area controllers:
MVC.MyArea.MyController.MyAction()
In other words:
a. I can get anything I want, if it is not in an Area.
b. I can get at the Actions in my Area controllers.
c. But I CANNOT get my Views in my Area.
What could the problem be?
TIA
EDIT:
The issue is getting T4MVC to rerun (see David Ebbo's answer and my "answer").
What you have should work, and I verified it by:
Creating a new MVC3 app and adding the latest T4MVC 2.6.40 (via nuget)
Adding an Area named MyArea
Adding a controller named MyController
Adding a view named MyView
Make sure you rerun the T4MVC.tt custom tool
After that, I'm able to write:
namespace Mvc3Application.Areas.MyArea.Controllers {
public partial class MyController : Controller {
public virtual ActionResult Index() {
return View(Views.MyView);
}
}
}
or
namespace Mvc3Application.Areas.MyArea.Controllers {
public partial class MyController : Controller {
public virtual ActionResult Index() {
return View(MVC.MyArea.My.Views.MyView);
}
}
}
Note that in the second case, the token in 'My' instead of 'MyController', which is the way it always works.
Please try following those steps in a clean app to see if it works.
I believe my issue is being caused by T4MVC not rerunning. As a result (I speculate) the T4MVC does not update to reflect changes in your project. For example, changing the parameters of an Action in a Controller. Or (specific to this question) adding a new View.
The T4MVC documentation on getting itself to rerun is vague, but points you at a VS add in called Chirpy.
Chirpy installs, and then you have to go in an configure it. You do this by opening Visual Studio, then going to Tools >> Options and choosing the Chirpy option.
See the image:
I had to add the template name T4MVC.tt bit to get it to work. Not sure if this is necessary or why. But it all now works fine.
If there is a better way of doing this, please let me know.

The view 'Index' or its master was not found.

The view 'Index' or its master was not found. The following locations were searched:
~/Views/ControllerName/Index.aspx
~/Views/ControllerName/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
I got this error when using ASP.Net mvc area. The area controller action are invoked, but it seems to look for the view in the 'base' project views instead of in the area views folder.
What you need to do is set a token to your area name:
for instance:
context.MapRoute(
"SomeArea_default",
"SomeArea/{controller}/{action}/{id}",
new { controller = "SomeController", action = "Index", id = UrlParameter.Optional }
).DataTokens.Add("area", "YOURAREANAME");
This error was raised because your Controller method name is not same as the View's name.
If you right click on your controller method and select Go To View (Ctrl+M,Ctrl+G), it will either open a View (success) or complain that it couldn't find one (what you're seeing).
Corresponding Controllers and View folders name have the same names.
Corresponding Controller methods & Views pages should same have the same names.
If your method name is different than view name, return view("viewName") in the method.
Global.asax file contain the URL Route.
Default URL route like this.
"{controller}/{action}/{id}"
So,Try this.
1. Right click your controller method as below.
Example: let say we call Index() method.Right click on it.
2. Click Add View.. and give appropriate name.In this example name should be Index.
Then it will add correct View by creating with relevant folder structure.
Check the generated code at MyAreaAreaRegistration.cs and make sure that the controller parameter is set to your default controller, otherwise the controller will be called bot for some reason ASP.NET MVC won't search for the views at the area folder
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"SomeArea_default",
"SomeArea/{controller}/{action}/{id}",
new { controller = "SomeController", action = "Index", id = UrlParameter.Optional }
);
}
Where this error only occurs when deployed to a web server then the issue could be because the views are not being deployed correctly.
An example of how this can happen is if the build action for the views is set to None rather than Content.
A way to check that the views are deployed correctly is to navigate to the physical path for the site on the web server and confirm that the views are present.
The problem was that I used MvcRoute.MappUrl from MvcContrib to route the context.Routes.
It seems that MvcContrib routing mapper was uncomfortable with area routing.
You most likely did not create your own view engine.
The default view engine looks for the views in ~/Views/[Controller]/ and ~/Views/Shared/.
You need to create your own view engine to make sure the views are searched in area views folder.
Take a look this post by Phil Haack.
I had this problem today with a simple out of the box VS 2013 MVC 5 project deployed manually to my local instance of IIS on Windows 8. It turned out that the App Pool being used did not have the proper access to the application (folders, etc.). After resetting my App Pool identity, it worked fine.
right click in index() method from your controller
then click on goto view
if this action open index.cshtml?
Your problem is the IIS pool is not have permission to access the physical path of the view.
you can test it by giving permission. for example :- go to c:\inetpub\wwwroot\yourweb then right click on yourweb folder -> property ->security and add group name everyone and allow full control to your site . hope this fix your problem.
It´s still a problem on the Final release.. .when you create the Area from context menu/Add/Area, visual studio dont put the Controller inside de last argument of the MapRoute method. You need to take care of it, and in my case, I have to put it manually every time I create a new Area.
You can get this error even with all the correct MapRoutes in your area registration. Try adding this line to your controller action:
If Not ControllerContext.RouteData.DataTokens.ContainsKey("area") Then
ControllerContext.RouteData.DataTokens.Add("area", "MyAreaName")
End If
If You can get this error even with all the correct MapRoutes in your area registration and all other basic configurations are fine.
This is the situation:
I have used below mentioned code from Jquery file to post back data and then load a view from controller action method.
$.post("/Customers/ReturnRetailOnlySales", {petKey: '<%: Model.PetKey %>'});
Above jQuery code I didn't mentioned success callback function.
What was happened there is after finishing a post back scenario on action method, without routing to my expected view it came back to Jquery side and gave view not found error as above.
Then I gave a solution like below and its working without any problem.
$.post("/Customers/ReturnRetailOnlySales", {petKey: '<%: Model.PetKey %>'},
function (data) {
var url = Sys.Url.route('PetDetail', { action: "ReturnRetailOnlySalesItems", controller: "Customers",petKey: '<%: Model.PetKey %>'});
window.location = url;});
Note: I sent my request inside the success callback function to my expected views action method.Then view engine found a relevant area's view file and load correctly.
I have had this problem too; I noticed that I missed to include the view page inside the folder that's name is same with the controller.
Controller: adminController
View->Admin->view1.cshtml
(It was View->view1.cshtml)(there was no folder: Admin)
This error can also surface if your MSI installer failed to actually deploy the file.
In my case this happened because I converted the .aspx files to .cshtml files and visual studio thought these were brand new files and set the build action to none instead of content.
I got the same problem in here, and guess what.... looking at the csproj's xml' structure, I noticed the Content node (inside ItemGroup node) was as "none"... not sure why but that was the reason I was getting the same error, just edited that to "Content" as the others, and it's working.
Hope that helps
Add the following code in the Application_Start() method inside your project:
ViewEngines.Engines.Add(new RazorViewEngine());
I added viewlocationformat to RazorViewEngine and worked for me.
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
"~/Areas/Admin/Views/{1}/{0}.cshtml",
"~/Areas/Admin/Views/Shared/{0}.cshtml"
};

Resources