0

複数の領域を含む ASP.NET MVC 4 アプリケーションに取り組んでいます。プロジェクトの要件に従って、各エリアには独自のサイトマップ ファイルが必要です。この記事から: https://github.com/maartenba/MvcSiteMapProvider/wiki/Multiple-Sitemaps-in-One-Application、MvcSiteMapProvider を複数のサイトマップで動作させるには、外部 DI を使用する必要があることを理解しています。したがって、パッケージ MvcSiteMapProvider.MVC4.DI.Unity.Modules をインストールし、この記事に従ってクラス MvcSiteMapProviderContainerExtension を変更しました。メニューを作成しようとすると、次のエラーが表示されます。

親キーなしで宣言されたノードが複数あります。親キーは、SiteMap の 1 つのノードを除くすべてのノードに設定する必要があります。親キーのないノードはルート ノードと見なされます。XML でノードを定義する場合、XML ファイルにはルート ノードが含まれている必要があります。

MvcSiteMapProvider_EnableSiteMapFile 設定を "false" に設定することで、XML 構成を無効にすることができます。外部 DI 構成の場合、MvcSiteMapProvider DI モジュールから XmlSiteMapNodeProvider を削除することにより、XML 解析を無効にすることができます。

または、MvcSiteMapProvider_IncludeRootNodeFromSiteMapFile 設定を "false" に設定して、XML ファイルからルート ノードを除外し、他のすべてのノードを含めることができます。外部 DI 構成の場合、この設定は XmlSiteMapNodeProvider のコンストラクターにあります。

SiteMapCacheKey: 'sitemap://admin/'

あいまいなルート ノード:

親キー: '' | コントローラー: 'ホーム' | アクション: 'インデックス' | エリア: '' | URL: '/' | キー: 'rootarea' | ソース: 「.sitemap XML ファイル」

親キー: '' | コントローラー: 'AdminHome' | アクション: 'インデックス' | エリア: 「管理者」 | URL: '/Admin/AdminHome' | キー: 'adminarea' | ソース: 「.sitemap XML ファイル」

どんな助けでも大歓迎です。

さらに情報が必要な場合は、お知らせください。

4

1 に答える 1

2

https://github.com/maartenba/MvcSiteMapProvider/issues/237ですでに回答されています。参考までにコピペしておきます。

SiteMapUnity で2 つの異なるインスタンスを使用する例を次に示します。

    public class MvcSiteMapProviderContainerExtension
            : UnityContainerExtension
    {
        protected override void Initialize()
        {
            bool securityTrimmingEnabled = false;
            bool enableLocalization = true;

            string rootSiteMapFile = HostingEnvironment.MapPath("~/Mvc.sitemap");
            string adminSiteMapFile = HostingEnvironment.MapPath("~/Areas/Admin/Mvc.sitemap");

            TimeSpan absoluteCacheExpiration = TimeSpan.FromMinutes(5);
            string[] includeAssembliesForScan = new string[] { "MccSiteMapProviderTest" };

            var currentAssembly = this.GetType().Assembly;
            var siteMapProviderAssembly = typeof(SiteMaps).Assembly;
            var allAssemblies = new Assembly[] { currentAssembly, siteMapProviderAssembly };
            var excludeTypes = new Type[] {
                typeof(SiteMapNodeVisibilityProviderStrategy),
                typeof(SiteMapXmlReservedAttributeNameProvider),
                typeof(SiteMapBuilderSetStrategy),
                typeof(SiteMapNodeUrlResolverStrategy),
                typeof(DynamicNodeProviderStrategy)
            };
            var multipleImplementationTypes = new Type[] {
                typeof(ISiteMapNodeUrlResolver),
                typeof(ISiteMapNodeVisibilityProvider),
                typeof(IDynamicNodeProvider)
            };

    // Single implementations of interface with matching name (minus the "I").
            CommonConventions.RegisterDefaultConventions(
                (interfaceType, implementationType) => this.Container.RegisterType(interfaceType, implementationType, new ContainerControlledLifetimeManager()),
                new Assembly[] { siteMapProviderAssembly },
                allAssemblies,
                excludeTypes,
                string.Empty);

    // Multiple implementations of strategy based extension points
            CommonConventions.RegisterAllImplementationsOfInterface(
                (interfaceType, implementationType) => this.Container.RegisterType(interfaceType, implementationType, implementationType.Name, new ContainerControlledLifetimeManager()),
                multipleImplementationTypes,
                allAssemblies,
                excludeTypes,
                "^Composite");

    // TODO: Find a better way to inject an array constructor

    // Url Resolvers
            this.Container.RegisterType<ISiteMapNodeUrlResolverStrategy, SiteMapNodeUrlResolverStrategy>(new InjectionConstructor(
                new ResolvedArrayParameter<ISiteMapNodeUrlResolver>(this.Container.ResolveAll<ISiteMapNodeUrlResolver>().ToArray())
                ));

    // Visibility Providers
            this.Container.RegisterType<ISiteMapNodeVisibilityProviderStrategy, SiteMapNodeVisibilityProviderStrategy>(new InjectionConstructor(
                new ResolvedArrayParameter<ISiteMapNodeVisibilityProvider>(this.Container.ResolveAll<ISiteMapNodeVisibilityProvider>().ToArray()),
                new InjectionParameter<string>(string.Empty)
                ));

    // Dynamic Node Providers
            this.Container.RegisterType<IDynamicNodeProviderStrategy, DynamicNodeProviderStrategy>(new InjectionConstructor(
                new ResolvedArrayParameter<IDynamicNodeProvider>(this.Container.ResolveAll<IDynamicNodeProvider>().ToArray())
                ));


    // Pass in the global controllerBuilder reference
            this.Container.RegisterInstance<ControllerBuilder>(ControllerBuilder.Current);
            this.Container.RegisterType<IControllerBuilder, ControllerBuilderAdaptor>(new PerResolveLifetimeManager());

            this.Container.RegisterType<IBuildManager, BuildManagerAdaptor>(new PerResolveLifetimeManager());

            this.Container.RegisterType<IControllerTypeResolverFactory, ControllerTypeResolverFactory>(new InjectionConstructor(
                new List<string>(),
                new ResolvedParameter<IControllerBuilder>(),
                new ResolvedParameter<IBuildManager>()));

    // Configure Security

    // IMPORTANT: Must give arrays of object a name in Unity in order for it to resolve them.
            this.Container.RegisterType<IAclModule, AuthorizeAttributeAclModule>("authorizeAttribute");
            this.Container.RegisterType<IAclModule, XmlRolesAclModule>("xmlRoles");
            this.Container.RegisterType<IAclModule, CompositeAclModule>(new InjectionConstructor(new ResolvedArrayParameter<IAclModule>(
                new ResolvedParameter<IAclModule>("authorizeAttribute"),
                new ResolvedParameter<IAclModule>("xmlRoles"))));



            this.Container.RegisterType<ISiteMapCacheKeyGenerator, SiteMapCacheKeyGenerator2>();


            this.Container.RegisterInstance<System.Runtime.Caching.ObjectCache>(System.Runtime.Caching.MemoryCache.Default);
            this.Container.RegisterType(typeof(ICacheProvider<>), typeof(RuntimeCacheProvider<>));

            this.Container.RegisterType<ICacheDependency, RuntimeFileCacheDependency>(
                "rootSiteMapCacheDependency", new InjectionConstructor(rootSiteMapFile));

            this.Container.RegisterType<ICacheDependency, RuntimeFileCacheDependency>(
                "adminSiteMapCacheDependency", new InjectionConstructor(adminSiteMapFile));

            this.Container.RegisterType<ICacheDetails, CacheDetails>("rootSiteMapCacheDetails",
                new InjectionConstructor(absoluteCacheExpiration, TimeSpan.MinValue, new ResolvedParameter<ICacheDependency>("rootSiteMapCacheDependency")));

            this.Container.RegisterType<ICacheDetails, CacheDetails>("adminSiteMapCacheDetails",
                new InjectionConstructor(absoluteCacheExpiration, TimeSpan.MinValue, new ResolvedParameter<ICacheDependency>("adminSiteMapCacheDependency")));

// Configure the visitors
            this.Container.RegisterType<ISiteMapNodeVisitor, UrlResolvingSiteMapNodeVisitor>();

// Prepare for the sitemap node providers
            this.Container.RegisterType<IXmlSource, FileXmlSource>("rootSiteMapXmlSource", new InjectionConstructor(rootSiteMapFile));
            this.Container.RegisterType<IXmlSource, FileXmlSource>("adminSiteMapXmlSource", new InjectionConstructor(adminSiteMapFile));

    // IMPORTANT: Must give arrays of object a name in Unity in order for it to resolve them.
    // Register the sitemap node providers
        this.Container.RegisterInstance<ISiteMapNodeProvider>("rootXmlSiteMapNodeProvider",
            this.Container.Resolve<XmlSiteMapNodeProviderFactory>().Create(this.Container.Resolve<IXmlSource>("rootSiteMapXmlSource")), new ContainerControlledLifetimeManager());

        this.Container.RegisterInstance<ISiteMapNodeProvider>("adminXmlSiteMapNodeProvider",
            this.Container.Resolve<XmlSiteMapNodeProviderFactory>().Create(this.Container.Resolve<IXmlSource>("adminSiteMapXmlSource")), new ContainerControlledLifetimeManager());

        this.Container.RegisterInstance<ISiteMapNodeProvider>("ReflectionSiteMapNodeProvider1",
            this.Container.Resolve<ReflectionSiteMapNodeProviderFactory>().Create(includeAssembliesForScan), new ContainerControlledLifetimeManager());

        this.Container.RegisterType<ISiteMapNodeProvider, CompositeSiteMapNodeProvider>("rootSiteMapNodeProvider", 
            new ContainerControlledLifetimeManager(),
            new InjectionConstructor(new ResolvedArrayParameter<ISiteMapNodeProvider>(
                new ResolvedParameter<ISiteMapNodeProvider>("rootXmlSiteMapNodeProvider"),
                new ResolvedParameter<ISiteMapNodeProvider>("ReflectionSiteMapNodeProvider1"))));

        this.Container.RegisterType<ISiteMapNodeProvider, CompositeSiteMapNodeProvider>("adminSiteMapNodeProvider",
            new ContainerControlledLifetimeManager(),
            new InjectionConstructor(new ResolvedArrayParameter<ISiteMapNodeProvider>(
                new ResolvedParameter<ISiteMapNodeProvider>("adminXmlSiteMapNodeProvider"),
                new ResolvedParameter<ISiteMapNodeProvider>("ReflectionSiteMapNodeProvider1"))));

    // Configure the builders
        this.Container.RegisterInstance<ISiteMapBuilder>("rootSiteMapBuilder", 
            this.Container.Resolve<SiteMapBuilderFactory>().Create(this.Container.Resolve<ISiteMapNodeProvider>("rootSiteMapNodeProvider")), 
            new ContainerControlledLifetimeManager());

        this.Container.RegisterInstance<ISiteMapBuilder>("adminSiteMapBuilder", 
            this.Container.Resolve<SiteMapBuilderFactory>().Create(this.Container.Resolve<ISiteMapNodeProvider>("adminSiteMapNodeProvider")), 
            new ContainerControlledLifetimeManager());      

    // Configure the builder sets
        this.Container.RegisterType<ISiteMapBuilderSet, SiteMapBuilderSet>("rootBuilderSet",
            new InjectionConstructor(
                "default",
                securityTrimmingEnabled,
                enableLocalization,
                new ResolvedParameter<ISiteMapBuilder>("rootSiteMapBuilder"),
                new ResolvedParameter<ICacheDetails>("rootSiteMapCacheDetails")));

        this.Container.RegisterType<ISiteMapBuilderSet, SiteMapBuilderSet>("adminBuilderSet",
            new InjectionConstructor(
                "admin",
                securityTrimmingEnabled,
                enableLocalization,
                new ResolvedParameter<ISiteMapBuilder>("adminSiteMapBuilder"),
                new ResolvedParameter<ICacheDetails>("adminSiteMapCacheDetails")));
        }
    }

SiteMapBuilderFactory、、、XmlSiteMapNodeProviderFactoryと呼ばれるファクトリがあることに注意してください。これはReflectionSiteMapNodeProviderFactoryUnity およびその他の DI コンテナーに固有であり、この場合に使用する必要があるコンストラクター シグネチャにバインドせずに個々のオブジェクトを挿入することはできません。これにより、コンストラクターの署名は時間の経過とともに変更される可能性が高いため、将来の変更の数を最小限に抑えることができます。

于 2013-11-07T08:44:50.833 に答える