I have problem with one area in my project called 'Reports'. I always get 404 error when I try to access some controller from this Area. This problem only occurs when I run my application on local IIS (Windows 8.1). On other machine (windows 7 and local IIS) everything is ok. Even on this windows 8.1 machine, but IIS Express everything is working well.
I was trying to clear temp files, but no resuls.
Areas are registed such like this:
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
And in Global.asax, Application_start() method:
AreaRegistration.RegisterAllAreas();
I dont know where could be the problem. Do you have any ideas?
Check event viewer. I had this problem and the 'Reports' URL was a virtual directory having to do with SQL Server Reporting Services.
Try this:
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_main",
"Reports/{controller}/{action}/{id}",
new { area = "Reports", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
The Reports_default routing rule sets Index to be the default action for a given controller.
You need to add another Reports_main rule that will set a default controller when you access the root of the area e.g. /Reports. In this rule I assume that the default controller is Home but you can change that to fit your project.
The default AreaRegistration scaffold by Visual Studio does not include a default for controller, meaning that providing a controller in the URL is required.
/Reports/Home // This works (if you have a home controller)
/Reports // This doesn't work
To make the controller optional, you need to provide a default.
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
// Note that controller is defaulted to Home
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Note also that the order in which routes are registered is the same that they will be executed for the entire application. Typically, this means that you must call AreaRegistration.RegisterAllAreas() before you call RouteConfig.RegisterRoutes(RouteTable.Routes).
The answer provided by Tasos will also work, but is incorrectly configured:
Specifying a default area within an AreaRegistration is redundant and unnecessary.
Reports_default in his example is an unreachable execution path, which makes it also redundant and unnecessary.
Related
I tried to access the session-value by using the ActionFilterAttribute in .NET CORE. Therefore i use the following code:
A normal .NET Core Controller which gets the annotation [SessionCheck].
[SessionCheck]
public class HomeController : Controller
{
}
These class is extended by the ActionFilterAttribute Class and overrides the OnActionExecuted Method, where i would like to access the session value. Is there a possibility? I could only access the Key but not the session value.
public class SessionCheck:ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
var session = context.HttpContext.Session;
//var mySessionValue = session["user"];
}
}
My main problem is, that i have a session value which describes where i have to route my request. If there is a special value in, i would like to route my request to Location A, otherwise to Location B.
Is there another possibility to do that?
I have same issue, you can do something like below:
filterContext.HttpContext.Session.GetString("user");
public class SessionCheck : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
{
if (actionExecutingContext.HttpContext.Session.GetString("user") == "User One")
{
actionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "LocationA Controller",
action = "LocationA Action",
returnurl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetEncodedUrl(actionExecutingContext.HttpContext.Request)
}));
}
else
{
actionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "LocationB Controller",
action = "LocationB Action",
returnurl = Microsoft.AspNetCore.Http.Extensions.UriHelper.GetEncodedUrl(actionExecutingContext.HttpContext.Request)
}));
}
}
}
Write SessionCheck class as above you can set your special value by typing HttpContext.Session.SetString("user", "User One"); in where you want to set also you can use multiple if-elseif like the same, This is working in .Net Core 3.1.
I have a bit of problem
I have an MVC site that is working just fine.
I wanted to have SEO friendly urls so I created custom routing that looks like this
{section}/{group}/{manufacturer}
since it has the same number of fields as the default route
{controller}/{action}/{id}
i created in loop in RouteConfig.cs that goes to database and loops Sections table and creates custom routes like
FOOD/{group}/{manufacturer}
SPORT/{group}/{manufacturer}
CARS/{group}/{manufacturer}
and point it to the Sections controller.
It works just fine. The problem I have is that now i need to rename FOOD to FRESH-FOOD and i want to keep old links to FOOD working.
What would you recommend ? How can I solve this ?
Is there a better way to do route Section instead of custom routes ?
Sounds like this might be a good case for a custom route handler. In the ProcessRequest method below you can check for controller name of "FOOD" and redirect to "FRESH-FOOD" like this:
public class CustomRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new CustomHttpHandler();
}
}
public class CustomHttpHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
var routeValues = context.Request.RequestContext.RouteData.Values;
var controllerName = context.Request.RequestContext.RouteData.GetRequiredString("controller");
if (controllerName.ToLower() == "food") controllerName = "FRESH-FOOD";
var controller = ControllerBuilder.Current.GetControllerFactory().
CreateController(context.Request.RequestContext, controllerName);
if (controller != null)
{
controller.Execute(context.Request.RequestContext);
}
}
}
When you create your custom routes use the Route constructor overload that takes an IRouteHandler
I did see answers for similar issues, but none of them works for this situation.
I have MVC4 application with registered area called "Settings", with one "Manage"-controller. I also have folder in my web project with sources called "Settings", so the folder Structure is the following:
+ WebProjectFolder
+ Areas
+Settings
+Controllers
ManageController.cs
+ SettingsAreaRegistration.cs
...
+ Settings
+ SomeClasses.cs
ManageController is very simple:
public class ManageController : Controller
{
public ActionResult Index()
{
return Content("WORKS FINE!");
}
}
Area registration is also very simple:
public class SettingsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Settings";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.IgnoreRoute("Settings/{*pathinfo}");
context.Routes.RouteExistingFiles = false;
context.MapRoute(
"Settings_default",
"Settings/{controller}/{action}/{id}",
new {area = context.AreaName, controller="Manage", action = "Index", id = UrlParameter.Optional }
);
}
}
The problem:
http://mysite/settings - 404
http://mysite/settings/Manage - 404
http://mysite/settings/Manage/Index - 404
In case I remove line "context.Routes.IgnoreRoute("Settings/{*pathinfo}");"
Results are the following:
http://mysite/settings - 404
http://mysite/settings/Manage - WORKS FINE!
http://mysite/settings/Manage/Index - WORKS FINE!
Only If I remove/rename existing folder "Settings", then results are correct.
Similar situation with having controller named the same as folder.
How to make MVC ignore existing folder and always give priority to the Controller?
I think you wanted to set RouteExistingFiles to true.
context.Routes.RouteExistingFiles = true;
Excerpt:
true if ASP.NET routing handles all requests, even those that match an existing file; otherwise, false. The default value is false.
This is probably a duplicate to many but the obvious answers in them do not solve my problem.
I get:
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
App.Web.Controllers.HomeController
App.Web.Areas.Mobile.Controllers.HomeController
I've setup a default namespace for my HomeController in Global.ascx.cs:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new string[] { "App.Web.Controllers.HomeController" }
);
(Verified that App.Web.Controllers.HomeController is not a typo).
And also registered the Mobile's HomeController in MobileAreaRegistration:
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Mobile_default",
"Mobile/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Therefore, why is it that I still see the error message? I've built/cleaned and ran again. Still the same outcome.
This is how I register my routes:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
In your Global.asax route registration for obvious reasons replace:
new string[] { "App.Web.Controllers.HomeController" }
with:
new string[] { "App.Web.Controllers" }
That's a namespace constraint that you should use there, not a specific type.
I create a new area in my asp.net mvc 3 solution named admin. Visual studio automatically assign the names space:
MyApp.areas.admin.controllers
I change this to MyApp.admin.controllers
But it stops resolving the action.
Any help in this regard will be appreciated.
Thanks
You need to specify the new namespace when registering the route for your admin area.
In your \Areas\admin\adminAreaRegistration.cs file, you need to modify the RegisterArea() method as follows:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"admin_default",
"admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "MyApp.admin.Controllers" } // specify the new namespace
);
}