This post is directly related to: MVC5 Area not working
That post fixed the index.cshtml issue, however it did not resolve each view for that controller. For example:
http://localhost:45970/Setup/Start gives the error that the resource cannot be found (basically a 404).
However http://localhost:45970/Setup/Setup/Start brings up the correct page.
So what needs to be reconfigured so that ALL views for that controller in the Setup Area will open properly?
Edit 1
Code from SetupAreaRegistration.cs
using System.Web.Mvc;
namespace BlocqueStore_Web.Areas.Setup
{
public class SetupAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Setup";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Setup_default",
url: "Setup/{controller}/{action}/{id}",
defaults: new { action = "Index", controller = "Setup", id = UrlParameter.Optional },
namespaces: new[] { "BlocqueStore_Web.Areas.Setup.Controllers" }
);
}
}
}
Since you have an Area named Setup with the above route configuration, opening http://localhost:45970/Setup/Start will execute StartController under Setup Area. You got 404 error because you don't have StartController under Setup Area, but you can open http://localhost:45970/Setup/Setup/Start successfully because you have SetupController and Start action method under Setup Area.
Based on your comment, you want the following url patterns
http://{host}/Setup/{view}
http://{host}/Admin/{view}
You can accomplish that without using any Area. You only need AdminController and SetupController using the default route.
Related
I have developed a project in C# MVC with 'AdminLte' Template and I uses Areas for submodules.
when I access a link from home page (http://localhost:9760/Home/Index) the it works perfectly as follows http://localhost:9760/Manage/ChangePassword
but when I access the same link from Area ex: 'AirSurveillance' http://localhost:9760/AirSurveillance/Manage/ChangePassword it is not working and gives 404 error because it tried to find 'Manage' controller (which is not there) in 'AirSurveillance' area.
this is my auto-generated 'SecurityClearanceAreaRegistration.cs' file
namespace IIMS.Areas.SecurityClearance
{
public class SecurityClearanceAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "SecurityClearance";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"SecurityClearance_default",
"SecurityClearance/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
Please help me.
When using areas, your links will need to specify the area for the controller/action you're pointing to. If you want to use controllers outside of those areas you specify a blank Area. for example...
#Html.ActionLink("ChangePassword", "Manage", new { Area = ""})
When I try to make a new view in an area in MVC 6 it only displays a white page. The Home/Index action works fine, and this one will hit the controller but never displays the view. I can return content and get a display, but when I try to return the view it breaks. Any advice?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using PmData.Models;
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace PlantManagement.Areas.Cms.Controllers
{
[Area("Cms")]
public class AssetsController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
return View();
}
}
}
that is coupled with a blank view that calls to the main layout page.
I found the issue. Sadly, it's because I'm so new to MVC 6 / vNext so I feel silly. It was a matter of their being an issue with an item on the page, but without app.UseDeveloperExceptionPage(); being added in the configure of startup.cs it would never show me the actual error, just give me the generic 500 error and white page. Once I added that it started producing errors I could work with and gave me what I needed.
I had a similar issue, and resolved it by,
a) Create a _ViewStart.cshtml file in each area you have. i.e. Areas/Cms/Views/_ViewStart.cshtml
b) In this _ViewStart.cshtml file add
#{
Layout = "~/Areas/Cms/Views/Shared/_LayoutCms.cshtml
}
c) Add a _LayoutCms.cshtml to Areas/Cms/Views/Shared
d) In this file add the reference to the overall site layout
#{
Layout = "~/Views/Shared/_Layout.cshtml
}
and any other area specific layout code.
That fixed my blank page issue. Hopefully yours too
In addition to my last answer, try these steps
e) Make sure you have an area registration setup within your Cms area folder i.e Areas/Cms/CmsAreaRegistration.cs
public class CmsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Cms";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Cms_default",
"Cms/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
f) In your App_Start/RouteConfig.cs make sure you are registering all areas by adding AreaRegistration.RegisterAllAreas() something like the following.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
AreaRegistration.RegisterAllAreas(); //Add this//
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
My MVC application is set up with controllers at the root/global level. These have no explicit Area. I also have a single "Admin" area. URLs that begin with /admin/ are routed to the matching controller in the Admin area. Other URLs are routed to the matching global controller. This is working fine for the most part.
The issue I'm having is that in the case when a URL matches a controller in the Admin area when one of the same name doesn't exist on the global area, the request is incorrectly routed to the controller in Admin area. I know this is happening because I put a breakpoint on the matching action in the relevant controller.
For example, I have a controller called CalendarController in the Admin area. When I visit /admin/calendar, it works because it finds the action and the corresponding view in Areas/Admin/Views/Calendar/Index.cshtml. The problem occurs when I visit /calendar. I do not have a controller named Calendar at the root level, but for some reason it routes the request to the Admin area's CalendarController, which I don't want. I want it to return a 404 because no CalendarController exists at the root level. Instead, I get an error because it's searching for the view at the root level (at /Views/Calendar/Index.cshtml) even though the matching controller was in the Admin area.
How can I prevent the Admin area from being searched for matching controllers except when the URL has /admin in it?
Here's the relevant route code, which is basically stock except for the namespaces addition. The issue still happens without the namespace. There are more routes in the actual application, but I'm getting the same behavior in a brand new MVC project.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "AreaProblem.Areas.Admin.Controllers" }
);
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
What I mean by a controller at the "root level" is Controllers/HomeController in this screenshot. I want URLs that don't start with /admin to only look at those controllers. The problem is that it's also searching in Areas/Admin/Controllers.
So the MVC routing engine will look in different namespaces to try and find a matching controller. You can solve this by specifying a namespace (like you did for the admin area). You can also specify that a route not search other namespaces using DataTokens.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new [] { "AreaProblem.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;
I have one area called user.
The area configuration looks like this
context.MapRouteLowercase(name: "User_Member", url: "User/Member", defaults: new { controller = "User", action = "Member", id = UrlParameter.Optional });
When I browse to this page without passing in a id, it returns the view my url looks like this /user/member
When I type the following into the browser /user/member/1
I've put a break point on
var userId
and it gets hit and I check the id parameter and its 1 which is correct.
[HttpGet]
[Authorize]
public ActionResult Member(Int64 id = 0)
{
var userId = id != 0 ? id : ReturnUserId();
var model = _userProfileBusinessLayer.GetProfile(userId);
return View(model);
}
Yet when I press F5 I get the following page
Server Error in '/' Application.
The view 'member' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/user/member.aspx
~/Views/user/member.ascx
~/Views/Shared/member.aspx
~/Views/Shared/member.ascx
~/Views/user/member.cshtml
~/Views/user/member.vbhtml
~/Views/Shared/member.cshtml
~/Views/Shared/member.vbhtml
I'm unsure why I'm seeing that because all I have done is added /1 to the url?
I should be seeing the profile of the user which matches then id of 1, yet I remove /1 and it returns the view ?!?!?!?! slightly baffled
In your project, the area user should have a class that inherits from AreaRegistration e.g.
public class UserAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "user";
}
}
}
In that class you can define routes sepcific for that area:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"UserManagement",
"user/Admin",
new { controller = "UserAdmin", action = "Index" });
}
The file Global.asax.cs should have an Application_Start() method which calls:
AreaRegistration.RegisterAllAreas();
That will pick up the area routes you have configured. This is usually how area routes are configured. Do you have a similar setup for your project?
I have a basic project with areas in it, I have registered my routes in this area and have used a Lowercase URL extension. Here is the code:
using System.Web.Mvc;
using Web.Modules;
namespace Web.Areas.Services
{
public class ServicesAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Services";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRouteLowercase(
"Services", // Route name
"services/{controller}/{action}/{id}", // URL with parameters
new { controller = "Services", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new string[] { "Web.Areas.Services" }
);
}
}
}
But now when I go to http://localhost/services/home it shows me my HomeController's Index View, what can I do to fix this? I have already added the namespaces and added the area to the routedata.
Thanks for any assistance
Seems like you either don't have the folder Areas/Services/Views/Home at all or the Index view in that folder. In this case, ASP.NET MVC will fallback to displaying your Index view from the Views/Home (no area) folder. If you need a different view for your area, you need to create it in the area's Views/[Controller Name] folder (or the Shared folder, of course).