I am creating a project in C# MVC and was using actions. Due to the requirements, now I am using Route to hide the controller name and display just the page name.
route config
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Law",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Law", action = "Home", id = UrlParameter.Optional }
);
controller 1 (to access this : http://localhost:17920/dashboard) and (http://localhost:17920/alert)
public class LawController : Controller
{
[Route("dashboard")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
[Route("alert")]
[ActionName("alert-list")]
public ActionResult AlertList()
{
return View();
}
controller 2 (to access this : http://localhost:17920/list)
public class ListController : Controller
{
[Route("list")]
[ActionName("list-of-return")]
public ActionResult listOfReturn()
{
return View();
}
What I am trying is when I enter this http://localhost:17920 as a default URL, then http://localhost:17920/dashboard should be displayed by default.
Thanks.
You need to define RoutePrefix over the Controller like below. Also update your Route("dashboard") to Route("Home") because that is your default action name on route configuration.
[RoutePrefix("Law")]
public class LawController : Controller
{
[Route("Home")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
// Other action methods
}
Please also refer https://devblogs.microsoft.com/aspnet/attribute-routing-in-asp-net-mvc-5/ for more details.
Edit As per edit in your question it is more clear what you want. From your existing code you just need to add one more Route over LawController's Home action as below, so it could match http://localhost:17920/ & http://localhost:17920/dashboard to that action method.
public class LawController : Controller
{
[Route("")]
[Route("dashboard")]
[ActionName("Home")]
public ActionResult Home()
{
return View();
}
[Route("alert")]
[ActionName("alert-list")]
public ActionResult AlertList()
{
return View();
}
Related
I added these routes to RouteConfig.cs
routes.MapRoute(
name: "NewPositiveRelease",
url: "dispatch/{poNumber}/{article}",
defaults: new { controller = "PositiveReleaseItem", action = "Create"});
routes.MapRoute(
name: "Dispatch",
url: "dispatch",
defaults: new { Controller = "Dispatch", action = "Index"});
In the hopes that I could go to this url
locahost:3000/dispatch/4529707272/171112
To execute the Create action in PositiveReleaseItemController. However, when I navigate to that url, I am seeing the error:
A public action method '4529707272' was not found on controller 'MVCQCPage.Controllers.DispatchController'.
Can someone please help me understand why this doesn't work?
Here is the controller:
using SharedLibrary.Models;
using System.Web.Mvc;
namespace MVCQCPage.Controllers
{
public class PositiveReleaseItemController : Controller
{
// GET: PositiveReleaseItem
public ActionResult Index()
{
return View();
}
public ActionResult Create(string poNumber, string article)
{
return View();
}
public ActionResult Insert(PositiveReleaseItem item)
{
return View();
}
}
}
I tried changing the order of the given routes, but with the same outcome. Please let me know if I can add any details which might help.
Thanks
Shouldn't it be:
"PositiveReleaseItem/{poNumber}/{article}",
Instead of:
"dispatch/{poNumber}/{article}",
I was able to resolve this by simply placing my new route mappings at the top of Routeconfig.cs (above all the others).
Not sure why this worked, as none of my other route maps refer to the Dispatch controller, so its weird that it was complaining about that.
I know how to send data to controller's action method as parameter from URL. Here I wonder how can I send data from URL to controller's field?
public MyAwesomeController : Controller {
public string SectionCode { get;set; }
}
and let's define Routes :
routes.MapRoute(
name : "AwesomeRouter",
url : "{code}/{action}",
defaults: new {controller = "MyAwesome", action = "Index", /* What to do here?*/}
);
I want SectionCode be filled with the {code} from URL. Is it possible to implement?
Yes it is, you can create inherited class from basic Controller class and override OnActionExecuting method where you can read url, route or any form data and store them in session or directly fill any field you need. Then create an inherited class of your controller.
public class MyAwesomeController : MyControllerBase
{
public ActionResult Index()
{
//this.SectionCode is available populated here
return View();
}
}
public class MyControllerBase : Controller
{
public string SectionCode
{
get;
private set;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
this.SectionCode = filterContext.RequestContext.RouteData.Values["code"].ToString();
base.OnActionExecuting(filterContext);
}
}
Each time you hit any action in this controller using route definition you provided, field will be automatically populated. But when you will have more than one route defined they it could get easily into conflicts eg. when code will match to any controller name. Normal website should not work this way.
Your route should look like this:
routes.MapRoute(
name: "AwesomeRouter",
url: "{code}/{action}",
defaults: new { controller = "MyAwesome", action = "Index" }
);
The code should then be passed on to the action as a parameter. I am storing it in the view bag for explanation purposes:
public class MyAwesomeController : Controller
{
public ActionResult Index(string code)
{
ViewBag.Code = code;
return View();
}
}
Using this URL then:
http://somehost/4567/Index
If you access the Viewbag property in your view:
#ViewBag.Code
You should see:
4567
I am defining my application URLs like
domainname.com/storecontroller/storeaction/storename
I want to rewrite like
domainname.com/storecontroller/storename
Actually, I need to skip storeaction from the url, I don't want to do it with querystring with "?" Is there anyway to do it by registering rout config path or any another way?
Yes. You can define action as a default parameter, and match for only specific controllers with a Regex constraint:
routes.MapRoute("<route name>", "{controller}/{storename}",
new
{
action = "storeaction"
},
new
{
controller = "somecontroller1|somecontroller2|somecontroller3",
});
(Action will always have the default value "storeaction")
Note that you need to define this route before the default generic route so it doesn't catch it before this kicks in.
Using Attribute routing
[RoutePrefix("Home")]
public ActionResult HomeController : Controller
{
[Route("{storeName}")]
public ActionResult ProcessStore(string storeName)
{
// to do : Return something
}
public ActionResult Index()
{
// to do : Return something
}
}
[RoutePrefix("Payment")]
public ActionResult PaymentController : Controller
{
[Route("{storeName}")]
public ActionResult ProcessStore(string storeName)
{
// to do : Return something
}
}
Currently I'm trying to implement some sub-controller mechanism. I've the following structure:
/Controller/Admin/UserController.cs
/Views/Admin/User/Index.cshtml
I'm registering the route like this:
routes.MapRoute(
name: "Admin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
My controller looks like this:
public class UserController : Controller
{
// GET: Administration
public ActionResult Index()
{
return View("~/Views/Admin/User/Index.cshtml"); // <---
}
}
My problem is, that this only works when I return the exact view. When
I pass no View, the automatic resolving of the path does not work. For example this does not work:
public class UserController : Controller
{
// GET: Administration
public ActionResult Index()
{
return View(); // <--- Not working
}
}
Why does this is not working with sub-controller?
Thanks a lot!
This controller:
public class TestController <T> : Controller
{
public string Index()
{
return "123";
}
}
This definition of the routes:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new
{
controller = "Test<T>",
action = "Index",
id = ""
});
This is the error I get:
The IControllerFactory 'Yad2.Web.Mvc.UI.Infrastructure.NinjectControllerFactory' did not return a controller for the name 'Test'.
public class TestController <T> : Controller
{
public string Index( )
{
return "123";
}
}
List of things wrong here:
Controllers cannot be generic abstract classes, you need to define T.
All actions need to return ActionResult derived objects.
"Test" in your route definition is absolutely incorrect. Never going to work.
You never showed your Ninject registration.