在 Asp.Net 5 中更改组件视图位置 [英] Change component view location in Asp.Net 5
问题描述
在 ASP.NET 5 上,组件视图必须位于以下两个位置之一:
Views/NameOfControllerUsingComponent/Components/ComponentName/Default.cshtml视图/共享/组件/组件名称/Default.cshtml
有没有办法把它改成:
Views/NameOfControllerUsingComponent/Components/ComponentName.cshtml视图/共享/组件/ComponentName.cshtml
所以基本上,删除文件夹 ComponentName 并将视图名称从 Default.cshtml 更改为 ComponentName.cshtml.
对我来说这更有意义......有可能吗?
仅当您创建从基础 ViewComponent
由框架提供.
该类定义了 View
帮助器,它返回 ViewViewComponentResult
:
public ViewViewComponentResult View(string viewName, TModel model){var viewData = new ViewDataDictionary(ViewData, model);返回新的 ViewViewComponentResult{视图引擎 = 视图引擎,视图名称 = 视图名称,视图数据 = 视图数据};}
ViewViewComponentResult
是定义约定的地方:
private const string ViewPathFormat = "Components/{0}/{1}";私人常量字符串 DefaultViewName = "默认";公共异步任务 ExecuteAsync(ViewComponentContext 上下文){...字符串限定视图名称;if (!isNullOrEmptyViewName &&(ViewName[0] == '~' || ViewName[0] == '/')){//传入的视图名称已经是根路径,视图引擎会处理这个.合格的视图名称 = 视图名称;}别的{//这将产生一个字符串,如:////组件/购物车/默认////视图引擎会将其与其他路径信息结合起来搜索路径,例如:////视图/共享/组件/购物车/Default.cshtml//视图/主页/组件/购物车/Default.cshtml//区域/博客/视图/共享/组件/购物车/Default.cshtml////这支持为组件视图提供覆盖的控制器或区域.var viewName = isNullOrEmptyViewName ?默认视图名称:视图名称;qualifiedViewName = string.Format(CultureInfo.InvariantCulture,视图路径格式,context.ViewComponentDescriptor.ShortName,视图名称);}...}
<块引用>
请注意,如果您从视图组件返回视图的完整路径作为视图名称,则视图组件将使用指定的视图.比如:
return View("~/Views/Shared/Components/ComponentName.cshtml")
由于无法修改 ViewViewComponentResult
中的约定,并且您的方法仅适用于具有单个视图的视图组件,因此您可以使用根视图路径方法构建一些东西:
- 创建您自己的
ViewComponent
类来扩展现有的. 添加新的辅助方法或隐藏现有的
View
方法以使用完整路径返回视图:public ViewViewComponentResult MyView
(TModel 模型){var viewName = string.Format("~/Views/Shared/Components/{0}.cshtml",this.ViewComponentContext.ViewComponentDescriptor.ShortName)返回视图(视图名称,模型);} - 如果您添加新方法,您也许可以将它们添加为
ViewComponent
的扩展方法,而不必创建自己的类.
另一种选择是创建一个类 SingleViewViewComponent
复制 ViewComponent
但替换了 ViewViewComponentResult View
的实现.然后在创建视图组件时,您将继承自 SingleViewViewComponent
而不是 ViewComponent
.
On ASP.NET 5 a Component view must be in one of two places:
Views/NameOfControllerUsingComponent/Components/ComponentName/Default.cshtml
Views/Shared/Components/ComponentName/Default.cshtml
Is there a way to change this to:
Views/NameOfControllerUsingComponent/Components/ComponentName.cshtml
Views/Shared/Components/ComponentName.cshtml
So basically, remove the folder ComponentName and change the view name from Default.cshtml to ComponentName.cshtml.
For me it makes more sense ... Is it possible?
That convention is only applied if you create a view component that derives from the base ViewComponent
provided by the framework.
That class defines the View
helpers, which return a 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
};
}
The ViewViewComponentResult
is where the conventions are defined:
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);
}
...
}
Notice that if you return from your view component the full path to a view as the view name, then the view component will use the specified view. Something like:
return View("~/Views/Shared/Components/ComponentName.cshtml")
Since there is no way to modify the conventions in ViewViewComponentResult
and your approach would only work for view components with a single view, you could build something using the root view paths approach:
- Create your own
ViewComponent
class extending the existing one. Add new helper methods or hide the existing
View
methods to return a view using a full path:public ViewViewComponentResult MyView<TModel>(TModel model) { var viewName = string.Format( "~/Views/Shared/Components/{0}.cshtml", this.ViewComponentContext.ViewComponentDescriptor.ShortName) return View(viewName, model); }
- If you add new methods you might be able to add them as extension methods of
ViewComponent
instead of having to create your own class.
Another alternative would be creating a class SingleViewViewComponent
copying the code for ViewComponent
but replacing the implementation of ViewViewComponentResult View<TModel>(string viewName, TModel model)
. Then when creating your view components, you would inherit from SingleViewViewComponent
instead of ViewComponent
.
这篇关于在 Asp.Net 5 中更改组件视图位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!