2015-11-04 75 views
2

在ASP.NET 5组件视图必须在两个地方:更改组件视图位置5

Views/NameOfControllerUsingComponent/Components/ComponentName/Default.cshtml 
Views/Shared/Components/ComponentName/Default.cshtml 

有没有办法来改变这种到:

Views/NameOfControllerUsingComponent/Components/ComponentName.cshtml 
Views/Shared/Components/ComponentName.cshtml 

所以基本上,删除文件夹ComponentName并将视图名称从Default.cshtml更改为ComponentName.cshtml。

对我来说它更有意义......有可能吗?

+0

您可以通过显式调用要显示的视图来更改视图名称。这允许您在一个ViewComponent中使用多个视图。这意味着这个结构定义了在哪里找到视图。 IMO考虑到这一点,将组件名称用作默认视图是没有意义的。 –

+0

是的,但它会在ComponentName文件夹中查找它。但是,是的,我没有想到ViewComponent可能有很多视图的情况......您认为这很常见吗?我发现ViewCoponent更像是一个控制器操作,只有一个视图。但是,是的,如果一个组件可以使用很多视图,那么默认的结构是有意义的。 –

+0

但它仍然有可能有许多意见。无论如何,我看到你的问题:)也许是有道理的在Github上创建一个新的提案:https://github.com/aspnet/Mvc/issues –

回答

1

该约定仅适用于您创建从框架提供的基础ViewComponent派生的视图组件。

这个类定义了View帮手,它会返回一个ViewViewComponentResult

public ViewViewComponentResult View<TModel>(string viewName, TModel model) 
{ 
    var viewData = new ViewDataDictionary<TModel>(ViewData, model); 
    return new ViewViewComponentResult 
    { 
     ViewEngine = ViewEngine, 
     ViewName = viewName, 
     ViewData = viewData 
    }; 
} 

ViewViewComponentResult是在约定定义:

private const string ViewPathFormat = "Components/{0}/{1}"; 
private const string DefaultViewName = "Default"; 

public async Task ExecuteAsync(ViewComponentContext context) 
{ 
    ... 

    string qualifiedViewName; 
    if (!isNullOrEmptyViewName && 
     (ViewName[0] == '~' || ViewName[0] == '/')) 
    { 
     // View name that was passed in is already a rooted path, the view engine will handle this. 
     qualifiedViewName = ViewName; 
    } 
    else 
    { 
     // This will produce a string like: 
     // 
     // Components/Cart/Default 
     // 
     // The view engine will combine this with other path info to search paths like: 
     // 
     // Views/Shared/Components/Cart/Default.cshtml 
     // Views/Home/Components/Cart/Default.cshtml 
     // Areas/Blog/Views/Shared/Components/Cart/Default.cshtml 
     // 
     // This supports a controller or area providing an override for component views. 
     var viewName = isNullOrEmptyViewName ? DefaultViewName : ViewName; 

     qualifiedViewName = string.Format(
      CultureInfo.InvariantCulture, 
      ViewPathFormat, 
      context.ViewComponentDescriptor.ShortName, 
      viewName); 
    } 

    ... 

} 

请注意,如果您从您的视图组件返回作为视图名称的视图的完整路径,则视图组件将使用指定的视图。 喜欢的东西:

return View("~/Views/Shared/Components/ComponentName.cshtml") 

由于没有办法修改约定ViewViewComponentResult和你的做法只会用一个单一的视图查看组件的工作原理,你可以用根视图路径的方法建立的东西:

  • 创建自己的ViewComponent类扩展现有的类。
  • 添加新的辅助方法或隐藏现有View方法使用完整路径返回一个视图:

    public ViewViewComponentResult MyView<TModel>(TModel model) 
    { 
        var viewName = string.Format(
          "~/Views/Shared/Components/{0}.cshtml", 
          this.ViewComponentContext.ViewComponentDescriptor.ShortName) 
        return View(viewName, model); 
    } 
    
  • 如果要添加新的方法,你也许可以将其添加为ViewComponent而不是扩展方法必须创建自己的班级。

另一种方法是创建类SingleViewViewComponent复制代码ViewComponent但替换的ViewViewComponentResult View<TModel>(string viewName, TModel model)的执行。然后,在创建视图组件时,您将继承SingleViewViewComponent而不是ViewComponent

+0

我刚刚创建了MVC的Gihub的问题...恕我直言系统可以在Views/NameOfControllerUsingComponent/Components/ComponentName.cshtml中查看,也可以在Views/NameOfControllerUsingComponent/Components/ComponentName.cshtml中查看......这两种方法都可以工作。 –