Page can’t be found error inside Areas controller Index - .net-core

I created this Area for the admin page (Areas/System) and an AdminController inside.
But when I tried to put the URL in the address as https://localhost:44361/System/Admin it didn't break inside the Index() function. And an error page shows "This localhost page can’t be found" even there's the Index.cshtml
On side note, this works well inside HomeController > Index() when you visit https://localhost:44361.
Below is the sample code for Areas/System AdminController.
[Area("System")]
[Route("System/[controller]/[action]")]
public class AdminController : BaseController
{
public IActionResult Index()
{
return View();
}
}

Sadly you haven't posted your Startup.Configure, more specifically app.UseMvc, but considering the fact that your HomeController/Index gets fired I think the issue might be there. Defining [Area("System")] should be enough, rest is implicit.
app.UseMvc(routes =>
{
//Order is important, most specific to least specific
routes.MapRoute(
name: "MyArea",
template: **"{area:exists}/**{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Bit more reading on areas and route configuration: https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas?view=aspnetcore-3.0#add-area-route

I guess I got the answer. I simply removed the Route attribute and it works.
[Route("System/[controller]/[action]")]

Related

Why is this ActionLink to another area not working?

I am testing how to build an action link to a page in another area, and every source I find says to use
Html.ActionLink("[Link Text]", "[action name]", "[controller]", new { area = "[areaName]" }, null)
except for one source I found which suggested
Html.ActionLink("[Link Text]", "[action name]",new { area = "[areaName]", controller = "[controllerName]" })
The problem is, neither of these work for me. In my MVC application I have an area called "Uploader", which contains its own Home controller, and Index page. So, in the main Index page of my MVC project, I create an ActionLink that looks like this:
#Html.ActionLink("Area Test", "Index", "Home", new { area = "Uploader" }, null)
If the link works correctly, I'll get taken to a page that reads "this is the uploader", the text on my area Index page, but instead, the main home/index page of my application just reloads.
The address I see in my browser after this reload is "https://localhost:44352/?area=Uploader".
The HomeController for the area is correctly formatted with an "Area" tag, like so:
namespace TestProject.Areas.Uploader.Controllers
{
[Area("Uploader")]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
I'm using .Net 5. What am I doing wrong?
Finally found the answer here. It turns out I had my area configuration backwards: the "default" route should come last.
It should be:
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
...instead of the other way around.

Redirecting a controller and action method to its URL

I have a project that I am working on that was done in ASP.NET MVC 5.
They used the default URL structure that comes standard with the framework. For example, the AGM page was constructed like this:
Controller: Home
Action method: AGM
Without any routing setup, to access this page, you would need to go to the following URL:
www.example.com/Home/AGM
This is the URL that they sent to the press. This URL looks horrible and I want to implement a cleaner URL structure which will look like this:
www.example.com/agm
I have set it up like this in the RouteConfig.cs file:
routes.MapRoute(
name: "AGM",
url: "agm",
defaults: new { controller = "Home", action = "AGM" }
);
What I want to achieve is if the user types in www.example.com/Home/AGM then it needs to display the URL like www.example.com/agm. Instead, it displays like www.example.com/Home/AGM.
I'm not sure how to implement this?
Configure routing and define action in the url
routes.MapRoute(
name: "AGM",
url: "{action}",
defaults: new { controller = "Home", action = "AGM" }
);
Then in the AGM method redirect to www.example.com/agm
if (Request.Path.ToLower() == "/home/agm")
{
return Redirect("/agm");
}
You can simply add [Route("AGM")] and [Route("Home/AGM")] top of your Action method:
[Route("AGM")]
[Route("Home/AGM")]
public IActionResult AGM()
{
return View();
}

What should be the naming convention and folder structure for Contact Us View Page in .NET Core MVC?

I have just started learning .NET Core MVC .I am creating a contact us view page .My doubt is should i create a structure where it is like this
1)
Views(folder)
-ContactUs(folder)
-Index.cshtml
Controller(folder)
-ContactUsController.cs
2)
Views(folder)
-Home(folder)
-ContactUs.cshtml
Controller(folder)
-HomeController.cs
3) This is similar to 1 just name change of cshtml file .Would like having a page as ContactUs.cshtml be better at seo rather than Index.cshtml?
Views(folder)
-ContactUs(folder)
-ContactUs.cshtml
Contorller(folder)
-ContactUsController.cs
Honestly from a 'code' point of view it doesn't matter. All the ways you've outlined above will work fine.
You will have the following URLs from them:
1 - /contactus
2 - /home/contactus
3 - /contactus/contactus
As you can see they will all work but you also need to consider things from an SEO point of view.
Ideally, you'd want a simple URL like /contactus to be used so in this case option 1 seems to be the best.
That said, you could still use option 2 or 3 but you would need to set up a Route in order to make the URL 'friendly'.
Something like this:
For example, in startup.cs for Option 2:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "contact",
defaults: new { controller = "Home", action = "ContactUs" });
template: "contactus");
});
says point yoursite.com/contactus to the home controller and the contactus action.
Note: Custom routes need to be placed before the default route.
The way MVC load views for each ActionMethod in a controller is following this order:
/Views/[Controller]/[ActionMethod].cshtml
/Views/Shared/[ActionMethod].cshtml
/Pages/Shared/[ActionMethod].cshtml
For example, for a controller:
public IActionResult View1()
{
return View();
}
public IActionResult View2()
{
return View();
}
The usual folder structure for this should be:
Now, in this specific case. The usual way to offer a ContactUs page, is making this one an ActionMethod of the HomeController, instead of creating an entire controller for it.

web api "get" method results in a view

I have a .net core 2.0 web api with the following get method:
[HttpGet]
public async Task<IEnumerable<Customer>> Get()
{
return await customerDataProvider.GetCustomers();
}
In the startup class i have the following in configuration:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
});
when i run the application i get the results displayed as raw json in the browser.
I would like to add a view and to handle the results in that view meaning display them in a table and add some filtering and sorting options.
How can i achieve this? I saw different articles on how to add a view or a razor page to a project but none of them was similar to my case..
Thanks!

MVC3 Routing Working 1 Direction Only

I am working on an ASP.NET mvc 3 site that contains several project entities, and then each project has several associated subpages, each that works with a component of the project.
So for instance, I could have a project with several photos, milestones, user info, etc. I have a Project Index view, as well as a Project Home which links to several component pages. Most of the components have two views, Index, and Edit/View.
So I set up a route for the edits and views. Note that my route is in an AREA called ProjectManagement
context.MapRoute(
"ProjectManagement_ProjectPageSingle",
"ProjectManagement/{controller}/{action}/{projectNumber}/{projectChildId}",
new { controller = "Project", action = "Home" }
);
and my controller actions all look similar to this:
public ActionResult Edit(string projectNumber, string projectChildId)
This works well and good when I type in the URL directly in the browser. For instance:
~/ProjectManagement/Milestone/Edit/39999P110175/1
however, when I generate an action link using:
<a href="#Url.Action("Edit", new { projectNumber = Model.Project.ProjectNumber, projectChildId = entry.Id})">
the action URL ends up looking like this:
~/ProjectManagement/Milestone/Edit/39999P110175?projectChildId=1
So the route sorta works...but the action link generator doesn't? Not sure where to go from here. Any advice would be much appreciated.
Note that the same thing occurs while using #Html.ActionLink instead of #Url.Action.
Thanks!
You don't seem to have specified the area name:
#Url.Action(
"Edit",
new {
projectNumber = Model.Project.ProjectNumber,
projectChildId = entry.Id,
area = "ProjectManagement"
}
)
Also make sure that there aren't any other routes that might conflict with this one in your area registration which should look like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"ProjectManagement_default",
"ProjectManagement/{controller}/{action}/{projectNumber}/{projectChildId}",
new { controller = "Project", action = "Home" }
);
}
Thanks to Michael for the response. Here's the answer for others.
I had:
context.MapRoute(
"ProjectManagement_ProjectPage",
"ProjectManagement/{controller}/{action}/{projectNumber}",
new { controller = "Project", action = "Home"}
);
///more routes
context.MapRoute(
"ProjectManagement_ProjectPageSingle",
"ProjectManagement/{controller}/{action}/{projectNumber}/{projectChildId}",
new { controller = "Project", action = "Home" }
);
The URL matched the ProjectPage route as well, so it took that one first. Had to flip the order, so the more specific route came first.
Thanks.

Resources