【问题标题】:Overriding an action called from ChildActionExtensions覆盖从 ChildActionExtensions 调用的操作
【发布时间】:2011-02-02 19:12:40
【问题描述】:

在我看来,我称之为:

    <%= Html.Action("ProductLayoutAndLimits", this.Model) /* Render product-specific options*/ %>

该操作在我的控制器中是虚拟的:

    [ChildActionOnly]
    public virtual ActionResult ProductLayoutAndLimits(DeliveryOptionsViewModel optionsViewModel)
    {
        return new EmptyResult();
    }

目的是我将在产品特定的控制器中覆盖此方法。所以很自然地,我这样做了:

    public override System.Web.Mvc.ActionResult ProductLayoutAndLimits(DeliveryOptionsViewModel optionsViewModel)
    {

但是断点没有命中,所以我的覆盖没有被拾取。我应该使用不同的重载吗?还是我需要传入不同的对象?或者我需要在我的产品特定操作上添加注释以便检测到它?

感谢任何帮助。谢谢!

编辑

虽然所有建议都值得赞赏,但我最感兴趣的是能够真正回答我的问题的解决方案,而不是提出不同的技术。

已建议使用模板,但请注意,在呈现任何新的附加视图代码之前,我需要执行控制器代码。基本控制器在一个解决方案中,用作其他产品的平台。他们不能做任何特定于产品的事情。在他们呈现他们的视图之后,意图是调用我对子操作的覆盖。我的控制器代码将检查许多事情,以确定如何在我的模型呈现视图之前设置属性。

编辑

我发现了问题。像往常一样,我觉得很傻。 Html.Action 正在从平台的视图代码中调用。事实证明,自 7 月以来,我们一直在为此使用产品特定视图。我没有注意到,因为我们通常不使用产品特定视图。哎呀!

【问题讨论】:

  • 您是否在基本控制器的 ProductLayoutAndLimits 方法中设置了断点,该断点是否被命中?如果是这样,您可能是在告诉 Html.Action 使用错误的控制器。如果请求来自 Base::SomeAction,则调用 Html.Action("SomeOtherAction") 将查找 Base::SomeOtherAction。您需要将“Derived”作为参数传递给 Html.Action 以使其查找 Derived::SomeOtherAction。
  • 查看我的编辑。连电话都没有打。男孩,我觉得自己很傻:)
  • @Levi:虽然我的问题实际上是我忽略的问题,但您的回答确实是正确的。触发我的产品操作的唯一方法是,如果我的产品的控制器是渲染视图的控制器。您介意将其发布为答案,以便我接受吗?谢谢!

标签: c# asp.net-mvc action


【解决方案1】:

为什么要使用子操作和覆盖控制器来处理这个问题?为什么不显示模板:

<%= Html.DisplayForModel("ProductLayoutAndLimits") %>

其中ProductLayoutAndLimits 将是相应显示模板的名称。

例子:

型号:

public class BaseViewModel
{
    public string BaseProp { get; set; }
}

public class DerviedViewModel : BaseViewModel
{
    public string DerivedProp { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new DerviedViewModel
        {
            BaseProp = "base prop",
            DerivedProp = "derived prop"
        });
    }
}

查看(~/Views/Home/Index.cshtml):

@model AppName.Models.BaseViewModel
@Html.DisplayForModel()

显示模板 (~/Views/Home/DisplayTemplates/DerviedViewModel.cshtml):

@model AppName.Models.DerviedViewModel
@Html.DisplayFor(x => x.BaseProp)
@Html.DisplayFor(x => x.DerivedProp)

当然你也可以有一个基类的显示模板(~/Views/Home/DisplayTemplates/BaseViewModel.cshtml):

@model AppName.Models.BaseViewModel
@Html.DisplayFor(x => x.BaseProp)

如果您的控制器操作已将基类作为模型返回,则该模板将被渲染。

【讨论】:

  • 原因是我无法在基本控制器中执行任何特定于产品的操作。换句话说,我不能从那里设置DerivedProp。基本控制器类属于用作其他产品平台的代码。由我的产品特定控制器来设置派生类的属性值。
  • @Samo,好的,在你的情况下,显示模板仍然可以很好地工作。
  • 怎么样?我需要控制器代码才能设置属性。在视图中做这些事情会破坏 MVC。我不明白模板如何为我工作。
  • @Samo,您只需在视图中写入&lt;%= Html.DisplayForModel() %&gt;。在您看来,这行代码绝对没有任何问题会破坏 MVC 模式。然后您提供相应的显示模板,如我的示例所示。然后根据传递给视图的模型类型,框架会自动选择合适的显示模板。
  • 我认为你没有理解我的意思。我的控制器代码需要进行一些检查,然后在我的模型上显式设置属性。我不能只告诉它显示某种模型的模板并期望它能够工作。
猜你喜欢
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多