OrchardCMS / Orchard

Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform.
https://orchardproject.net
BSD 3-Clause "New" or "Revised" License
2.37k stars 1.12k forks source link

Web.config settings for Entity Framework ignored as of 1.9(.1) #5668

Open jvdonkoec opened 9 years ago

jvdonkoec commented 9 years ago

I'm upgrading an Orchard website from 1.8.1 to 1.9.1 including some custom modules which use Entity Framework to access legacy databases(using the Firebird Db provider).

Entity Framework requires some settings in the web.config but it seems it can't find those settings anymore. These settings were located in the module root Web.Config file. If I move these settings to the Orchard.Web Web.config file it can find them and the legacy databases can be accessed. But, I want to keep these Entity Framework settings as close as possible the the module which uses it.

The settings needed by Entity Framework, one element in the top and 2 in the bottom area of the modules Web.Config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <remove name="host"/>
            <remove name="pages"/>
            <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
            <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
        </sectionGroup>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>
    <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
            <namespaces>
                <add namespace="System.Web.Mvc"/>
                <add namespace="System.Web.Mvc.Ajax"/>
                <add namespace="System.Web.Mvc.Html"/>
                <add namespace="System.Web.Routing"/>
                <add namespace="System.Web.WebPages"/>
                <add namespace="System.Linq"/>
                <add namespace="System.Collections.Generic"/>
                <add namespace="Orchard.Mvc.Html"/>
            </namespaces>
        </pages>
    </system.web.webPages.razor>
    <system.web>
        <compilation targetFramework="4.5.1">
            <assemblies>
                <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </assemblies>
        </compilation>
    </system.web>
    <runtime>
        <!-- NOTE: These binding redirects have no runtime effect; they are only here to avoid build warnings. -->
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="NHibernate" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="Autofac" publicKeyToken="17863AF14B0044DA" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
    <entityFramework>
        <defaultConnectionFactory type="FirebirdSql.Data.EntityFramework6.FbConnectionFactory, EntityFramework.Firebird" />
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
            <provider invariantName="FirebirdSql.Data.FirebirdClient" type="FirebirdSql.Data.EntityFramework6.FbProviderServices, EntityFramework.Firebird" />
        </providers>
    </entityFramework>
    <system.data>
        <DbProviderFactories>
            <remove invariant="FirebirdSql.Data.FirebirdClient" />
            <add name="FirebirdClient Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".NET Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient" />
        </DbProviderFactories>
    </system.data>
</configuration>

The error thrown when it can't find the settings:

An unhandled exception has occurred and the request was terminated. Please refresh the page. If the error persists, go back
Unable to determine the provider name for provider factory of type 'FirebirdSql.Data.FirebirdClient.FirebirdClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.
System.NotSupportedException: Unable to determine the provider name for provider factory of type 'FirebirdSql.Data.FirebirdClient.FirebirdClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config. at System.Data.Entity.Utilities.DbProviderFactoryExtensions.GetProviderInvariantName(DbProviderFactory factory) at System.Data.Entity.Infrastructure.DependencyResolution.DefaultInvariantNameResolver.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.CachingDependencyResolver.<>c__DisplayClass1.b__0(Tuple`2 k) at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) at System.Data.Entity.Infrastructure.DependencyResolution.CachingDependencyResolver.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.<>c__DisplayClass3.b__0(IDbDependencyResolver r) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.RootDependencyResolver.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.<>c__DisplayClass3.b__0(IDbDependencyResolver r) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.CompositeResolver`2.GetService(Type type, Object key) at System.Data.Entity.Infrastructure.DependencyResolution.DbDependencyResolverExtensions.GetService[T](IDbDependencyResolver resolver, Object key) at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName(DbConnection connection) at System.Data.Entity.Internal.InternalConnection.get_ProviderName() at System.Data.Entity.Internal.LazyInternalContext.get_ProviderName() at System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create(DbContext context) at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() at System.Data.Entity.Internal.Linq.InternalSet`1.AsNoTracking() at System.Data.Entity.Infrastructure.DbQuery`1.AsNoTracking() at OnlineServices.Orchard.Databases.Services.OnlineServicesContextService.GetGebruikers(DatabasesSearchVM options) in c:\OECDEV\OnlineServices\OnlineServices.Orchard\src\Orchard.Web\Modules\OnlineServices.Orchard.Databases\Services\OnlineServicesContextService.cs:line 72 at OnlineServices.Orchard.Controllers.DatabasesAdminController.Index(PagerParameters pagerParameters, DatabasesSearchVM search) in c:\OECDEV\OnlineServices\OnlineServices.Orchard\src\Orchard.Web\Modules\OnlineServices.Orchard.Databases\Controllers\DatabasesAdminController.cs:line 38 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f()
dcinzona commented 9 years ago

This is what we have done in the past:

// Read the module Web.Config
var fileMap = new ExeConfigurationFileMap {
    ExeConfigFilename = HostingEnvironment.MapPath("~/Modules/MyCustomModule/web.config")
};

var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var appSettings = configuration.AppSettings.Settings;