diff --git a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs index 7378fb141..423c8980a 100644 --- a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs +++ b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs @@ -53,5 +53,16 @@ namespace Orchard.Specs.Bindings { }); } + + + [When(@"I cycle the app domain")] + public void WhenICycleTheAppDomain() { + var webApp = Binding(); + webApp.Host.Execute(() => { + Trace.WriteLine("This call to Host.Reinitialize should not be needed, eventually"); + MvcApplication.Host.Reinitialize_Obsolete(); + }); + + } } } diff --git a/src/Orchard.Specs/Bindings/WebAppHosting.cs b/src/Orchard.Specs/Bindings/WebAppHosting.cs index b8f709612..6b6fa82a5 100644 --- a/src/Orchard.Specs/Bindings/WebAppHosting.cs +++ b/src/Orchard.Specs/Bindings/WebAppHosting.cs @@ -119,6 +119,14 @@ namespace Orchard.Specs.Bindings { } + [When(@"I go to ""(.*)"" on host (.*)")] + public void WhenIGoToPathOnHost(string urlPath, string host) { + Host.HostName = host; + _details = Host.SendRequest(urlPath); + _doc = new HtmlDocument(); + _doc.Load(new StringReader(_details.ResponseText)); + } + [When(@"I go to ""(.*)""")] public void WhenIGoTo(string urlPath) { _details = Host.SendRequest(urlPath); diff --git a/src/Orchard.Specs/Hosting/RequestDetails.cs b/src/Orchard.Specs/Hosting/RequestDetails.cs index 7309cf8e2..d5ab6f3ca 100644 --- a/src/Orchard.Specs/Hosting/RequestDetails.cs +++ b/src/Orchard.Specs/Hosting/RequestDetails.cs @@ -12,6 +12,7 @@ namespace Orchard.Specs.Hosting { ResponseHeaders = new Dictionary(); } + public string HostName { get; set; } public string UrlPath { get; set; } public string Page { get; set; } public string Query { get; set; } diff --git a/src/Orchard.Specs/Hosting/RequestExtensions.cs b/src/Orchard.Specs/Hosting/RequestExtensions.cs index f0a55a0b3..dc7271b83 100644 --- a/src/Orchard.Specs/Hosting/RequestExtensions.cs +++ b/src/Orchard.Specs/Hosting/RequestExtensions.cs @@ -16,6 +16,7 @@ namespace Orchard.Specs.Hosting { var physicalPath = Bleroy.FluentPath.Path.Get(webHost.PhysicalDirectory); var details = new RequestDetails { + HostName = webHost.HostName, UrlPath = urlPath, Page = physicalPath .Combine(urlPath.TrimStart('/', '\\')) @@ -89,6 +90,9 @@ namespace Orchard.Specs.Hosting { if (_details.RequestHeaders.TryGetValue("Cookie", out value)) return value; } + else if (index==HeaderHost) { + return _details.HostName; + } return base.GetKnownRequestHeader(index); } diff --git a/src/Orchard.Specs/Hosting/WebHost.cs b/src/Orchard.Specs/Hosting/WebHost.cs index 97c95657c..c188f76e7 100644 --- a/src/Orchard.Specs/Hosting/WebHost.cs +++ b/src/Orchard.Specs/Hosting/WebHost.cs @@ -11,6 +11,7 @@ namespace Orchard.Specs.Hosting { private Path _tempSite; private Path _orchardWebPath; + public void Initialize(string templateName, string virtualDirectory) { var baseDir = Path.Get(AppDomain.CurrentDomain.BaseDirectory); @@ -29,6 +30,7 @@ namespace Orchard.Specs.Hosting { .ShallowCopy("*.dll", _tempSite.Combine("bin")) .ShallowCopy("*.pdb", _tempSite.Combine("bin")); + HostName = "localhost"; PhysicalDirectory = _tempSite; VirtualDirectory = virtualDirectory; @@ -44,6 +46,7 @@ namespace Orchard.Specs.Hosting { sourceModule.Combine("Views").DeepCopy(targetModule.Combine("Views")); } + public string HostName { get; set; } public string PhysicalDirectory { get; private set; } public string VirtualDirectory { get; private set; } diff --git a/src/Orchard.Specs/MultiTenancy.feature b/src/Orchard.Specs/MultiTenancy.feature index 9921e4121..a32b0ab39 100644 --- a/src/Orchard.Specs/MultiTenancy.feature +++ b/src/Orchard.Specs/MultiTenancy.feature @@ -41,3 +41,36 @@ Scenario: A new tenant is created with uninitialized state And I am redirected Then I should see "Uninitialized" And the status should be 200 OK + +Scenario: A new tenant goes to the setup screen + Given I have installed Orchard + And I have installed "Orchard.MultiTenancy" + When I go to "Admin/MultiTenancy/Add" + And I fill in + | name | value | + | Name | Scott | + | RequestUrlHost | scott.example.org | + And I hit "Save" + And I go to "/Setup" on host scott.example.org + Then I should see "Welcome to Orchard" + And I should see "Finish Setup" + And the status should be 200 OK + +Scenario: A new tenant runs the setup + Given I have installed Orchard + And I have installed "Orchard.MultiTenancy" + When I go to "Admin/MultiTenancy/Add" + And I fill in + | name | value | + | Name | Scott | + | RequestUrlHost | scott.example.org | + And I hit "Save" + And I go to "/Setup" on host scott.example.org + And I fill in + | name | value | + | SiteName | Scott Site | + | AdminPassword | 6655321 | + And I hit "Finish Setup" + And I go to "/Default.aspx" + Then I should see "

Scott Site

" + And I should see "Welcome, admin!" diff --git a/src/Orchard.Specs/MultiTenancy.feature.cs b/src/Orchard.Specs/MultiTenancy.feature.cs index dc94db983..4dd7fc195 100644 --- a/src/Orchard.Specs/MultiTenancy.feature.cs +++ b/src/Orchard.Specs/MultiTenancy.feature.cs @@ -2,7 +2,7 @@ // // This code was generated by SpecFlow (http://www.specflow.org/). // SpecFlow Version:1.2.0.0 -// Runtime Version:2.0.50727.3603 +// Runtime Version:2.0.50727.4927 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -158,6 +158,98 @@ this.ScenarioSetup(scenarioInfo); testRunner.Then("I should see \"Uninitialized\""); #line 43 testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("A new tenant goes to the setup screen")] + public virtual void ANewTenantGoesToTheSetupScreen() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant goes to the setup screen", ((string[])(null))); +#line 45 +this.ScenarioSetup(scenarioInfo); +#line 46 + testRunner.Given("I have installed Orchard"); +#line 47 + testRunner.And("I have installed \"Orchard.MultiTenancy\""); +#line 48 + testRunner.When("I go to \"Admin/MultiTenancy/Add\""); +#line hidden + TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table3.AddRow(new string[] { + "Name", + "Scott"}); + table3.AddRow(new string[] { + "RequestUrlHost", + "scott.example.org"}); +#line 49 + testRunner.And("I fill in", ((string)(null)), table3); +#line 53 + testRunner.And("I hit \"Save\""); +#line 54 + testRunner.And("I go to \"/Setup\" on host scott.example.org"); +#line 55 + testRunner.Then("I should see \"Welcome to Orchard\""); +#line 56 + testRunner.And("I should see \"Finish Setup\""); +#line 57 + testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("A new tenant runs the setup")] + public virtual void ANewTenantRunsTheSetup() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant runs the setup", ((string[])(null))); +#line 59 +this.ScenarioSetup(scenarioInfo); +#line 60 + testRunner.Given("I have installed Orchard"); +#line 61 + testRunner.And("I have installed \"Orchard.MultiTenancy\""); +#line 62 + testRunner.When("I go to \"Admin/MultiTenancy/Add\""); +#line hidden + TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table4.AddRow(new string[] { + "Name", + "Scott"}); + table4.AddRow(new string[] { + "RequestUrlHost", + "scott.example.org"}); +#line 63 + testRunner.And("I fill in", ((string)(null)), table4); +#line 67 + testRunner.And("I hit \"Save\""); +#line 68 + testRunner.And("I go to \"/Setup\" on host scott.example.org"); +#line hidden + TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table5.AddRow(new string[] { + "SiteName", + "Scott Site"}); + table5.AddRow(new string[] { + "AdminPassword", + "6655321"}); +#line 69 + testRunner.And("I fill in", ((string)(null)), table5); +#line 73 + testRunner.And("I hit \"Finish Setup\""); +#line 74 + testRunner.And("I go to \"/Default.aspx\""); +#line 75 + testRunner.Then("I should see \"

Scott Site

\""); +#line 76 + testRunner.And("I should see \"Welcome, admin!\""); #line hidden testRunner.CollectScenarioErrors(); } diff --git a/src/Orchard.Tests/Environment/RunningShellTableTests.cs b/src/Orchard.Tests/Environment/RunningShellTableTests.cs index 6dac36484..3c0c1bb80 100644 --- a/src/Orchard.Tests/Environment/RunningShellTableTests.cs +++ b/src/Orchard.Tests/Environment/RunningShellTableTests.cs @@ -162,5 +162,51 @@ namespace Orchard.Tests.Environment { Assert.That(table.Match(new StubHttpContext("~/bar/foo", "wiki.example.com")), Is.Null); } + [Test] + public void HostNameMatchesRightmostIfRequestIsLonger() { + var table = (IRunningShellTable) new RunningShellTable(); + var settings = new ShellSettings {Name = "Default"}; + var settingsA = new ShellSettings {Name = "Alpha", RequestUrlHost = "example.com"}; + table.Add(settings); + table.Add(settingsA); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "www.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } + + [Test] + public void LongestMatchingHostHasPriority() { + var table = (IRunningShellTable) new RunningShellTable(); + var settings = new ShellSettings {Name = "Default"}; + var settingsA = new ShellSettings {Name = "Alpha", RequestUrlHost = "www.example.com"}; + var settingsB = new ShellSettings {Name = "Beta", RequestUrlHost = "example.com"}; + var settingsG = new ShellSettings {Name = "Gamma", RequestUrlHost = "wiki.example.com"}; + table.Add(settings); + table.Add(settingsA); + table.Add(settingsB); + table.Add(settingsG); + + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "www.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsG)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "username.example.com")), Is.SameAs(settingsB)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } + + + [Test] + public void ShellNameUsedToDistinctThingsAsTheyAreAdded() { + var table = (IRunningShellTable)new RunningShellTable(); + var settings = new ShellSettings { Name = "Default" }; + var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "removed.example.com" }; + var settingsB = new ShellSettings { Name = "Alpha", RequestUrlHost = "added.example.com" }; + table.Add(settings); + table.Add(settingsA); + table.Add(settingsB); + + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "removed.example.com")), Is.SameAs(settings)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "added.example.com")), Is.SameAs(settingsB)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } } } diff --git a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs index 9c7645970..e55615b2a 100644 --- a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs +++ b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs @@ -75,7 +75,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { .Returns(_container.BeginLifetimeScope("shell")); var factory = _container.Resolve(); - var context = factory.CreateSetupContext(); + var context = factory.CreateSetupContext(new ShellSettings { Name = "Default" }); Assert.That(context.Descriptor.EnabledFeatures, Has.Some.With.Property("Name").EqualTo("Orchard.Setup")); } diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs index e4d5006fe..f4fd6ecbd 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs @@ -1,12 +1,15 @@ using System.Collections.Generic; +using Orchard.Environment; using Orchard.Environment.Configuration; namespace Orchard.MultiTenancy.Services { public class TenantService : ITenantService { private readonly IShellSettingsManager _shellSettingsManager; + private readonly IOrchardHost _orchardHost; - public TenantService(IShellSettingsManager shellSettingsManager) { + public TenantService(IShellSettingsManager shellSettingsManager, IOrchardHost orchardHost) { _shellSettingsManager = shellSettingsManager; + _orchardHost = orchardHost; } #region Implementation of ITenantService @@ -17,6 +20,10 @@ namespace Orchard.MultiTenancy.Services { public void CreateTenant(ShellSettings settings) { _shellSettingsManager.SaveSettings(settings); + + + // MultiTenancy: This will not be needed when host listens to event bus + _orchardHost.Reinitialize_Obsolete(); } #endregion diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs b/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs index cd6ac207b..88592c1ac 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs @@ -23,6 +23,7 @@ using Orchard.UI.Notify; namespace Orchard.Setup.Controllers { [ValidateInput(false)] public class SetupController : Controller { + private readonly ShellSettings _shellSettings; private readonly INotifier _notifier; private readonly IOrchardHost _orchardHost; private readonly IShellSettingsManager _shellSettingsManager; @@ -31,12 +32,14 @@ namespace Orchard.Setup.Controllers { private readonly IAppDataFolder _appDataFolder; public SetupController( + ShellSettings shellSettings, INotifier notifier, IOrchardHost orchardHost, IShellSettingsManager shellSettingsManager, IShellContainerFactory shellContainerFactory, ICompositionStrategy compositionStrategy, IAppDataFolder appDataFolder) { + _shellSettings = shellSettings; _notifier = notifier; _orchardHost = orchardHost; _shellSettingsManager = shellSettingsManager; @@ -75,10 +78,10 @@ namespace Orchard.Setup.Controllers { } try { - var shellSettings = new ShellSettings { - Name = "Default", + var shellSettings = new ShellSettings(_shellSettings) { DataProvider = model.DatabaseOptions ? "SQLite" : "SqlServer", - DataConnectionString = model.DatabaseConnectionString + DataConnectionString = model.DatabaseConnectionString, + DataTablePrefix = model.DatabaseTablePrefix, }; // The vanilla Orchard distibution has the following modules enabled. @@ -99,10 +102,10 @@ namespace Orchard.Setup.Controllers { var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellToplogy); using (var environment = new StandaloneEnvironment(bootstrapLifetimeScope)) { environment.Resolve().CreateDatabase(); - + environment.Resolve().UpdateShellDescriptor( - 0, - shellDescriptor.EnabledFeatures, + 0, + shellDescriptor.EnabledFeatures, shellDescriptor.Parameters); } @@ -110,6 +113,9 @@ namespace Orchard.Setup.Controllers { // creating a standalone environment. // in theory this environment can be used to resolve any normal components by interface, and those // components will exist entirely in isolation - no crossover between the safemode container currently in effect + + // must mark state as Running - otherwise standalone enviro is created "for setup" + shellSettings.State = new TenantState("Running"); using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) { try { // create superuser @@ -165,9 +171,9 @@ namespace Orchard.Setup.Controllers { } } - shellSettings.State = new TenantState("Running"); _shellSettingsManager.SaveSettings(shellSettings); + // MultiTenancy: This will not be needed when host listens to event bus _orchardHost.Reinitialize_Obsolete(); // redirect to the welcome page. diff --git a/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs b/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs index 88d1cb3e1..122c38e77 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel.DataAnnotations; using Orchard.Setup.Annotations; using Orchard.Mvc.ViewModels; @@ -17,5 +18,7 @@ namespace Orchard.Setup.ViewModels { public bool DatabaseOptions { get; set; } [SqlDatabaseConnectionString] public string DatabaseConnectionString { get; set; } + + public string DatabaseTablePrefix { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx b/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx index f87b48449..cfc7135e3 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx +++ b/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx @@ -35,6 +35,10 @@ using (Html.BeginFormAntiForgeryPost()) { %> <%=Html.EditorFor(svm => svm.DatabaseConnectionString)%> <%=_Encoded("Example:") %>
<%=_Encoded("Data Source=sqlServerName;Initial Catalog=dbName;Persist Security Info=True;User ID=userName;Password=password") %>
+ + + <%=Html.EditorFor(svm => svm.DatabaseTablePrefix)%> +
diff --git a/src/Orchard/Environment/Configuration/ShellSettings.cs b/src/Orchard/Environment/Configuration/ShellSettings.cs index bf1bf36ff..c6717938f 100644 --- a/src/Orchard/Environment/Configuration/ShellSettings.cs +++ b/src/Orchard/Environment/Configuration/ShellSettings.cs @@ -5,6 +5,20 @@ /// from the App_Data settings.txt files. /// public class ShellSettings { + public ShellSettings() { + State = new TenantState("Invalid"); + } + + public ShellSettings(ShellSettings settings) { + Name = settings.Name; + DataProvider = settings.DataProvider; + DataConnectionString = settings.DataConnectionString; + DataTablePrefix = settings.DataTablePrefix; + RequestUrlHost = settings.RequestUrlHost; + RequestUrlPrefix = settings.RequestUrlPrefix; + State = settings.State; + } + public string Name { get; set; } public string DataProvider { get; set; } diff --git a/src/Orchard/Environment/DefaultOrchardHost.cs b/src/Orchard/Environment/DefaultOrchardHost.cs index a2a0ce27f..3f6e182d3 100644 --- a/src/Orchard/Environment/DefaultOrchardHost.cs +++ b/src/Orchard/Environment/DefaultOrchardHost.cs @@ -96,11 +96,16 @@ namespace Orchard.Environment { } ShellContext CreateSetupContext() { - Logger.Debug("Creating shell context for setup"); - return _shellContextFactory.CreateSetupContext(); + Logger.Debug("Creating shell context for root setup"); + return _shellContextFactory.CreateSetupContext(new ShellSettings { Name = "Default" }); } ShellContext CreateShellContext(ShellSettings settings) { + if (settings.State.CurrentState == TenantState.State.Uninitialized) { + Logger.Debug("Creating shell context for tenant {0} setup", settings.Name); + return _shellContextFactory.CreateSetupContext(settings); + } + Logger.Debug("Creating shell context for tenant {0}", settings.Name); return _shellContextFactory.CreateShellContext(settings); } diff --git a/src/Orchard/Environment/RunningShellTable.cs b/src/Orchard/Environment/RunningShellTable.cs index 6efaa53d5..ca96ecadc 100644 --- a/src/Orchard/Environment/RunningShellTable.cs +++ b/src/Orchard/Environment/RunningShellTable.cs @@ -8,7 +8,6 @@ using Orchard.Environment.Configuration; namespace Orchard.Environment { public interface IRunningShellTable { void Add(ShellSettings settings); - IEnumerable List(); ShellSettings Match(HttpContextBase httpContext); } @@ -50,10 +49,6 @@ namespace Orchard.Environment { } } - public IEnumerable List() { - return _shells; - } - public ShellSettings Match(HttpContextBase httpContext) { var host = httpContext.Request.ServerVariables.Get("HTTP_HOST") ?? ""; diff --git a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs index f3e5e4564..8321a26e9 100644 --- a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs @@ -20,7 +20,7 @@ namespace Orchard.Environment.ShellBuilders { /// Builds a shell context for an uninitialized Orchard instance. Needed /// to display setup user interface. /// - ShellContext CreateSetupContext(); + ShellContext CreateSetupContext(ShellSettings settings); } public class ShellContextFactory : IShellContextFactory { @@ -87,11 +87,9 @@ namespace Orchard.Environment.ShellBuilders { }; } - public ShellContext CreateSetupContext() { + public ShellContext CreateSetupContext(ShellSettings settings) { Logger.Warning("No shell settings available. Creating shell context for setup"); - var settings = new ShellSettings { Name = "Default" }; - var descriptor = new ShellDescriptor { SerialNumber = -1, EnabledFeatures = new[] { new ShellFeature { Name = "Orchard.Setup" } }, diff --git a/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs b/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs index 011616ceb..52e5607fd 100644 --- a/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs +++ b/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs @@ -10,8 +10,9 @@ namespace Orchard.Mvc.ModelBinders { } public void Publish(IEnumerable binders) { + // MultiTenancy: should hook default model binder instead and rely on shell-specific binders (instead adding to type dictionary) foreach (var descriptor in binders) { - _binders.Add(descriptor.Type, descriptor.ModelBinder); + _binders[descriptor.Type] = descriptor.ModelBinder; } } } diff --git a/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs b/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs index 5a087e396..5bf66bba6 100644 --- a/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs +++ b/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs @@ -8,8 +8,7 @@ namespace Orchard.Mvc.Routes { public class DefaultRouteProvider : IRouteProvider { public IEnumerable GetRoutes() { return new[] { - new RouteDescriptor { - Name = "Default", + new RouteDescriptor { Priority = -20, Route = new Route( "{controller}/{action}/{id}",