Ich habe eine Multi-Tenant-Ansicht-Engine ähnlich wie das umgesetzt, was hier beschrieben wird:Handhabung Layout-Eigenschaften mit benutzerdefinierten Razor Ansicht Motor
die mich Ansicht, die die Suchpositionen lassen außer Kraft setzen, wie dies:
MasterLocationFormats = new[]
{
"~/Views/%1/{1}/{0}.cshtml",
"~/Views/%1/Shared/{0}.cshtml",
"~/Views/Default/{1}/{0}.cshtml",
"~/Views/Default/Shared/{0}.cshtml",
};
In dem die %1
mit den richtigen Ordnern für den aktiven Mieter ersetzt wird. Dies funktioniert gut, Ausnahme ein Problem. Wenn ich die Layout-Pfad auf meiner Ansicht wie folgt definieren:
Layout = "~/Views/Default/Shared/_MyLyout.cshtml";
Es besiegt Art von dem Zweck, die Multi-Tenancy mit, da ich die genaue Lage der Layoutseite zu hart Code haben müssen. Ich möchte in der Lage sein, so etwas zu tun:
Layout = "~/Views/%1/Shared/_MyLyout.cshtml";
Wenn ich wollte Mieter ermöglichen, ihre eine Layoutseiten zu haben, wie würde ich über die Unterstützung dieses gehen?
Ich habe versucht, mit der Ansicht-Engine Methoden Hantieren, die ich overrode:
- CreatePartialView
- Create
- FileExists
Aber nichts scheint mich zu deuten darauf hin, dynamisch in der Lage zu spezifizieren die Layoutseite.
Update:
Hier ist, was ich bisher arbeiten. Früher habe ich die Antwort auf diese Frage leicht einen HTML-Hilfs geändert https://stackoverflow.com/a/9288455/292578 zu erstellen:
public static string GetLayoutPageForTenant(this HtmlHelper html, string LayoutPageName)
{
var layoutLocationFormats = new[]
{
"~/Views/{2}/{1}/{0}.cshtml",
"~/Views/{2}/Shared/{0}.cshtml",
"~/Views/Default/{1}/{0}.cshtml",
"~/Views/Default/Shared/{0}.cshtml",
};
var controller = html.ViewContext.Controller as MultiTenantController;
if(controller != null)
{
var tenantName = controller.GetTenantSchema();
var controllerName = html.ViewContext.RouteData.Values["Controller"].ToString();
foreach(var item in layoutLocationFormats)
{
var resolveLayoutUrl = string.Format(item, LayoutPageName, controllerName, tenantName);
var fullLayoutPath = HostingEnvironment.IsHosted ? HostingEnvironment.MapPath(resolveLayoutUrl) : System.IO.Path.GetFullPath(resolveLayoutUrl);
if(File.Exists(fullLayoutPath)) return resolveLayoutUrl;
}
}
throw new Exception("Page not found.");
}
, die ähnlich ist, was saravanan vorgeschlagen. Dann kann ich das Layout meiner Meinung nach mit diesem Code festgelegt:
Layout = Html.GetLayoutPageForTenant("_Home");
Leider ist diese dupliziert der Arbeit, die der benutzerdefinierten Ansicht Motor tut, die wie die falsche Art und Weise scheint zu gehen.
Das einzige Problem, das ich mit diesem Ansatz habe, ist, dass nicht jeder Mieter ihre eigenen benutzerdefinierten Layout-Seiten haben wird. Ich möchte weiterhin, dass die Suche standardmäßig auf den Standardordner eingestellt wird, wenn keine benutzerdefinierte Layoutseite gefunden wird. – Sparafusile
@Sparafile: In diesem Fall können wir eine Fallback-ID im ViewBag haben. Wir werden also im Contoller überprüfen, ob der Mandant eine benutzerdefinierte Layoutseite hat, wenn wir den Ordner in der Ansichtsliste festlegen, wird der Ordnername des Mandanten festgelegt. 'ViewBag.TenantFolderName =" defaultPath "; if (Mandanten hat customFolder) { ViewBag.TenantFolderName = tenantFolderName; } ' IMHO wird dies ausfallsicher sein. – Saravanan
Während ich zustimme, dass dies funktionieren könnte, vereitelt es den Zweck der benutzerdefinierten Ansichts-Engine, die gesamte Arbeit in der Steuerung zu erledigen. Ich werde weiterhin nach einer eleganteren Lösung suchen. – Sparafusile