API Web nella soluzione MVC in un progetto separato


88

Sto creando un nuovo progetto MVC4 e la ricerca mi ha portato a credere che la comunicazione da javascript al lato server sia ora ottenuta meglio attraverso il framework API web piuttosto che le azioni del controller. La mia comprensione è corretta su questo?

Presumo di poter condividere tutti i miei attributi, ecc. Tra l'API Web e i controller MVC, quindi a prima vista non sembra un cambiamento enorme per me.

Quando imposto le applicazioni, mi piace suddividere i componenti in progetti. Il mio piano era di avere un progetto MVC e un progetto API web. Ma sono incappato in problemi. Ad esempio, mi sono ritrovato con 2 app in quanto tali, configurazione separata del routing ecc. Ecc.

Quindi la mia domanda è: in un'applicazione MVC il framework dell'API Web dovrebbe trovarsi all'interno dello stesso progetto o l'API Web dovrebbe essere separata in un progetto a sé stante e aggirare i problemi?

Risposte:


110

Sfortunatamente ti sbagli su questo - presumo di poter condividere tutti i miei attributi ecc. Tra web api e controller mvc quindi, a prima vista, non sembra un cambiamento enorme per me.

Molti dei concetti utilizzati da Web API e MVC, anche se simili a prima vista, in realtà non sono compatibili. Ad esempio, gli attributi dell'API Web sono System.Web.Http.Filters.Filtere gli attributi MVC sono System.Web.Mvc.Filtere non sono intercambiabili.

Lo stesso vale per molti altri concetti: associazione di modelli (meccanismi completamente diversi), rotte (l'API Web utilizza HTTPRoutes non rotte, anche se entrambe operano sulla stessa RouteTable sottostante), risolutore di dipendenze (non compatibile) e altro ancora, anche se simile sul superficie, sono molto diversi nella pratica. Inoltre, l'API Web non ha un concetto di aree.

In definitiva, se tutto ciò che stai cercando di fare è avere un modo "nuovo e alla moda" di offrire contenuti JSON, pensaci due volte prima di intraprendere questa strada. Certamente non consiglierei il refactoring di qualsiasi codice esistente a meno che tu non stia davvero cercando di abbracciare HTTP e costruire la tua app in modo RESTful.

Dipende tutto da cosa stai costruendo. Se stai iniziando un nuovo progetto e tutto ciò di cui hai bisogno è fornire un po 'di JSON per facilitare la tua app web, a condizione che tu sia disposto a convivere con un codice potenzialmente duplicato (come le cose che ho menzionato sopra), l'API Web potrebbe essere facilmente ospitata all'interno lo stesso progetto di ASP.NET MVC.

Separerei l'API Web in un progetto separato solo se intendi creare un'API adeguata per il tuo servizio online, magari da utilizzare da clienti esterni o da vari dispositivi, come alimentare le tue app mobili.


2
+1 Ottima risposta. Inizialmente pensavo che sia MVC che WebAPI potessero condividere parte del codice, specialmente nel caso di filtri, associazione di modelli, ecc. Ma sono totalmente diversi.
VJAI

5
Sì, in tale scenario è sufficiente avviare un nuovo progetto MVC4 in Visual Studio e, quando viene richiesto un modello di progetto (seconda schermata), selezionare semplicemente API Web. Questo installerà l'API Web da Nuget e nel caso che hai descritto dovrebbe essere perfettamente a posto. Quello che ottieni è un file di configurazione dell'API Web separato collegato a Global.asax. Inoltre, potresti voler separare i controller API in una cartella separata (per impostazione predefinita sono insieme ai controller MVC). Infine, le rotte di default sono ovviamente configurate separatamente e non interferiscono tra loro
Filip W

9
Vorrei che il mio lead avesse letto questo post prima di progettare il nostro progetto attuale.
Billdr

2
@FilipW Grazie per le buone spiegazioni. Ho anche un'applicazione MVC e userò WebAPI2 per utilizzare il servizio per le applicazioni Android. D'altra parte, come dice David Peden di seguito, anche la sicurezza, la manutenzione e la distribuzione sono molto importanti quando si decide di creare un nuovo progetto separato per WebAPI. In tal caso, tenendoli presenti, cosa suggeriresti? Per creare un nuovo progetto separato per WebAPI o utilizzare il progetto MVC corrente? Grazie in anticipo.
Jack

1
Molto buono "Separerei l'API Web in un progetto separato solo se intendi creare un'API adeguata per il tuo servizio online, magari da utilizzare da clienti esterni o da vari dispositivi, come alimentare le tue app mobili". colpisce il chiodo sulla testa e rende facile determinare in che modo farlo.
ozzy432836

27

IMO, sicurezza e implementazione dovrebbero guidare la tua decisione. Ad esempio, se la tua app MVC utilizza l'autenticazione basata su form ma sei interessato a utilizzare l'autenticazione di base (con SSL) per la tua API, progetti separati ti semplificheranno la vita. Se desideri ospitare il tuo sito su www.example.com ma ospitare la tua API come api.example.com (rispetto a www.example.com/api), progetti separati ti semplificheranno la vita. Se separi i tuoi progetti e li sottodomini di conseguenza e intendi sfruttare la tua API dalla tua app MVC, dovrai capire come affrontare il problema della stessa politica di origine per le chiamate lato client alla tua API. Le soluzioni comuni a questo problema sono sfruttare jsonp o CORS (preferibilmente se puoi).

Aggiornamento (26/03/2013): il supporto ufficiale di CORS è in arrivo: http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API


Sto cercando di capire i problemi relativi alla decisione di integrare l'API Web con la mia applicazione MVC o di averla come progetto separato. Sono stato in grado di distribuire con successo un'app HelloWorld dell'API Web in un sottodominio sul mio host web. Da questo progetto separato, userò probabilmente il modello dalla mia applicazione web MVC e chiamerò il codice in quel progetto separato. Sembra che potrebbe essere più facile seguire questa strada di un progetto separato, ma quali problemi pensi che potrei incontrare con questo approccio?
Ciaran Gallagher

2
Personalmente, non utilizzerei il tuo modello di visualizzazione come DTO per la tua API. Mi aspetto che quella decisione ti causi un serio dolore lungo la strada mentre i tuoi modelli di visualizzazione e le firme API divergono. SoC ( en.wikipedia.org/wiki/Separation_of_concerns ) è molto importante.
David Peden

@DavidPeden Suggerisci di creare un nuovo progetto separato per WebAPI. È vero? D'altra parte, creerò un nuovo progetto separato per WebAPI (attualmente ho un UI Layer (MVC) e Data Layer (Class Library) nella mia applicazione. Quindi, utilizzo anche DI, ma mi chiedo se posso usare le stesse entità, archivi, interfacce e classi astratte nel livello dati per il progetto WebAPI appena creato e l'unica cosa che devo fare è creare controller WebAPI? oppure creo anche tutti (entità, archivi, interfacce e abstract classi) ancora per la WebAPI? Qualche aiuto per favore?
Jack

1
@ H.Johnson È difficile dare consigli generali significativi, ma sembra che potresti trarre vantaggio dall'avere un livello di servizio dell'applicazione che incapsula le tue entità e i tuoi repository che possono essere sfruttati da entrambe le tue interfacce utente (MVC e API).
David Peden

9

Dopo un certo grado di esperienza (creazione di API per app e per mvc). Per lo più faccio entrambe le cose.

Creo un progetto separato per le chiamate API che provengono da altri client o altri dispositivi (app Android / IOS). Uno dei motivi è perché l'autenticazione è diversa, è basata su token (per mantenerla senza stato). Non voglio mischiare questo nella mia applicazione MVC.

Per le mie chiamate api javascript / jquery alla mia applicazione mvc, mi piace mantenere le cose semplici, quindi includo un'api web all'interno della mia applicazione MVC. Non intendo avere un'autenticazione basata su token con le mie chiamate API JavaScript, perché ehi, è nella stessa applicazione. Posso semplicemente usare l' [authorize]attributo su un endpoint API, quando un utente non è connesso, non riceverà i dati.

Inoltre, quando si ha a che fare con i carrelli della spesa e si desidera memorizzare un carrello della spesa di un utente in una sessione (senza aver effettuato l'accesso), è necessario averlo anche nella propria API se si aggiungono / eliminano prodotti tramite il codice javascript. Ciò renderà sicuramente la tua API stateful, ma ridurrà anche la complessità nella tua MVC-API.


4
Bene @Dimi, è una modifica inutile per ottenere dei voti ... Come posso rifiutarli?
CularBytes

Fai quello che vuoi. Non modifico per voti, ma presumo per l'aspetto migliore che ci vuole. Vai avanti.
Sviluppatore

3
@CularBytes Non puoi rifiutare le modifiche, ma puoi modificarle di nuovo e ripristinare le modifiche. Ciò richiede un processo di revisione tra pari con meno di 2.000 ripetizioni, ma hai abbastanza rappresentanti per farlo immediatamente. Sono d'accordo che la modifica non ha aggiunto alcun valore e l'ho ripristinata per te.
Dan Bechard


5

Recentemente ho fatto quasi la stessa cosa: ho iniziato con un nuovo progetto di applicazione Web MVC 4 scegliendo il modello API Web in VS2012.

Questo creerà un'API Web ospitata nella stessa applicazione di MVC.

Volevo spostare gli ApiController in un progetto di libreria di classi separato. Questo è stato abbastanza facile ma la soluzione era un po 'nascosta.

In AssemblyInfo.cs del progetto MVC 4 aggiungere una riga di codice simile

[assembly: PreApplicationStartMethod(typeof(LibraryRegistrator), "Register")]

Ora hai bisogno della classe LibraryRegistrator (sentiti libero di nominarla come vuoi)

public class LibraryRegistrator
    {
        public static void Register()
        {
            BuildManager.AddReferencedAssembly(Assembly.LoadFrom(HostingEnvironment.MapPath("~/bin/yourown.dll")));
        }
    }

Nel progetto MVC 4 aggiungere anche il riferimento alla libreria Api.

Ora puoi aggiungere controller Api alla tua libreria di classi separata (yourown.dll).


2

Anche se il tuo progetto è così complesso da giustificare due "front-end", prenderei comunque in considerazione la possibilità di suddividere webapi in un progetto separato come ultima risorsa. Avrai problemi di distribuzione e sarebbe difficile per un principiante capire la struttura della tua soluzione. Per non parlare dei problemi di routing.

Mirerei a mantenere il namespace system.web isolato nell'unico "livello di presentazione". Nonostante il webapi non sia presentazionale , fa comunque parte dell'interfaccia della tua applicazione. Finché mantieni la logica nel tuo dominio e non nei tuoi controller non dovresti incorrere in troppi problemi. Inoltre, non dimenticare di utilizzare le aree.


1
Il mio motivo principale per desiderare progetti separati è che l'API non è realmente front-end. È di livello intermedio.
lordcheeto

6
"Sarebbe difficile da capire per un principiante" non è un ottimo motivo per scegliere un approccio rispetto all'altro. Mantenerlo semplice quando possibile, certo, ma le esigenze complesse spesso richiedono soluzioni complesse. Piuttosto che scrivere codice stupido per soddisfare i neofiti, dovremmo addestrare i neofiti a comprendere e scrivere codice intelligente.
Dan Bechard

0

Oltre a configurare la DLL separata per Web.Api.

Solo un suggerimento:

  1. Crea il progetto
  2. Nugget WebActivatorEx
  3. Crea un metodo di classe da richiamare su app_start

    [assembly: WebActivatorEx.PostApplicationStartMethod (typeof (API.AppWebActivator), "Start")]

    [assembly: WebActivatorEx.ApplicationShutdownMethod (typeof (API.AppWebActivator), "Shutdown")]

  4. Registra un percorso web.api all'interno del metodo di avvio

    public static void Start () {GlobalConfiguration.Configure (WebApiConfig.Register); }

  5. Fare riferimento al progetto al progetto Web. per attivare il metodo di avvio.

Spero che questo ti aiuti.


0

Ho provato a dividere i controller API in un nuovo progetto. Tutto quello che ho fatto è creare un nuovo progetto di libreria, spostando i controller all'interno della cartella denominata API. Quindi aggiunto il riferimento del progetto di libreria al progetto MVC.

La configurazione webAPI viene lasciata nel progetto MVC stesso. Funziona bene.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.