Reputation: 23
I've got a simple question about the behavior of ActionResult in ASP.NET MVC.
I need to have two action result with the same name but different parameters. In particular I want this:
public class CarController : Controller
{
[AuthorizeUser(AccessLevel = "New")]
public ActionResult New()
{
return View("New");
}
[AuthorizeUser(AccessLevel = "New?type=2")]
public ActionResult New(string type)
{
return View("NewCarType2");
}
}
I know that I can rename the second action result with a different name, but if I want to keep it to "new"?
I've tried with route.maps without success. I've think to do this:
public class CarController : Controller
{
public ActionResult New (string type) {
if(!string.IsNullOrEmpty(type) && type.Equals("2")) {
return NewCarType2()
else
return New()
}
}
[AuthorizeUser(AccessLevel = "New?type=2")]
private ActionResult NewCarType2()
{
return View("NewCarType2");
}
[AuthorizeUser(AccessLevel = "New")]
private ActionResult New()
{
return View("New");
}
}
but the attribute for the user's authorization is ignored.. also with the method's signature public and the attribute [NoAction].
The only way that I find to do what I want is with a class inheritance:
public class CarController : Controller
{
public virtual ActionResult New(string type)
{
if (!string.IsNullOrEmpty(type) && type.Equals("2"))
return RedirectToAction("NewCarType2", "CarOverride");
else
return RedirectToAction("New", "CarOverride");
}
}
public class CarOverrideController : CarController
{
[AuthorizeUser(AccessLevel = "New?type=2")]
public ActionResult NewCarType2(string type)
{
return View("NewCarType2");
}
[AuthorizeUser(AccessLevel = "New")]
public override ActionResult New(string type)
{
return View("New");
}
}
But is this the correct way to manage this situation (a part write the name of the ActionResults all different)?
Upvotes: 2
Views: 3401
Reputation: 6959
I would question why you need two routes with the same name which are doing two different things?
If all your AuthorizeUser attribute is doing is checking the user's role, why not do something similar to:
public ActionResult New(string type)
{
if (!string.IsNullOrWhiteSpace(type) && User.IsInRole("YOUR-ROLE-HERE"))
{
// Display NewCarType2 view if type requested and user is in correct role
return View("NewCarType2");
}
// Default to New view if no type requested or user not in role
return View("New");
}
This will catch both /new
and /new?type=foo
requests.
Upvotes: 0
Reputation: 1561
There are 2 possibilities to do what you want.
As Puneet replied in the comment, you can overload the method in the controller as mentioned in this post.
[ActionName("MyOverloadedName")]
or
You can define a Route
attribute on the controller method and route the action from a different URL to this method. For further explanation go to the ASP.NET Tutorial.
[Route("URL")]
public ActionResult New(string type) { ... }
Upvotes: 1