Partial view works different inside areas and outside of them - asp.net-mvc-4

i have two controllers outside the areas and a few areas for my application
my Layout page contains a partial view rendering code:
#Html.Action(actionName: "LoginBar", controllerName: "Login")
and it is registered in RouteConfig
routes.MapRoute(
name: "LoginBar",
url: "loginbar",
defaults: new
{
controller = "Login",
action = "LoginBar"
});
when i browsing page in HomeController: /home it works well
when i'm trying to browse pages inside areas: /contentedit/articles the exception throws on a line #Html.Action:
InvalidOperationException: No route in the route table matches the supplied values.
any ideas why this exception throws and what code modifications I need?

Inside #Html.Action(actionName: "LoginBar", controllerName: "Login") you can give area as object route like this way :
#Html.Action("LoginBar","Login",new { area = "//your area name//" })

Related

Routing / URL generation issues

I'm currently building an FAQ system which has the following URL structure:
Parent category: /faqs/parent-category/ (eg /faqs/products/)
Child article within a parent category: /faqs/parent-category/child-article/ (eg /faqs/products/how-to-build-my-product/)
I have the following routes set up:
routes.MapRoute(
name: "Faq.Main",
template: "{controller}/{parentSlug}/",
defaults: new { controller = "Faqs", action = "Index" }
);
routes.MapRoute(
name: "Faq.Article",
template: "{controller}/{parentSlug}/{slug}/",
defaults: new { controller = "Faqs", action = "View" }
);
The URL's generate fine for the parent, however I'm having an issue with the child articles. An example generated URL is as follows: /faqs/how-to-build-my-product/view/?parentSlug=products
The code in the View to create these links is as follows:
<a asp-controller="Faqs" asp-action="View" asp-route-parentSlug="#faq.ParentSlug" asp-route-slug="#faq.Slug">#faq.Title</a>
As you can see the URL generated for the child article isn't formatted correctly. It needs to be /faqs/products/how-to-build-my-product/
Any ideas how I can rectify this?
Thanks in advance.

Unable to target different area in asp.net core mvc

When i am using the asp-route-area tag helper to target a different area. The URL does not target it.
I have put the below code in the VIew of my Index method of 1 area:
<a asp-route-area="Employee" asp-action="List" asp-controller="Home">Link3</a>
The link formed is not targetting the Employee area. The link formed is :
Link3
It should be:
<a href="/Employee/home/list/>Link3</a>
My route is:
routes.MapRoute(
name: "areas",
template: "{area:exists}/{controller=Home}/{action=Index}");
//Default Route
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
what's wrong?
The correct syntax is asp-area="Employee".
asp-route-* tag helper is used to populate route parameters if they are defined on the target action e.g. [Get("path/{id}")] can be populated by asp-route-id="1".
If no matching route parameter can be found it is added to the query string, hence ?area=Employee is added to your URL because you don't have a matching route parameter named area.
According to this link
Once you've defined the folder hierarchy, you need to tell MVC that each controller is associated with an area. You do that by decorating the controller name with the [Area] attribute.
Further below, its says that in the route configuration you should use areaRoute instead of areas
In your case I think it should be:
<a asp-route-area="areas" asp-area="Employee" asp-action="List" asp-controller="Home">Link3</a>
I found that I did not added the attribute [Area("Employee")] on my Home Controller of Employee area.
Adding that attribute solved my problem.
using Microsoft.AspNetCore.Mvc;
namespace URLRouting.Areas.Employee.Controllers
{
[Area("Employee")]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

Optional middle parameter in MVC4 Route

I am trying to create a controller action that receives several parameters for filtering a scope and then the final parameter is a required paging parameter for paging the results.
//Example Action
public ActionResult Details(string time, string regionscope, string localscope = null, int page = 1) {
}
//RouteConfig.cs
routes.MapRoute(
name: "LocationWithLocalScopeRoute",
url: "/Details/{time}/{regionscope}/{localscope}/{page}",
defaults: new
{
controller = "Location",
action = "Details",
localscope = UrlParameter.Optional
}
);
Is there anyway I can exclude the localscope parameter but still have the page parameter be interpreted as the page number by the controller (while still maintaining pretty URLs)?
// Test URLs
/Details/May-17/Mid/1
/Details/May-17/Mid/Bumville/1
I know I could add a route before the existing route:
//RouteConfig.cs
routes.MapRoute(
name: "LocationWithNoLocalScopeRoute",
url: "/Details/{time}/{regionscope}/{page}",
defaults: new
{
controller = "Location",
action = "Details"
}
);
I also realize I could put page before any of the other parameters.
routes.MapRoute(
name: "LocationWithLocalScopeRoute",
url: "/Details/{page}/{time}/{regionscope}/{localscope}",
defaults: new
{
controller = "Location",
action = "Details",
localscope = UrlParameter.Optional
}
);
Was just wondering if there was a way to make it work all in one route definition while still having the Test URLs work.
No, not without creating another specific route or making localscope the last parameter.
When using routing, only the last parameter can be marked as UrlParameter.Optional. If more that one is optional, then the routing engine has no way to know which route segment applies to which method parameter.
In your case when the url is ../Details/May-17/Mid/1, is the last segment with the value of 1 the value for localscope or the value for page? There is no way to determine that, so if you were to generate the url using #Url.Action() (or one of the other methods that generate url's), then the url will be generated with query string values, not route values.

BetterCMS Server Widget Controller/View not found

Using BetterCMS 2.0.6.192 directly from NuGet. Brand new c# project.
I've been through the setup multiple times but cannot get a Server Widget to call custom Controller/View code.
I am attempting to create a custom server widget. I have the Phonebook.cshtml in the View/Widgets folder and registered as as Widget on a page in the site. This widget view will render with some simple html but when I try to Post or render a partial view I get an error "No route in the route table matches the supplied values".
Within the Phonebook.cshtml widget I have added
#{ Html.RenderAction("Index", "Phonebook", new {Area = ""}); }
but the partial view is not found. The error message, seen on the page with the widget is,
"Error rendering view "~/Views/Widgets/Phonebook.cshtml": No route in the route table matches the supplied values.".
I have a PhonebookController in the /Controllers folder in the /Views folder I have an Index.cshtml. While debugging the Index view is never fired.
I have also tried adding
#{ Html.RenderAction("Index", "Phonebook", new { Area = "Phonebook" }); }
to the /Views/Widgets/Phonebook.cshtml. I have /Areas/Phonebook/Controllers/PhonebookController.cs and /Areas/Phonebook/Views/Index the Index action is never fired.
I think it might have to do with routing. In the PhonebookAreaRegistration.cs file I have
context.MapRoute( "Phonebook_default", "Phonebook/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } );
In the /App_Start/RouteConfig.cs I have commented out the default routing as instructed in the docs.
Help.
This is a cross posted in Better CMS forum, not sure how much traffic that forum gets anymore. http://www.bettercms.com/support/widgets-and-modules/struggling-with-server-widget/
Rookie mistake. Forgot to register Routes in Global.asax.cs file.
Old Code- Does not work:
protected void Application_Start()
{
cmsHost = CmsContext.RegisterHost();
cmsHost.OnApplicationStart(this);
}
New Code- Works:
protected void Application_Start()
{
cmsHost = CmsContext.RegisterHost();
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
cmsHost.OnApplicationStart(this);
}

how to define action link to action from controller in an area in asp.net mvc

I have an area named customer. it contains a controller named customer with following action
public ActionResult BrowseByCategory(int id=0)
{
//some code here............
return View();
}
I need to create a link on for above action on the _layout.cshtml view on the root.
I have written following markup. but its not working
#Html.ActionLink(c.CategoryName, "BrowseByCategory", "Customer", new { area = "customer" },new { id = c.CategoryCode })
Please suggest the change.
There is an overload of ActionLink method that can be used in your case like so:
#Html.ActionLink(c.CategoryName, "BrowseByCategory", new { area = "customer", controller = "Customer", id = c.CategoryCode }, new { #* There should be htmlParameters *# })
You can't reference a model in an action in something as global as _Layout.cshtml, or at least you shouldn't. Technically, you could define a model for _Layout.cshtml, but then every... single.. view that uses this layout could only work with that same model. If you passed a different class type, you'd get runtime errors from your layout.
In your particular situation here, it seems that the link necessary in the layout is conditional on what category is currently being viewed. The best way to handle this, then, would be using sections.
In your layout, you can define a section like:
#RenderSection("CustomLink", required: false)
Just put that wherever you want the link to appear. Making it not required means you won't get runtime errors if some other view doesn't need this custom link.
Then, in your view:
#section CustomLink
{
#Html.ActionLink(c.CategoryName, "BrowseByCategory", "Customer", new { area = "customer" },new { id = c.CategoryCode })
}
Now, this will appear where you want in your layout, but you can define it at the view level.