【问题标题】:ASP.NET View Components: Remove default path to viewASP.NET 视图组件:删除默认路径以查看
【发布时间】:2017-07-10 20:09:50
【问题描述】:

我想返回一个带有特定路径的视图,就像这样,return View(~/Views/Home)。要返回的类型是IViewComponentResult

但是,当网站被渲染时,它会尝试在以下位置找到视图:Components/{controller-name}/~/Views/Home

所以我想问你们,如果你知道从路径中删除Components/{controller-name}/ 的聪明方法。我的视图组件类派生自 ViewComponent 类。

与此相关的问题是,现在,您必须有一个“组件”文件夹,其中控制器的名称作为包含 Default.cshtml 文件的子文件夹。我不喜欢将所有组件都放在一个文件夹中。我希望你有一个解决方案。

【问题讨论】:

    标签: razor asp.net-core-mvc asp.net-core-viewcomponent


    【解决方案1】:

    约定发生在ViewViewComponentResult,因此如果您不想要约定,则必须实现自己的IViewComponentResult

    由于 mvc 是开源的,你可以复制所有的ViewViewComponentResult,然后更改约定位。

    所以基本上必须做两件事:

    1. 创建您自己的IViewComponentResult - 我们称之为MyViewViewComponentResult
    2. 在您实现的ViewComponent 中创建一个助手来替换原来的View() - 目的是返回您在步骤1 中创建的自定义MyViewViewComponentResult

    创建你自己的IViewComponentResult

    约定发生在 ExecuteAsync:

    public class ViewViewComponentResult : IViewComponentResult
    {
        // {0} is the component name, {1} is the view name.
        private const string ViewPathFormat = "Components/{0}/{1}";
        private const string DefaultViewName = "Default";
    
        ....
    
        public async Task ExecuteAsync(ViewComponentContext context)
        {
            ....
            if (result == null || !result.Success)
            {
                // 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;
                var qualifiedViewName = string.Format(
                    CultureInfo.InvariantCulture,
                    ViewPathFormat,
                    context.ViewComponentDescriptor.ShortName,
                    viewName);
    
                result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
            }
    
            ....
        }
    
        .....
    }
    

    所以根据你的需要改变它

    在您实现的ViewComponent 中创建一个帮助器,替换原来的View

    所以根据原文

    /// <summary>
    /// Returns a result which will render the partial view with name <paramref name="viewName"/>.
    /// </summary>
    /// <param name="viewName">The name of the partial view to render.</param>
    /// <param name="model">The model object for the view.</param>
    /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
    public ViewViewComponentResult View<TModel>(string viewName, TModel model)
    {
        var viewData = new ViewDataDictionary<TModel>(ViewData, model);
        return new ViewViewComponentResult
        {
            ViewEngine = ViewEngine,
            ViewName = viewName,
            ViewData = viewData
        };
    }
    

    你会做类似的事情

    /// <summary>
    /// Returns a result which will render the partial view with name <paramref name="viewName"/>.
    /// </summary>
    /// <param name="viewName">The name of the partial view to render.</param>
    /// <param name="model">The model object for the view.</param>
    /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
    public MyViewViewComponentResult MyView<TModel>(string viewName, TModel model)
    {
        var viewData = new ViewDataDictionary<TModel>(ViewData, model);
        return new MyViewViewComponentResult
        {
            ViewEngine = ViewEngine,
            ViewName = viewName,
            ViewData = viewData
        };
    }
    

    所以以后你会打电话给MyView()而不是View()

    更多信息请查看另一个 SO:Change component view location in Asp.Net 5

    【讨论】:

      猜你喜欢
      • 2017-01-15
      • 2019-09-07
      • 1970-01-01
      • 2012-11-26
      • 2021-12-18
      • 2011-09-21
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      相关资源
      最近更新 更多