Coding Freak
Coding Freak

Reputation: 418

How do I create an action link for each action in my controller within a view using asp.net mvc?

SO, I have 20+ Actions in a controller as here below:

public  ActionResult DoThis()
        {
            Image img = Image.FromFile("DoThis.png");
            //some other stuff to be done.
            return View();
        }
public  ActionResult DoThat()
        {
            Image img = Image.FromFile("DoThat.png");
            //some other stuff to be done.
            return View();
        }

I have a view which I want to show ActionLink for each action that is placed in my controller with assigned picture to the action, let say this:

@foreach
{
   <div class="col-sm-4">
    <div class="product-image-wrapper">
        <div class="single-products">
            <div class="productinfo text-center">
                <img src="the image assigned to the controller actions" alt="" />
                <h3 style="font-family:'Myriad عربي'">Action Name ؟</h3>
                <a href="@URL.Action("The acion link from controller")" class="btn btn-default add-to-cart">Click Here</a>
            </div>
        </div>
    </div>
</div>
}

Is that possible or I am asking too much?

Upvotes: 1

Views: 1448

Answers (2)

Bal&#225;zs
Bal&#225;zs

Reputation: 2929

Well, you can certainly get the methods of a certain class via reflection:

public List<string> GetActionNames()
{
    return typeof(HomeController)
        .GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
        .Where(method => method.ReturnType.IsSubclassOf(typeof(ActionResult)) || method.ReturnType == typeof(ActionResult))
        .Select(method => method.Name)
        .ToList();
}

This will return the names of all actions defined on your controller, where anything returning an ActionResult-compatible type is considered an action method and nothing else is. However, you should consider the following:

  • How will you decide what to bind to which parameter,
  • How will you handle overloaded methods,
  • You should refine this logic based on any security needs and other restrictions,
  • You should filter them further if any of the methods is a non-HttpGet, you could do this by filtering the methods by not having an HttpPost attribute on them (this gets even more complicated if you are dealing with an ApiController, where you should also consider the name prefix based method convention).

Generally speaking, the first bulletpoint is of most concern, you will be better off by just typing the links by hand rather than trying to figure out a reliable and general way of solving it. So I would only advise you to use such a logic if you can be sure that the aforementioned things are not something that you have to care about.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038780

Here's one way to get a list of ActionDescriptor[] for all actions on your controller:

@{
    var descriptor = new ReflectedControllerDescriptor(this.ViewContext.Controller.GetType());
    var actions = descriptor.GetCanonicalActions();
}

@foreach (var action in actions)
{
    <div>
        @Html.ActionLink("click me", action.ActionName)
    </div>
}

Now of course this will get a list of all actions on the current controller. If on the other hand you want to get only some specific actions, you could decorate them with some marker attribute and then filter the retrieved actions to only those having the attribute:

public class MyActionAttribute: Attribute
{
}

...

public class HomeController: Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [MyAction]
    public ActionResult DoThis()
    {
        Image img = Image.FromFile("DoThis.png");
        //some other stuff to be done.
        return View();
    }

    [MyAction]
    public ActionResult DoThat()
    {
        Image img = Image.FromFile("DoThat.png");
        //some other stuff to be done.
        return View();
    }
}

and then:

@{
    var descriptor = new ReflectedControllerDescriptor(this.ViewContext.Controller.GetType());
    var actions = descriptor.GetCanonicalActions().Where(desc => desc.GetCustomAttributes(typeof(MyActionAttribute), true).Any());
}

Upvotes: 4

Related Questions