我想返回一个包含视图特定路径的视图,如return View(~/Views/Home)
。要返回的类型是IViewComponentResult
。
但是,当网站被渲染时,它会尝试在Components/{controller-name}/~/Views/Home
下找到该视图。
所以我想问你们,如果你知道从路径中删除Components/{controller-name}/
的聪明方法。我的视图组件类派生自ViewComponent
类。
关于这一点的问题是,现在,你必须有一个“Components”文件夹,其控制器名称是一个包含Default.cshtml文件的子文件夹。我不喜欢将所有组件放在一个文件夹中。我希望你有一个解决方案。
答案 0 :(得分:3)
约定发生在ViewViewComponentResult
,因此如果您不想要约定,则必须实现自己的IViewComponentResult
由于mvc是开源的,你可以复制所有ViewViewComponentResult
,然后更改约定位。
所以基本上要做两件事:
IViewComponentResult
- 让我们称之为MyViewViewComponentResult
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