mi hanno messo in atto una vista del motore multi-tenant simile a quanto descritto qui:proprietà di layout Manipolazione con motore di visualizzazione Razor personalizzato
Il che mi permetta di sovrascrivere le posizioni di ricerca per la visualizzazione come questo:
MasterLocationFormats = new[]
{
"~/Views/%1/{1}/{0}.cshtml",
"~/Views/%1/Shared/{0}.cshtml",
"~/Views/Default/{1}/{0}.cshtml",
"~/Views/Default/Shared/{0}.cshtml",
};
In cui il %1
è sostituito con la cartella corretta per l'inquilino attiva. Questo sta funzionando bene, tranne un problema. Quando ho definire il percorso di layout sul mio punto di vista in questo modo:
Layout = "~/Views/Default/Shared/_MyLyout.cshtml";
E 'sorta di sconfigge lo scopo di avere il multi-tenancy dal momento che ho dovuto codificare la posizione esatta della pagina di layout. Voglio essere in grado di fare qualcosa del genere:
Layout = "~/Views/%1/Shared/_MyLyout.cshtml";
Se volessi permettere inquilini di avere loro una pagine di layout, come potrei fare per sostenere questo?
Ho provato a giocherellare con i metodi di vista del motore che mi ha calpestato:
- CreatePartialView
- CreateView
- FileExists
Ma nulla sembra indicare se stesso verso l'essere in grado di specificare in modo dinamico la pagina di layout.
Aggiornamento:
Ecco quello che ho a lavorare finora. Ho usato la risposta a questa domanda https://stackoverflow.com/a/9288455/292578 leggermente modificato per creare un aiutante HTML:
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.");
}
che è simile a quello che Saravanan suggerito. Allora posso impostare il layout a mio avviso con questo codice:
Layout = Html.GetLayoutPageForTenant("_Home");
Purtroppo, questo duplica il lavoro che il motore visualizzazione personalizzata sta facendo, che sembra il modo sbagliato di procedere.
L'unico problema che ho con questo approccio è che non tutti gli inquilini avranno le proprie pagine di layout personalizzate. Continuo comunque a cercare la cartella predefinita nella cartella predefinita se non viene trovata una pagina di layout personalizzata. – Sparafusile
@Sparafusile: In questo caso, possiamo avere un ID fallback nel ViewBag. Quindi, nel Contoller, controlleremo se l'inquilino ha una pagina di layout personalizzata, in tal caso la cartella verrà impostata nella view bag, altrimenti verrà impostato il nome della cartella del tenant. 'ViewBag.TenantFolderName =" defaultPath "; if (tenant Has CustomFolder) { ViewBag.TenantFolderName = tenantFolderName; } ' IMHO, questo sarà sicuro. – Saravanan
Mentre sono d'accordo che questo potrebbe funzionare, questo tipo di sconfigge lo scopo del motore di visualizzazione personalizzato di fare tutto il lavoro nel controller. Continuerò a cercare una soluzione più elegante. – Sparafusile