2011-10-23 5 views
16

so come ottenere il nome del controller di correnteAsp.net MVC 3 ottenere l'istanza del regolatore di corrente (non solo il nome)

HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString(); 

Ma esiste un modo per ottenere l'istanza del regolatore di corrente in qualche classe (non in un'azione e non in una vista)?

+1

Dove? In un modello? In una vista? Ovviamente se stai facendo un'azione puoi usare questo per fare riferimento al tuo controller, ma suppongo che non sia così :). – BigMike

+0

in alcune classi (non in un'azione e non in una vista) – Alexandre

+0

poiché in pattern MVC si è obbligati a partecipare a un'azione, a meno che non ci si trovi nel flusso del metodo di alcuni modelli di dati o in qualche aiuto. Solo per evitare riferimenti null aggiungerei un parametro al metodo di classe per il controller, quindi tracciamo dove inizia e passa il flusso. – BigMike

risposta

22

Per impostazione predefinita è possibile accedere solo allo Controller corrente all'interno di un controller con o all'interno di una vista con ViewContext.Context. Per accedervi da qualche classe è necessario implementare un custom ControllerFactory che memorizza l'istanza del controller da qualche parte e recuperarla da lì. Ad esempio, nel Request.Items:

public class MyControllerFactory : DefaultControllerFactory 
{ 
    public override IController CreateController(RequestContext requestContext, string controllerName) 
    { 
     var controller = base.CreateController(requestContext, controllerName); 
     HttpContext.Current.Items["controllerInstance"] = controller; 
     return controller; 
    } 
} 

Poi registrazione nel vostro Application_Start:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory()); 

e si può ottenere l'istanza di controllo in seguito:

public class SomeClass 
{ 
    public SomeClass() 
    { 
     var controller = (IController)HttpContext.Current.Items["controllerInstance"]; 
    } 
} 

ma vorrei trovare un altro modo passare l'istanza del controller alla mia classe invece di questa soluzione "hacky".

+6

Probabilmente dovresti cambiare HttpContext.Current.Session ["controllerInstance"] in HttpContext.Current.Items ["controllerInstance"] poiché la sessione potrebbe finire nel database con determinate configurazioni. – John

0

qualcuno dovrà correggermi se quello che sto facendo è dannoso per l'intero ciclo di vita Asp.Net pagina/qualunque cosa, ma sicuramente si può fare questo:

controller

ViewBag.CurrentController = this; 

In considerazione

var c = ViewBag.CurrentController; 
var m1 = BaseController.RenderViewToString(c, "~/Views/Test/_Partial.cshtml", null); 

Nel mio caso, ho avuto un controller di base che estende tutti i controller. In quel controller di base viveva un metodo statico chiamato RenderViewToString e richiedeva un controller. Dato che ho pensato di istanziare una nuova istanza di un controller vuoto a questo punto per c, l'ho appena inviato alla vista nell'incantevole contenitore ViewBag che esiste nel mondo di Asp.Net MVC. Per ragioni a cui non potevo entrare ora, non riuscivo a recuperare la stringa nel controller e rimandarla alla vista (era quello che avevo fatto prima che i requisiti cambiassero).

Il motivo per cui l'ho fatto in questo modo è in altri linguaggi come PHP e JS, ci sono modi semplici simili per trasferire le classi in giro.

Problemi correlati