在 Asp.Net 5 中更改组件视图位置 [英] Change component view location in Asp.Net 5

查看:21
本文介绍了在 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(string viewName, TModel model) 的实现.然后在创建视图组件时,您将继承自 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆