最近,我已经开始从2010年5月/ 6月的FubuMVC框架版本更新FubuMVC project到最新版本。
我遇到的最大绊脚石之一是如何配置FubuControls及其使用的显示模型,以便我可以在Site.Master
页面中呈现这些控件。我遇到问题的一条FubuException
错误消息是:
FubuMVC Error 2102:
Unknown input type ResourceDisplay
从FindUniqueByInputType
第69行的方法FubuMVC.Core.Registration.Querying.ChainResolver
抛出。
这是我的Web项目的Global.asax.cs:
public class Global : FubuStructureMapApplication
{
protected override void InitializeStructureMap(IInitializationExpression ex)
{
Bootstrapper.ScanAndRegisterTypesForStructureMap(ex, new List<Registry>
{
new WebAppWebRegistry(),
new AppSettingProviderRegistry()
});
setup_service_locator();
}
private static void setup_service_locator()
{
ServiceLocator.SetLocatorProvider(() => new StructureMapServiceLocator(ObjectFactory.Container));
}
public override FubuRegistry GetMyRegistry()
{
return new WebAppFubuRegistry();
}
}
这是我的FubuRegistry
:
public class WebAppFubuRegistry : FubuRegistry
{
public WebAppFubuRegistry()
{
IncludeDiagnostics(true);
Services(x => x.SetServiceIfNone<IWebAppSecurityContext, WebAppSecurityContext>());
Applies.ToThisAssembly()
.ToAssemblyContainingType<HomeController>();
Actions
.IncludeTypesNamed(x => x.EndsWith("Controller"));
Routes
.UrlPolicy<WebAppUrlPolicy>()
.IgnoreControllerNamespaceEntirely()
.ConstrainToHttpMethod(action => action.Method.Name.StartsWith("Perform"), "POST");
Views
.TryToAttach(x=>
{
x.by<ViewAndActionInDifferentFolders>();
x.by_ViewModel_and_Namespace_and_MethodName();
x.by_ViewModel_and_Namespace();
x.by_ViewModel();
});
/* Irrelevant behaviors are added to configuration here */
RegisterPartials(x => x.For<ResourceDisplay>().Use<ResourceTracker>());
//this.UseDefaultHtmlConventions();
//HomeIs<HomeController>(x => x.Index());
}
}
我发现的部分问题是,当我更新项目时,我改变了:
public class SiteMasterView : FubuMasterPage<EmptyModel>, IFubuPage<EmptyModel>{ }
到
public class SiteMasterView : FubuMasterPage
这意味着RenderPartial<TViewModel>(this IFubuPage<TViewModel> viewPage)
无法再使用扩展功能SiteMasterView
。
以下是RenderPartial<TViewModel>
中旧的无效Site.Master
来电:
<%= this.RenderPartial().Using<ResourceTracker>().For(Get<UserResources>().Resources)%>
所以,我认为此时我考虑尝试创建自己的RenderPartial扩展函数,该函数可以与FubuMasterPage
一起使用(而不仅仅是IFubuPage<EmptyModel>
)。但我想我也可以更新我对FubuFramework的使用并使用void Partial<TInputModel>(this IFubuPage page) where TInputModel : class;
扩展函数而不是旧的更详细的版本。
新电话:
<% this.Partial<ResourceDisplay>(); %>
当我开始遇到ChainResolver
发出的错误时,我尝试了各种解决方案,包括创建生成IFubuCommand
的{{1}}实现。我还尝试在ResourceDisplay
中明确注册部分。但是我没有幸运地超越FubuRegistry
。
使用FubuFramework注册FubuControls及其视图模型的首选方法是什么?
如何修复上述错误?
答案 0 :(得分:2)
标记,
首先:我认为你所寻找的是RenderPartialFor<TViewModel>
。这应该仍然有效,即使在母版页上也是如此。
第二:让我解决RenderPartial*
和Partial
之间的混淆。
这是一个已知问题,会给人们带来很多困惑。 RenderPartial与Partial完全不同。我知道这很令人困惑,我很抱歉。我们计划在FubuMVC 1.0的预备阶段尽快解决这个问题。
RenderPartial不执行行为链/操作。它与UserControls在ASP.NET WebForms中的工作方式非常相似。这是UserControl的简单渲染。
然而,部分地执行行为链/动作的“部分调用”。这允许您在当前操作的上下文中调用不同的操作。由于它是部分调用,因此并非所有行为都被执行。例如,如果您有一个TransactionalBehavior在HTTP请求的生命周期内管理数据库事务,然后您执行了行为链的Partial()调用,它将不生成新的数据库事务
行为的编码应知道他们决定在部分调用期间执行它们是否合适。
因此,您需要决定是否需要使用RenderPartial
的简单内容(如简单的页眉/页脚或可重复使用的静态HTML块),或者是否需要在动作中执行某些逻辑来生成模型使用Partial
方法绑定到局部视图。
在Partial
的情况下,它仍然会使用ASPX作为其视图,除了ASPX不应该有完整的HTML(例如没有begin&lt; html&gt;标记或body标记),因为它总是从另一个视图加载到更大的HTML文档的中间。部分ASPX通常不应使用母版页等。
任何操作都可以通过Partial
调用,并由其输入模型或反映其ControllerType.ActionMethod的lamda标识。但是,我建议您不要使用Partial
执行任何旧操作,但要执行部分调用的操作。
默认情况下,所有操作都将通过FubuMVC接收路由。对于部分操作,您可能不希望它们是可路由的(即,它们只能在服务器端的另一个操作的上下文中调用)。要指定这一点,您需要应用约定让Fubu知道不要路由这些操作。默认情况下,FubuMVC具有内置约定,不会使用[FubuPartial]
属性路由任何操作。如果你不想,你不 使用这个约定,但它很方便,因为它是你自动内置的。
如果您想使用jQuery $ .load()AJAX方法从Web浏览器加载服务器上的部分HTML内容(即页面上发生了某些变化),您可能希望部分操作有一个路由的原因是并且您想要从服务器刷新一些内容而不重新加载整个页面/屏幕。)