如何使用asp.net mvc在视图中为控制器中的每个操作创建操作链接?

时间:2017-01-18 07:49:17

标签: c# asp.net-mvc

所以,我在控制器中有20多个Action,如下所示:

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();
        }

我有一个视图,我希望为我的控制器中放置的每个动作显示ActionLink,并将指定的图片添加到动作中,让我们说:

@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>
}

这可能还是我要求太多了?

2 个答案:

答案 0 :(得分:3)

以下是获取控制器上所有操作的ActionDescriptor[]列表的一种方法:

@{
    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>
}

现在,当然这将获得当前控制器上所有操作的列表。另一方面,如果您只想获得某些特定操作,则可以使用某个标记属性修饰它们,然后将检索到的操作过滤为仅具有该属性的操作:

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();
    }
}

然后:

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

答案 1 :(得分:1)

嗯,你当然可以通过反思获得某个类的方法:

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();
}

这将返回控制器上定义的所有操作的名称,其中返回ActionResult - 兼容类型的任何内容都被视为操作方法,而其他任何内容都不是。但是,您应该考虑以下事项:

  • 您将如何决定绑定哪个参数
  • 您将如何处理重载方法,
  • 您应该根据任何安全需求和其他限制来优化此逻辑,
  • 如果任何方法是非HttpGet,你应该进一步过滤它们,你可以通过而不是对它们进行过滤来实现这一点(它会得到HttpPost属性如果您正在处理ApiController,那么您应该考虑基于名称前缀的方法约定,这会更复杂。“

一般来说,第一个要点是最受关注的,只需手动输入链接而不是试图找出一种可靠而通用的解决方法,你会更好。所以我只建议你使用这样的逻辑,如果你能确定上述事情不是你必须关心的事情。