【发布时间】:2021-12-06 17:01:59
【问题描述】:
我正在从 ASP.NET MVC 迁移到 ASP.NET Core MVC。
我有一个BasePodsWidgetController,看起来像这样:
public abstract class BasePodsWidgetController<TProperties, TConfiguration, TItem> : WidgetController<TProperties>
where TProperties : BaseWidgetProperties, new()
where TConfiguration : TreeNode, IItemsListingWidgetConfiguration, new()
where TItem : TreeNode, new()
{
protected readonly IComponentPropertiesRetriever _componentPropertiesRetriever;
protected IContentRepository<TConfiguration> _contentRepository;
protected IContentRepository<PodContainer> _parentRepository;
protected IContentRepository<TItem> _childrenRepository;
protected abstract string ViewPath { get; }
protected virtual int Limit { get; set; } = 5;
public BasePodsWidgetController(IContentRepository<TConfiguration> contentRepository, IContentRepository<PodContainer> parentRepository, IContentRepository<TItem> childrenRepository,
IComponentPropertiesRetriever componentPropertiesRetriever)
{
_contentRepository = contentRepository;
_parentRepository = parentRepository;
_childrenRepository = childrenRepository;
_componentPropertiesRetriever = componentPropertiesRetriever;
}
public virtual PartialViewResult Index()
{
var properties = _componentPropertiesRetriever.Retrieve<TProperties>();
ViewBag.MarginClass = WidgetStylingHelper.GetMarginClassFromWidgetProperties(properties.Margin);
var widgetGuid = properties.WidgetConfiguration?.FirstOrDefault()?.NodeGuid;
var widgetGuidValue = widgetGuid.HasValue ? widgetGuid.Value : Guid.Empty;
var model = new PodsListing<TConfiguration, TItem>
{
Configuration = _contentRepository.GetByNodeGuid(widgetGuidValue),
Items = new TItem[0]
};
if (null != model.Configuration)
{
var parent = _parentRepository.GetByNodeGuid(model.Configuration.ItemsParentNodeGUID);
if (null != parent)
{
model.Items = _childrenRepository.GetChildrenByPath(parent.NodeAliasPath, Limit).ToArray();
}
}
return PartialView(ViewPath, model);
}
}
然后允许我像这样继承和覆盖:
public class FeaturePodsWidgetController : BasePodsWidgetController<FeaturePodsWidgetProperties, FeaturePodsWidget, FeaturePod>
{
protected override string ViewPath => "Widgets/_FeaturePods";
public FeaturePodsWidgetController(IContentRepository<FeaturePodsWidget> contentRepository, IContentRepository<PodContainer> parentRepository, IContentRepository<FeaturePod> childrenRepository, IComponentPropertiesRetriever componentPropertiesRetriever)
: base(contentRepository, parentRepository, childrenRepository, componentPropertiesRetriever)
{
}
public override PartialViewResult Index()
{
var properties = _componentPropertiesRetriever.Retrieve<FeaturePodsWidgetProperties>();
var widgetGuid = properties.WidgetConfiguration?.FirstOrDefault()?.NodeGuid;
var widgetGuidValue = widgetGuid.HasValue ? widgetGuid.Value : Guid.Empty;
ViewBag.MarginClass = WidgetStylingHelper.GetMarginClassFromWidgetProperties(properties.Margin);
var model = new PodsListing<FeaturePodsWidget, FeaturePod>
{
Configuration = _contentRepository.GetByNodeGuid(widgetGuidValue),
Items = new FeaturePod[0]
};
if (null != model.Configuration)
{
var parent = _parentRepository.GetByNodeGuid(model.Configuration.ItemsParentNodeGUID);
if (null != parent)
{
model.Items = _childrenRepository.GetChildrenByPath(parent.NodeAliasPath, 4).ToArray();
}
}
return PartialView(ViewPath, model);
}
}
但是在 ASP.NET Core 中转换为 ViewComponents,我得到一个错误,说只允许一个 Invoke 方法并且不知道为什么
BasePodsWidgetViewComponent
[ViewComponent()]
public abstract class BasePodsWidgetViewComponent<TProperties, TConfiguration, TItem> : ViewComponent
where TProperties : BaseWidgetProperties, new()
where TConfiguration : TreeNode, IItemsListingWidgetConfiguration, new()
where TItem : TreeNode, new()
{
protected readonly IComponentPropertiesRetriever _componentPropertiesRetriever;
protected IContentRepository<TConfiguration> _contentRepository;
protected IContentRepository<PodContainer> _parentRepository;
protected IContentRepository<TItem> _childrenRepository;
protected abstract string ViewPath { get; }
protected virtual int Limit { get; set; } = 5;
public BasePodsWidgetViewComponent(IContentRepository<TConfiguration> contentRepository, IContentRepository<PodContainer> parentRepository, IContentRepository<TItem> childrenRepository,
IComponentPropertiesRetriever componentPropertiesRetriever)
{
_contentRepository = contentRepository;
_parentRepository = parentRepository;
_childrenRepository = childrenRepository;
_componentPropertiesRetriever = componentPropertiesRetriever;
}
public virtual IViewComponentResult Invoke()
{
var properties = _componentPropertiesRetriever.Retrieve<TProperties>();
ViewBag.MarginClass = WidgetStylingHelper.GetMarginClassFromWidgetProperties(properties.Margin);
var widgetGuid = properties.WidgetConfiguration?.FirstOrDefault()?.NodeGuid;
var widgetGuidValue = widgetGuid.HasValue ? widgetGuid.Value : Guid.Empty;
var model = new PodsListing<TConfiguration, TItem>
{
Configuration = _contentRepository.GetByNodeGuid(widgetGuidValue),
Items = new TItem[0]
};
if (null != model.Configuration)
{
var parent = _parentRepository.GetByNodeGuid(model.Configuration.ItemsParentNodeGUID);
if (null != parent)
{
model.Items = _childrenRepository.GetChildrenByPath(parent.NodeAliasPath, Limit).ToArray();
}
}
return View(ViewPath, model);
}
}
转换后的 FeaturePodsWidgetViewComponent
public class FeaturePodsWidgetViewComponent : BasePodsWidgetViewComponent<FeaturePodsWidgetProperties, FeaturePodsWidget, FeaturePod>
{
public const string IDENTIFIER = "FeaturePodsWidget";
protected override string ViewPath => "_FeaturePodsWidget";
public FeaturePodsWidgetViewComponent(IContentRepository<FeaturePodsWidget> contentRepository, IContentRepository<PodContainer> parentRepository, IContentRepository<FeaturePod> childrenRepository, IComponentPropertiesRetriever componentPropertiesRetriever)
: base(contentRepository, parentRepository, childrenRepository, componentPropertiesRetriever)
{
}
public override IViewComponentResult Invoke()
{
var properties = _componentPropertiesRetriever.Retrieve<FeaturePodsWidgetProperties>();
var widgetGuid = properties.WidgetConfiguration?.FirstOrDefault()?.NodeGuid;
var widgetGuidValue = widgetGuid.HasValue ? widgetGuid.Value : Guid.Empty;
ViewBag.MarginClass = WidgetStylingHelper.GetMarginClassFromWidgetProperties(properties.Margin);
var model = new PodsListing<FeaturePodsWidget, FeaturePod>
{
Configuration = _contentRepository.GetByNodeGuid(widgetGuidValue),
Items = new FeaturePod[0]
};
if (null != model.Configuration)
{
var parent = _parentRepository.GetByNodeGuid(model.Configuration.ItemsParentNodeGUID);
if (null != parent)
{
model.Items = _childrenRepository.GetChildrenByPath(parent.NodeAliasPath, 4).ToArray();
}
}
return View(ViewPath, model);
}
}
我收到此错误:
视图组件“I3.Base.Web.ViewComponents.Widgets.FeaturePodsWidgetViewComponent”必须只有一个名为“Invoke”或“InvokeAsync”的公共方法
我不知道为什么:(
【问题讨论】:
-
是否允许创建虚拟Invoke方法?否则,您应该将 Invoke 放在基类中并调用另一个可以在派生类中覆盖的抽象方法。
标签: c# asp.net-core-mvc kentico asp.net-core-viewcomponent