Attualmente sto lavorando a un progetto MVC e sto cercando di capire come potrei andare ad estendere i percorsi di un controller esistente all'interno di un'area, in particolare da un altro progetto.Override/Estensione di un controller MVC/Area
Per esempio, ho un controller con una superficie che appare come il seguente:
namespace MyProject.Areas.Foo.Controllers
{
[Authorize]
public class FooController : ApplicationController
{
//code
}
}
E quello che vorrei fare, è in grado di definire un altro controller, all'interno di un progetto separato che potrebbe estendere questo modo:
namespace MyOtherProject.Areas.Foo.Custom.Controllers
{
public class FooController : ApplicationController
{
public string Bar()
{
return "Bar";
}
}
}
in sostanza, vorrei i controllori a quasi la funzione come se stavo usando la parola partial
(in modo che potessi chiamare qualsiasi delle azioni in originale o quello nuovo).
Il principale problema
Quello che sto davvero cercando di realizzare è che ho un progetto principale con diverse aree e un'altra zona della mia soluzione con varie cartelle del cliente. Voglio essere in grado di estendere sostanzialmente i controller di base per il mio progetto principale e aggiungere azioni specifiche del client all'interno di queste cartelle client in modo che possano essere utilizzate nel progetto principale. Lo sto già facendo con determinate MVC Views, ma speravo di poterlo realizzare anche con i controller.
Quello che ho provato
- Ho provato ad utilizzare la parola chiave
partial
su entrambe le dichiarazioni della classe, ma dal momento che sono in diversi progetti/assemblee, non credo che le opere. - Ho definito un evento di build che spostava la DLL personalizzata nella directory
bin
del progetto MVC principale, ma non sembrava funzionare come previsto. - Ho provato vari approcci per l'ereditarietà, sperando che la nuova classe venisse rilevata, ma quelli non funzionavano (ha ricevuto l'errore di dichiarazione del controller duplicato).
- Ho letto di provare a utilizzare un numero personalizzato
ControllerFactory
ma non ero sicuro di come implementarlo. - Ho provato a definire i parametri di routing del namespace personalizzati nella sezione AreaRegistration per prelevare il nuovo controller come nell'esempio seguente.
Routing Esempio (AreaRegistration)
context.MapRoute(
AreaName,
String.Format("{0}/{{action}}/{{id}}", AreaName),
new { controller = AreaName, action = "Index", id = UrlParameter.Optional },
new[] {
String.Format("MyProject.Areas.{0}.Controllers", AreaName),
String.Format("MyOtherProject.Areas.{0}.Custom.Controllers", AreaName)
}
);
Aggiornamento
ho tentato un approccio seen here come per alcune delle discussioni commenti che ha coinvolto semplicemente la manipolazione di questo attraverso l'ereditarietà:
// Main Project
namespace MyProject.Areas.Foo.Controllers
{
[Authorize]
public class FooController : ApplicationController
{
public ActionResult Index()
{
return View();
}
}
}
// This is in another project/namespace/assembly
namespace MyOtherProject.Foo.Controllers
{
public class CustomFooController : MyProject.Areas.Foo.Controllers.FooController
{
[Route("Foo/Bar")]
public string Bar()
{
return "Bar";
}
}
}
Così i miei passi attuali sono i seguenti:
- ereditati dalla base
FooController
nel progetto principale all'interno di un altro progetto/soluzione. - Impostare il routing degli attributi per accedere al controller personalizzato per evitare percorsi in conflitto dal progetto principale.
- Creato un evento di build che sposta la DLL personalizzata nel progetto principale una volta creato (quindi sarà accessibile) dal nuovo progetto personalizzato.
Questo non sembra fare alcuna differenza. Ho provato ad andare sull'URL Foo/Bar
ma ho appena lanciato un 404 come se non lo vedesse affatto. Il file CustomFooController.cs
si trova nel proprio progetto separato ed è solo un file di classe e non un progetto MVC. È corretto? Devo impostare le regole di routing nel progetto principale?
Cosa c'è di sbagliato con l'utilizzo di eredità? Nel progetto B, includere un riferimento a project-main, quindi controller-B ereditato da controller-main. In alternativa, utilizzare una classe comune come base e configurare di conseguenza i percorsi. –
Quindi dovrei ereditare il mio controller Project B da 'FooController' nel Progetto A? In tal caso, in che modo ciò influenzerebbe il mio routing, dal momento che voglio essere in grado di utilizzare lo stesso routing di base, ovvero "Foo/ProjectAAction" o "Foo/ProjectBAction". Funzionerebbe ancora? –
Tutte le rotte verso il controllore-B otterrebbero anche azioni main controller perché fanno parte del controller-B per ereditarietà. cioè i tuoi percorsi non sarebbero a conoscenza dei controller principali del progetto –