Как правильно зарегистрировать модель дисплея и FubuControl? - PullRequest
2 голосов
/ 04 марта 2011

Недавно я начал обновлять проект 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 Ответ

2 голосов
/ 05 марта 2011

Марк,

Во-первых: я думаю, что вы ищете RenderPartialFor<TViewModel>. Это должно работать, даже на главных страницах.

Второе: позвольте мне разрешить путаницу между RenderPartial* и Partial.

Это известная проблема, которая вызывает путаницу среди людей. RenderPartial довольно сильно отличается от Partial. Я знаю, что это сбивает с толку, извините. Мы планируем исправить это в ближайшее время, в преддверии FubuMVC 1.0.

RenderPartial не выполняет цепочку поведения / действие. Это очень похоже на работу UserControls в ASP.NET WebForms. Это простой рендеринг UserControl.

Однако, Partial выполняет «частичный вызов» цепочки поведения / действия. Это позволяет вам вызывать другое действие в контексте текущего действия. Так как это частичный вызов, не все поведения выполняются. Например, если у вас был TransactionalBehavior, который управлял транзакцией БД в течение срока действия HTTP-запроса, а затем вы вызывали Partial () цепочки поведения, он не порождает новую транзакцию БД.

Поведения кодируются с осознанием того, что они решают, целесообразно ли им выполнять во время частичного вызова.

Таким образом, вам нужно решить, хотите ли вы простой контент, используя RenderPartial (например, простой заголовок / нижний колонтитул или повторно используемый фрагмент статического HTML), или вам нужно выполнить некоторую логику в действии, чтобы создать связанную модель к частичному виду, используя метод Partial.

В случае Partial он все равно будет использовать ASPX в качестве своего представления, за исключением того, что ASPX не должен иметь полный HTML (например, без тега begin или тега body), поскольку он всегда будет загружаться в середина большего HTML-документа из другого представления. Частичный ASPX обычно не должен использовать главные страницы и т. Д.

Любое действие может быть вызвано через Partial и идентифицируется его входной моделью или лямдой, отражающей его ControllerType.ActionMethod. Тем не менее, я рекомендую вам не выполнять никаких старых действий с использованием Partial, но есть действия, которые должны вызываться частично.

По умолчанию все действия будут получать маршрут через FubuMVC. Для частичных действий вы можете не захотеть, чтобы они были маршрутизируемыми (то есть они могут только вызываться в контексте другого действия на стороне сервера). Чтобы обозначить это, вам нужно применить соглашение, чтобы Fubu знал, что не нужно направлять эти действия. По умолчанию FubuMVC имеет встроенное соглашение, согласно которому не следует направлять какие-либо действия с атрибутом [FubuPartial]. У вас нет , чтобы использовать это соглашение, если вы не хотите, но это удобно, поскольку оно встроено автоматически для вас.

Причина, по которой вам может потребоваться частичное действие с маршрутом, заключается в том, что вы хотите использовать метод jJuery $ .load () AJAX для загрузки частичного содержимого HTML на сервер из веб-браузера (то есть что-то меняется на странице). и вы хотите обновить контент с сервера без перезагрузки всей страницы / экрана).

...