lele.lic
lele.lic

Reputation: 23

ActionResult with different parameters

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

Answers (2)

timothyclifford
timothyclifford

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

greenhoorn
greenhoorn

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

Related Questions