【问题标题】:How do I create an action link for each action in my controller within a view using asp.net mvc?如何使用 asp.net mvc 在视图中为控制器中的每个操作创建操作链接?
【发布时间】:2017-01-18 17:10:13
【问题描述】:

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

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

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

【问题讨论】:

  • &lt;a href="@Html.ActionLink(... 没有意义(ActionLink() 生成一个 &lt;a&gt; 标记 - 我假设您的意思是 Url.Action(...)
  • 您总是可以使用反射来获取控制器中每个方法的名称。不太清楚你想做什么,为什么?为什么不创建一个包含方法属性和关联图像的项目集合?
  • 我只想在控制器中动态添加指向我的操作的链接。我的意思是我不想为视图中控制器中的每个操作写@URL.Action。那可能吗?有时,我的控制器中的这些操作的数量可能会增加或减少,在我看来应该自动处理。
  • @StephenMuecke 我有一个问题没有得到解答,请您看一下并发表您的观点,因为我需要解决这个问题。谢谢你。这是问题的链接。 Question
  • MVC 控制器不是“用图像做事”的地方,这通常用于注入控制器的服务。您可以通过创建一个strategy 的服务来解决这个问题,每个服务都与图像做一些单独的事情,并将您的控制器重构为带有字符串参数的单个 Action 方法,该字符串参数确定要在图像上执行的操作(以及要执行的服务)启用)。另一个例子见this。创建链接列表就很简单了。

标签: c# asp.net-mvc


【解决方案1】:

这是获取控制器上所有操作的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());
}

【讨论】:

  • 达林 谢谢你的回答。如何在我的视图中设置 Image foreach 控制器操作?我的意思是图片应该属于控制器
  • 我不确定我是否理解您的要求。如果要显示图像,可以使用&lt;img&gt; 元素:&lt;img src="@Url.Action(action.ActionName)" alt="" /&gt;。这当然假设您的控制器操作返回图像内容类型而不是 html。
  • 我的意思是有什么方法可以将图像分配给控制器操作,然后在我的视图中将分配的图片访问到控制器?就像我应该为我的控制器中的每个动作有不同的图像,然后将它传递给视图中的动作链接?
  • 您是什么意思将图像分配给控制器操作?这真的没有多大意义。控制器操作可以返回图像结果(而不是视图结果),这将允许您使用 &lt;img&gt; 标记显示此图像。
  • @NaserDostdar - 你不能用你当前的实现(Image img = Image.FromFile("DoThis.png"); 只是在方法中分配一个局部变量)。一种选择是根据 Darin 的建议使用属性并包含图像文件的属性 - 例如[MyAction(Image="DoThis.png")] 然后使用反射读取属性属性值
【解决方案2】:

嗯,通过反射当然可以得到某个类的方法:

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,您应该进一步过滤它们,您可以通过 not 过滤具有HttpPost 属性的方法来做到这一点(这变得更加复杂如果您正在处理ApiController,您还应该考虑基于名称前缀的方法约定)。

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

【讨论】:

  • 我对你的答案投了赞成票,并将在我的项目中使用你的答案,但就你的答案而言,我不能接受它作为答案。还是谢谢你!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
相关资源
最近更新 更多