Как правильно зарегистрировать модель дисплея и FubuControl?
Недавно я начал обновлять проект FubuMVC с версии инфраструктуры FubuMVC, выпущенной до мая / июня 2010 года, до самой последней версии.
Один из самых больших камней преткновения, с которыми я сталкиваюсь, заключается в том, как настроить FubuControls и модели отображения, которые они используют, чтобы я мог отображать эти элементы управления в Site.Master
стр. Тот самый FubuException
Сообщение об ошибке, с которым я не могу обойти это:
FubuMVC Error 2102:
Unknown input type ResourceDisplay
брошенный из метода FindUniqueByInputType
в FubuMVC.Core.Registration.Querying.ChainResolver
строка 69
Вот мой 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
что породило ResourceDisplay
, Также я попытался зарегистрировать частичное явно в моем FubuRegistry
, Но мне не повезло пройти ChainResolver
,
Каков предпочтительный способ регистрации FubuControls и моделей их представлений в FubuFramework?
Как я могу исправить ошибку, упомянутую выше?
1 ответ
Отметка,
Первое: я думаю, что вы ищете 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 или тега body), потому что он всегда будет загружаться в середину большего HTML-документа из другого представления, Частичный ASPX обычно не должен использовать главные страницы и т. Д.
Любое действие может быть вызвано через Partial
и идентифицируется его входной моделью или лямдой, отражающей его ControllerType.ActionMethod. Тем не менее, я рекомендую вам не выполнять какие-либо старые действия, используя Partial
, но есть действия, которые должны быть вызваны частично.
По умолчанию все действия получат маршрут через FubuMVC. Для частичных действий вы можете не захотеть, чтобы они были маршрутизируемыми (то есть их можно вызывать только в контексте другого действия на стороне сервера). Чтобы обозначить это, вам нужно применить соглашение, чтобы Fubu знал, что не нужно направлять эти действия. По умолчанию FubuMVC имеет встроенное соглашение, чтобы не направлять какие-либо действия с [FubuPartial]
приписывать. Вам не нужно использовать это соглашение, если вы не хотите, но это удобно, поскольку оно встроено автоматически для вас.
Причина, по которой вам может потребоваться частичное действие при наличии маршрута, заключается в том, что вы хотите использовать метод AJAX jQuery $.load () для загрузки частичного содержимого HTML на сервер из веб-браузера (т.е. что-то меняется на странице, и вы хотите, чтобы обновить некоторый контент с сервера без перезагрузки всей страницы / экрана).