mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Nearly working integration of multi tenancy components
Tenant service provides refresh signal to host (temporary need) Setup module changed to run in any named shell that is uninitialized Table prefix added to setup form (for when sql server option is selected) CreateSetupContext takes shellsettings to support uninitialized tenants Removed name on default route provider - adding several routes by same name not allowed in single appdomain --HG-- branch : dev
This commit is contained in:
@@ -53,5 +53,16 @@ namespace Orchard.Specs.Bindings {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
[When(@"I cycle the app domain")]
|
||||
public void WhenICycleTheAppDomain() {
|
||||
var webApp = Binding<WebAppHosting>();
|
||||
webApp.Host.Execute(() => {
|
||||
Trace.WriteLine("This call to Host.Reinitialize should not be needed, eventually");
|
||||
MvcApplication.Host.Reinitialize_Obsolete();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -12,6 +12,7 @@ namespace Orchard.Specs.Hosting {
|
||||
ResponseHeaders = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public string HostName { get; set; }
|
||||
public string UrlPath { get; set; }
|
||||
public string Page { get; set; }
|
||||
public string Query { get; set; }
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
@@ -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; }
|
||||
|
||||
|
@@ -41,3 +41,36 @@ Scenario: A new tenant is created with uninitialized state
|
||||
And I am redirected
|
||||
Then I should see "<td>Uninitialized</td>"
|
||||
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 "<h1>Scott Site</h1>"
|
||||
And I should see "Welcome, <strong>admin</strong>!"
|
||||
|
94
src/Orchard.Specs/MultiTenancy.feature.cs
generated
94
src/Orchard.Specs/MultiTenancy.feature.cs
generated
@@ -2,7 +2,7 @@
|
||||
// <auto-generated>
|
||||
// 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 \"<td>Uninitialized</td>\"");
|
||||
#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 \"<h1>Scott Site</h1>\"");
|
||||
#line 76
|
||||
testRunner.And("I should see \"Welcome, <strong>admin</strong>!\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -75,7 +75,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
.Returns(_container.BeginLifetimeScope("shell"));
|
||||
|
||||
var factory = _container.Resolve<IShellContextFactory>();
|
||||
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"));
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
@@ -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.
|
||||
|
@@ -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; }
|
||||
}
|
||||
}
|
@@ -35,6 +35,10 @@ using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<%=Html.EditorFor(svm => svm.DatabaseConnectionString)%>
|
||||
<span class="hint"><%=_Encoded("Example:") %><br /><%=_Encoded("Data Source=sqlServerName;Initial Catalog=dbName;Persist Security Info=True;User ID=userName;Password=password") %></span>
|
||||
</span>
|
||||
<span data-controllerid="sql">
|
||||
<label for="DatabaseTablePrefix"><%=_Encoded("Database Table Prefix") %></label>
|
||||
<%=Html.EditorFor(svm => svm.DatabaseTablePrefix)%>
|
||||
</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
@@ -5,6 +5,20 @@
|
||||
/// from the App_Data settings.txt files.
|
||||
/// </summary>
|
||||
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; }
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ using Orchard.Environment.Configuration;
|
||||
namespace Orchard.Environment {
|
||||
public interface IRunningShellTable {
|
||||
void Add(ShellSettings settings);
|
||||
IEnumerable<ShellSettings> List();
|
||||
ShellSettings Match(HttpContextBase httpContext);
|
||||
}
|
||||
|
||||
@@ -50,10 +49,6 @@ namespace Orchard.Environment {
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ShellSettings> List() {
|
||||
return _shells;
|
||||
}
|
||||
|
||||
public ShellSettings Match(HttpContextBase httpContext) {
|
||||
var host = httpContext.Request.ServerVariables.Get("HTTP_HOST") ?? "";
|
||||
|
||||
|
@@ -20,7 +20,7 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
/// Builds a shell context for an uninitialized Orchard instance. Needed
|
||||
/// to display setup user interface.
|
||||
/// </summary>
|
||||
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" } },
|
||||
|
@@ -10,8 +10,9 @@ namespace Orchard.Mvc.ModelBinders {
|
||||
}
|
||||
|
||||
public void Publish(IEnumerable<ModelBinderDescriptor> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@ namespace Orchard.Mvc.Routes {
|
||||
public IEnumerable<RouteDescriptor> GetRoutes() {
|
||||
return new[] {
|
||||
new RouteDescriptor {
|
||||
Name = "Default",
|
||||
Priority = -20,
|
||||
Route = new Route(
|
||||
"{controller}/{action}/{id}",
|
||||
|
Reference in New Issue
Block a user