Domanda

Sto sperimentando MVC e la mia domanda è: dove avevo la logica Page_Load in Pagine master con WebForms, dove dovrebbe andare in MVC? Ecco il caso aziendale:

  • Intestazioni host diverse dovrebbero causare la visualizzazione di titoli di pagina diversi sulla (una) Pagina principale del sito, quindi su tutte le pagine. Ad esempio, se l'intestazione host è hello.mydomain.com, il titolo della pagina dovrebbe essere " Hello World " per tutte le pagine / visualizzazioni, mentre goodbye.mydomain.com dovrebbe essere " Goodbye World " per tutte le pagine / visualizzazioni.
  • Se l'intestazione host è diversa da qualsiasi altra cosa presente nell'elenco, indipendentemente da dove nell'applicazione, dovrebbe reindirizzare a / Error / NoHostHeader.

Precedentemente, lo inserivo nell'evento MasterPage Load () e sembra che in MVC, potrei farlo sia in tutti i controller (non mi sembra giusto dover chiamare questa funzionalità in tutti i controller), o da qualche parte in Global.asax (sembra troppo ... globale?).

Modifica: Ho ottenuto che funzioni correttamente utilizzando il metodo Global.asax combinato con un controller per l'elaborazione effettiva dei dati. L'unico problema a questo punto è che tutte le informazioni sull'intestazione host si trovano in un database. Normalmente memorizzerei l'inquilino "inquilino" informazioni se si inserisce una variabile Session e si effettua una chiamata DB solo quando non è presente; c'è un modo migliore per farlo?

È stato utile?

Soluzione

Non esiste un equivalente 1: 1 in MVC per un motivo, ricapitoliamo semplicemente come pensarlo in modo MVC:

Modello : " Le pagine di questo sito sono sempre richieste in un determinato contesto, chiamiamolo l'inquilino (o utente, argomento o qualunque cosa rappresentino i tuoi sottodomini). Il modello di dominio ha una proprietà che rappresenta l'inquilino della richiesta corrente. & Quot;

Visualizza : " Rende il titolo della pagina in base al tenant impostato nel modello. "

Controller : " Imposta l'inquilino nel modello in base all'intestazione host " ;.

Tieni presente che ciò che vogliamo evitare è mescolare controller, vista e logica aziendale. Avere la logica del controller in più di un posto o un luogo, che non è chiamato "controller" non è un problema, purché rimanga separato.

E ora il bello: Potresti fare questo " stile MVC " anche con i moduli Web e la soluzione funziona ancora con ASP.NET MVC!

Hai ancora il ciclo di vita della richiesta (non il ciclo di vita della pagina), quindi potresti implementare un HttpModule personalizzato che contiene questa parte della logica del controller per tutte le richieste. Gestisce l'evento BeginRequest, controlla l'intestazione host e archivia il tenant in qualcosa come HttpContext.Current.Items [" tenant "]. (Ovviamente potresti avere un wrapper statico e digitato per questa voce del dizionario.)

Quindi tutti gli oggetti del tuo modello (o una classe base del modello, o qualunque cosa sia appropriata per la tua soluzione) possono accedere a HttpContext per fornire accesso a queste informazioni in questo modo:

public string Tenant
{
    get { return HttpContext.Current.Items["tenant"]; }
}

I vantaggi:

  • Hai separato causa (intestazione host) ed effetto (rendering del titolo della pagina), migliorando la manutenibilità e la testabilità
  • Pertanto, è possibile aggiungere facilmente ulteriori comportamenti al modello di dominio in base a questo stato, ad esempio il caricamento di contenuti dal database in base al tenant corrente.
  • Puoi facilmente fare in modo che più parti della vista dipendano dall'inquilino, come file CSS che includi, un'immagine del logo ecc.
  • In seguito è possibile modificare la logica del controller per impostare il titolare nel modello non solo in base al sottodominio, ma forse in base a un cookie, un referrer, un termine di ricerca, la lingua dell'agente utente o qualunque cosa si possa pensare, senza modificando qualsiasi codice in base al modello.

Aggiorna la tua modifica : non mi piace l'idea di mantenere lo stato nella sessione, soprattutto se il cookie della sessione potrebbe applicarsi non solo a ciascun sottodominio, ma a tutti i domini. In questo caso potresti pubblicare contenuti incoerenti se gli utenti visitassero prima un altro sottodominio. Probabilmente le informazioni nel database che mappano le intestazioni host ai tenant non cambieranno molto spesso, quindi puoi memorizzarle nella cache e non è necessaria una ricerca nel database per ogni richiesta.

Altri suggerimenti

È possibile creare un controller di base che abbia fornito il ViewData corretto alla vista della pagina principale MVC, quindi derivare ciascuno dei controller effettivi da quello. Se inserisci la logica nel metodo ActionExecuting, dovresti essere in grado di generare un'eccezione o reindirizzare a una pagina di errore, se necessario.

Anche tu stai pensando " WebForms " e non abbastanza MVC. Una pagina master è solo un wrapper della tua vista e dovrebbe contenere solo html di layout. Puoi inviare cose al tuo padrone, ma è una strada a senso unico e dovresti cercare di ottenere visualizzazioni agnostiche. In conclusione: dimentica gli eventi che WebForms ha avuto in quanto non verranno utilizzati qui.

Dato che hai a che fare con le intestazioni Host, suppongo che potresti metterlo nel Global.asax ... fantastico, ora sono confuso: P

Codice rubato da http://forums.asp.net/t/1226272.aspx

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            string host = string.Empty;

            if (this.Request.ServerVariables["HTTP_HOST"] == this.Request.Url.DnsSafeHost)
            {
                host = this.Request.Url.DnsSafeHost;
            }
            else
            {
                Regex regex = new Regex("http://[^/]*.host/([^/]*)(/.*)");
                Match match = regex.Match(this.Request.Url.AbsoluteUri);

                if (match.Success)
                {
                    host = match.Groups[1].Value;
                    Context.RewritePath(match.Groups[2].Value);
                }
            }

            // Match the host with the portal in the database
            ...
        } 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top