【问题标题】:How to create a html helper method similar to Html.DisplayFor that will look in a custom folder如何创建类似于 Html.DisplayFor 的 html 辅助方法,该方法将在自定义文件夹中查找
【发布时间】:2011-10-18 12:23:28
【问题描述】:

我的模型基于一个抽象基类,它看起来像这样:

  • InsurancePolicy(所有策略的基本抽象类)
    • 车辆保险政策
      • AbcInsurancePolicy
      • DefInsurancePolicy
    • 家庭保险政策
    • 人寿保险政策
    • ...等

在控制器中,我有以下代码用于通常的细节/列表场景:

    public ActionResult Details(int id) {
        // actual type is one of the concrete implementations
        InsurancePolicy policy = _repository.Get(id);
        return View(policy);
    }

    public ActionResult List() {
        // a list of concrete implementations
        IList<InsurancePolicy> policies = _repository.GetLatest(20);
        return View(policies);
    }

Details.chstml 只调用@Html.DisplayForModel(),ASP.NET MVC 实际上是根据实际类型(子类之一)从Shared/DisplayTemplates 中选择正确的局部视图。此外,如果找不到具有该名称的视图,它会退回到基类模板 InsurancePolicy.cshtml。例如,它会为 AbcInsurancePolicy 模型选择 VehicleInsurancePolicy.cshtml,因为没有找到 AbcInsurancePolicy.cshtml;对于 HomeInsurancePolicy,它将选择默认的 InsurancePolicy.cshtml,因为 DisplayTemplates 文件夹中没有 HomeInsurancePolicy.cshtml。它允许我添加其他 InsurancePolicy 子类型,而无需首先创建显示模板。

我希望列表视图具有类似的行为。在 List.cshtml razor 视图中,我只会遍历我的项目,并调用类似 Html.ListItemFor(...)

<ul>
@foreach (var policy in Model) {
    @Html.ListItemFor(_ => policy)
 }
</ul>

如何创建一个 Html.ListItemFor html 帮助程序,它会查看 ListItemTemplates 文件夹并完全像 Html.DisplayFor 一样工作? 有没有其他方法可以做到这一点?

注意事项: Html.DisplayFor(m =&gt; m.Property, templateName) 不行,它必须根据项目类型选择模板名称,递归回退到基类模板,直到找到东西。

【问题讨论】:

    标签: .net asp.net asp.net-mvc razor html-helper


    【解决方案1】:

    其工作方式是根据视图引擎中定义的一组视图位置找到模板。

    您可以做的是通过从 RazorViewEngine 继承并覆盖

    来创建自己的 ViewEngine
       public override ViewEngineResult FindPartialView(
            ControllerContext controllerContext, 
            string partialViewName, 
            bool useCache)
    

    通过这种方式,您可以提出自己的全新约定,并使用控制器上下文中的值来决定要查找的视图。

    你可能会做这样的事情(虽然可能需要调整它以完全适合你的场景)

     public override ViewEngineResult FindPartialView(
        ControllerContext controllerContext, 
        string partialViewName, 
        bool useCache)
    {
        ViewEngineResult result = null;
    
        //Get the TypeName that you want to look for
         var typeName = controllerContext.Controller.ViewData.Model.GetType().Name;
    
         result = base.FindPartialView(
                 controllerContext, typeName, useCache);
    
    
        //Fall back to default search path if no other view has been selected  
        if (result == null || result.View == null)
        {
            result = base.FindPartialView(
                controllerContext, partialViewName, useCache);
        }
    
        return result;  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多