I have an ASP.NET MVC 4.5 app. In this app, I have two controllers: Parent and Children. The look something like this:
[RoutePrefix("dashboard/parents")]
public partial class ParentsController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("add")]
public ActionResult Add()
{
return View();
}
}
[RoutePrefix("dashboard/children")]
public partial class ChildrenController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("add")]
public ActionResult Add()
{
return View();
}
}
At this time, these controllers work how I want. However, in my ChildrenController, I want to add something like an overload to the add route. In other words, I'd like for the user to be able to visit: /dashboard/parents/{parentId}/children/add. This URL would be used to add a child to a specific parent. My question is, how do I update my controllers to allow for this type of scenario?
thank you!
I think what you are looking for the is "~" to override your default routeprefix.. The following example is taken from the asp.net website which tells you how to accomplish the task.
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
// GET /api/authors/1/books
[Route("~/api/authors/{authorId:int}/books")]
public IEnumerable<Book> GetByAuthor(int authorId) { ... }
// ...
}
Related
I understand ActionResult is the base class for RedirectResult class so essentially functionality for the code below is the same.
Is there an advantage to explicitly specify the appropriate result class as a return type as opposed to the base class?
public ActionResult Index()
{
return Redirect("Home/Contact");
}
public RedirectResult Index()
{
return Redirect("Home/Contact");
}
if you need redirect quickly to another action without lost any data and this action is in the same controller , call the action as a method:
public IActionResult Index()
{
return Contact();
}
public IActionResult Contact()
{
....
}
which one from another redirections methods is better is an opinion-based question and is not allowed by SO policy
Is there any way to add a parameter to the Controller Routing attribute?
something like:
[Route("controller/{id}/"]
public class Controller {
public Controller(string id) { /*..*/ }
[HttpGet]
public ActionResult Get() { /*..*/ }
}
The [FromRoute] attribute on your controller method arguments should get you what you need.
Example
[Route("api/Test/{testId}")]
public class TestController: ControllerBase
{
[HttpGet]
[Route("echo")]
public void TestMethod([FromRoute]string testId)
{
return testId;
}
}
Also see this S.O. for more information.
Is it possible to have 2 ActionResult DeleteConfirmed in 1 controller?
I have 2 different views that I want to delete.
Thanks,
EB
[HttpPost, ActionName("DeleteLink")]
public ActionResult DeleteConfirmed(int id)
{
Link link = db.Links.Find(id);
db.Links.Remove(link);
db.SaveChanges();
return RedirectToAction("OutOfBank");
}
It seems that you want to overload DeleteConfirmed action. You can use the attribute if you want your code to do overloading.
[ActionName("MyOverloadedName")]
But, you'll have to use a different action name for the same http method.
So it's just semantics at that point. Would you rather have the name in your code or your attribute?
Code Example:
public class HomeController : Controller
{
public ActionResult GetEmpName()
{
return Content("This is the test Message");
}
[ActionName("GetEmpWithCode")]
public ActionResult GetEmpName(string EmpCode)
{
return Content("This is the test Messagewith Overloaded");
}
}
Phil has an article related to this: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
I have a controller called BaseController. In the BaseController, I have an Action method called Index which has some logic that involves querying the routes and building the URLs. Something on the lines of:
var link = Url.RouteUrl("myroute", new { id = 5 });
All this is well and fine until I create a controller NewController that extends the BaseController. In the constructor of NewController, I pass BaseController as a dependency.
public class NewController
{
private BaseController _baseController;
public NewController(BaseController baseController)
{
_baseController = baseController;
}
public ActionResult Index()
{
return _baseController.Index();
}
}
Reason why this was needed was because I need to override the view (some HTML and CSS changes). I didn't want to recreate the models and services and rewrite the business logic, so thought this would be the best and most time-effective approach.
Only issue is when the BaseController's Index Action is called, the Url is null obviously. Routes data is not available because the request was generated outside the base controller.
What is the best way to get around this?
Make BaseController.Index() virtual:
public class BaseController : Controller
{
public virtual ActionResult Index()
{
return View();
}
}
Then use inheritance:
public class NewController : BaseController
{
public override ActionResult Index()
{
var index = base.Index();
//do whatever
return index;
}
}
You are trying to call action method from another controller. Propably your constructor method gets baseController as a null. can you try to implement it like following
public ActionResult Index()
{
return new BaseController().Index(); // assume you call index action
}
Or you can call BaseController action from another controller like following
public ActionResult Index()
{
return RedirectToAction("Index", "Base"); // assume you call index action
}
You can also change Route url like following.
#Url.RouteUrl("myroute", new { controller = "Base", action = "Index", id = 5 })
I have another solution that requires a little bit of code design efforts.
Why don't you Abstract your business logic away from the two Controllers?
For example: RouteBuilder.cs a class that have the functions that contains the logic of building the routes.
And BaseClass.cs is a class that contains the Logic shared between the two Controllers.
Then:
public class BaseController
{
public ActionResult Index()
{``
//Instantiase BaseClass.cs and call the needed functions. Then RouteBuilder.cs and call functions.
return View();
}
}
public class NewController
{
public ActionResult Index()
{``
//Instantiase BaseClass.cs and call the needed functions.
return View();
}
}
Viola. Problem solved and clean code produced.
If you have 5 list views in a controller and in each list you can go to edit, details or delete.
On the edit, details and delete page youo have a link 'return to list'.
What's the best method to 'remember' to which list action you must return?
As a solution I've put some info like CurrentAction in the ViewModel and used that in the View. But if you want to use this with different controllers instead of one...
(You can use a Currentcontroller, CurrentArea, but that's not a 'beautifull' solution)
public class MyController : Controller
{
public ActionResult Index()
{
...
}
public ActionResult List2()
{
...
}
public ActionResult List3()
{
...
}
public ActionResult List4()
{
...
}
public ActionResult Create(...)
{
...
}
[HttpPost]
public ActionResult Create(...)
{
...
}
public ActionResult Edit(...)
{
...
}
[HttpPost]
public ActionResult Edit(...)
{
...
}
public ActionResult Delete(...)
{
...
}
[HttpPost]
public ActionResult Delete(...)
{
...
}
}
thanks
Filip
You can use Request.UrlReferrer Property to examine from where did user come to delete ot edit screens.Then bind url to return to list command.
You can set TempData["ReturnUrl"] in your caller action and then use it to set the url of return to list hyperlink.