How to create a nested action in mvc? - asp.net-mvc

I want to use blow URL for my delete and edit and detail of my product
localhost:3891/Administrator/ShowProduct/delete/id?AdminId=12
localhost:3891/Administrator/ShowProduct/Edit/id?AdminId=12
localhost:3891/Administrator/ShowProduct/detail/id?AdminId=12
I tried blow code for RouteConfig:
routes.MapRoute(
name: "Administrtor",
url: "Administrator/ShowProduct/{action}/{id}",
defaults: new { controller = "Administrator", action = "ShowProduct", id = UrlParameter.Optional }
);
My controller is Administrator and my action is ShowProduct
How I can create Another Action Subset of ShowProduct?

You can create Controller with the name Administrator with Delete, Edit and Details actions.
Route Code
routes.MapRoute(
name: "Administrtor",
url: "Administrator/ShowProduct/{action}/{id}",
defaults: new { controller = "Administrator", action = "Delete", id = UrlParameter.Optional }
);
Controller Code
public class AdministratorController : Controller
{
public ActionResult Delete(int adminId)
{
return View();
}
public ActionResult Details(int adminid)
{
return View();
}
public ActionResult Edit(int adminid)
{
return View();
}
}
Generated URLs
http://localhost:64922/Administrator/showproduct/Edit/1
http://localhost:64922/Administrator/showproduct/Details/1
http://localhost:64922/Administrator/showproduct/Delete/1
If you want to display adminId in URL (?adminId=) then change the adminId to Id in route.

I used Area in asp.net-mvc like this first right click on project name and go add and select Area and then right click on Area folder and Add Area, then type name of Area in my case :Administrator
every Area have model,view,controller
For Controller in my case : right click on controller folder and type this name
ShowProduct
and now I can write any action for it like edit,delete and detail

Related

MVC ActionLink advice

I'm just starting out with .NET, and am building a test application. I currently have the homepage set using a DefaultController, and an Index() action method. This works as expected, and the homepage is simple www.domain.com.
I have created 2 new pages (Terms and Privacy) under the same DefaultController, using Terms() and Privacy() action methods.
I want to be able to browse to these with the URL as www.domain.com/terms and www.domain.com/privacy.
When i use a <li>#Html.ActionLink("Terms of Service", "Terms", "Default")</li> it works, but it takes me to the URL at www.domain.com/Default/privacy.
Should i be creating seperate controllers for each of these pages, or am I using the #html.ActionLink helper incorrectly? I have previously used <li>Privacy Policy</li> but I understand this isn't best practice?
Also, is there a way to force links as lowercase?
My Controller Code:
public class DefaultController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Terms()
{
return View();
}
public ActionResult Privacy()
{
return View();
}
}
If these were in the HomeController I don't believe you'd have the same problem. However, I think you can get around this by using the RouteConfig file:
routes.MapRoute(
name: "Default",
url: "{Action}/{Id}",
defaults: new { controller = "Default", Action = "Index", Id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Generic",
url: "{controller}/{Action}/{Id}",
defaults: new { Action = "Index", Id = UrlParameter.Optional }
);
I believe that what you want to do is hide the controller name in the url. If that is the case, your question is answered here:
ASP.NET MVC - Removing controller name from URL
You can use Attribute routing to give specific routes to endpoints.
[Route("terms")]
public ActionResult Terms()
{
return View();
}
[Route("privacy")]
public ActionResult Privacy()
{
return View();
}
In your RouteConfig.cs you must enable attribute routing with the following line of code: routes.MapMvcAttributeRoutes();
Now any urls generated with #Url.Action() or #Html.ActionLink should generate URLS as domain.com/privacy and domain.com/terms

Routing without Action Name in Url

I'm having problems with routing. I have News controller and I can read the details of a news from url http://localhost/News/Details/1/news-title(slug). Here is no problem for now. But I created a controller called Services with Index action. Route config:
routes.MapRoute(
"Services",
"Services/{id}",
new { controller = "Services", action = "Index" }
);
When my Index Action is
public ActionResult Index(string title)
{
return View(title);
}
I write localhost:5454/Services/sometext by hand in browser it works.
But when change my index action to
public ActionResult Index(string title)
{
Service service = _myService.Find(title);
ServiceViewModel = Mapper.Map<Service , ServiceViewModel >(service );
if (service == null)
{
return HttpNotFound();
}
return View(serviceViewModel);
}
I get Http Error 404 Not Found for Url localhost/Services/ITServices.
I can add this services from admin page with it's title (ITServices for example).
Then I do foreach in my Home Page for the services links
#foreach (var service Model.Services)
{
<div class="btn btn-success btn-sm btn-block">
#Html.ActionLink(service.Title, "Index", new { controller = "Services", id = service.Title })
</div>
}
But I can't show the page in localhost/Services/ITServices.
When I click on the link I want to go to page localhost/Services/ITServices and it has to show the content(which can be added from admin page) like in the news. But I don't want to use it with action name and ids like in the news. How can I achieve this?
EDIT
Ok. I add FindByTitle(string title) in repository. I changed the id to title in RouteConfig and in the link in Home Page View. Then in my domain model deleted Id and updated Title as [Key]. Now it works. Only have to check with remote validation for possible duplicates of Title when adding new from admin page.
The parameter name in the URL template does not match the argument on the Action (Index).
So you can do one of two things.
Change the template parameter to match the argument of the Action
routes.MapRoute(
name: "Services",
url: "Services/{title}",
defaults: new { controller = "Services", action = "Index" }
);
Where Action Index is
public ActionResult Index(string title) { ... }
or you change the argument of the Action Index to match the paramater in the url template
public ActionResult Index(string id) { ... }
Where the route mapping is
routes.MapRoute(
name: "Services",
url: "Services/{id}",
defaults: new { controller = "Services", action = "Index" }
);
But either way the route is not finding route because it cannot match the parameters.
In fact if the intention is to use the title as a slug you could go so far as to use a catch all route for services like
routes.MapRoute(
name: "Services",
url: "Services/{*title}",
defaults: new { controller = "Services", action = "Index" }
);
Take a look at the answers provided here
how to route using slugs?
Dynamic routing action name in ASP.NET MVC
Try this:
public ActionResult Index(string id)

MVC Routes with/without actions and with/without id

I have an asp.net MVC site and i would like to go to a controller without an action, but i would also like to be able to give an action on the same or other controllers.
So lets say i have Page.
I would like to be able to access the following urls
MY_URL (nothing else) - This would get another page with id = 1, or name = Home (business logic doesnt matter)
MY_URL/Page/id - This will get a page with a particular Id
MY_URL/Page/Create - Create a new page
MY_URL/Page/Delete - Delete a page
MY_URL/Page/Edit - Edit a page
I thought this would do it, but Create/Delete/Edit dont work (they just go to MY_URL/page with no id)
routes.MapRoute(
name: "PageWithId",
url: "Page/{id}",
defaults: new { controller = "Page", action = "Index" }
);
routes.MapRoute(
name: "default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Page", action = "Index", id = UrlParameter.Optional }
);
Here is my controller
public class PageController : Controller
{
private PageService _service;
public PageController(PageService service)
{
_service = service;
}
public async Task<ActionResult> Index(int? id)
{
... code to get page if id <> null
... code to get home page id id = null
// return view
return View(model);
}
public ActionResult Create()
{
return View();
}
... Delete, Edit methods implemented
}
Any help would be appreciated

Why does #Html.ActionLink not use RouteData

I have the simplest setup:
An empty asp.net MVC application with one controller:
public class HomeController : Controller
{
public ActionResult Edit(int id)
{
return View();
}
public ActionResult Commit(int id)
{
return View();
}
}
My Edit.cshtml has a call to ActionLink() like so:
#Html.ActionLink("Commit Data", "Commit")
If I now access the Edit-Action through "/Home/Edit/2" I would expect that the rendered link directs the user to "/Home/Commit/2".
It does not :( ... The link is created to "Home/Commit", completely disregarding the current RouteData entries.
I am using the default routing configuration (have not added any routes).
One way to fix this would be to add an explicit route for both actions:
routes.MapRoute(
name: null,
url: "Home/Edit/{id}",
defaults: new { controller = "Home", action = "Edit" }
);
routes.MapRoute(
name: null,
url: "Home/Commit/{id}",
defaults: new { controller = "Home", action = "Commit" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This works - but I really dont want to explicitly define every single route in the app - if I am using the "default" pattern...
The second solution would be to just add the routing-values manually like so:
#Html.ActionLink("Commit Data", "Commit", "Home", new {id = Model.Id})
But this also seems not right - ActionLink SHOULD use the current routing information, should it not?
What am I missing?
Ok, in case someone else is wondering the same thing - or just wants to have a solution that works...
I simply created my own #ActionLink() helper method on my custom ViewPage base class:
protected MvcHtmlString ActionLink(string linkText, string actionName)
{
var routeData = ViewContext.RequestContext.RouteData;
var id = routeData.Values["id"];
if (id != null)
return Html.ActionLink(linkText, actionName, new {id = id});
return Html.ActionLink(linkText, actionName);
}
This is exactly what I wanted. Now I can call
#ActionLink("Commit", "Commit")
and when I'm in the context of something with an id, the link will point to the appropriate route for this Id.

Parameter not being passed to Controller's action in ASP.NET MVC

I have two actions in a controller and yet the parameters are not being passed into one of them.
This one: /RouteStop/List/1
And this one: /RouteStop/Details/100
And my global.asax:
routes.MapRoute(
"List",
"{controller}/{action}/{id}",
new { controller = "RouteStop", action = "List", id = UrlParameter.Optional }
);
routes.MapRoute(
"Details",
"{controller}/{action}/{routeID}",
new { controller = "RouteStop", action = "Details", routeID = UrlParameter.Optional }
);
And here's the actions from my Controller:
public ActionResult List(string id)
{
return View();
}
public ActionResult Details(string routeID)
{
return View();
}
When I access this URL (/RouteStop/Details/100) the parameter gets passed just fine. But when I access the other one (/RouteStop/List/1) the parameter is null. The names match up as they should but I can't figure it out.
Try replacing {controller} with List and Details in respective routes. but for your scenario the default routing that you get when you create an MVC app should work.

Resources