Web-API in MVC-Lösung in separatem Projekt

88

Ich erstelle ein neues MVC4-Projekt, und die Forschung hat mich zu der Überzeugung geführt, dass die Kommunikation von Javascript zur Serverseite jetzt besser über das Web-API-Framework als über Controller-Aktionen erreicht werden kann. Ist mein Verständnis in dieser Hinsicht richtig?

Ich gehe davon aus, dass ich alle meine Attribute usw. zwischen Web-API und MVC-Controllern teilen kann. Auf den ersten Blick scheint dies für mich keine massive Änderung zu sein.

Wenn ich Anwendungen einrichte, teile ich Komponenten gerne in Projekte auf. Mein Plan war ein MVC-Projekt und ein Web-API-Projekt. Aber ich bin auf Probleme gestoßen. Zum Beispiel habe ich 2 Apps als solche, separate Routing-Einrichtung usw. usw. erhalten.

Meine Frage ist also, ob in einer MVC-Anwendung das Web-API-Framework im selben Projekt enthalten sein sollte oder ob die Web-API in ein eigenes Projekt unterteilt werden sollte, um die Probleme zu umgehen.

Amateur
quelle

Antworten:

110

Leider irren Sie sich darin - ich gehe davon aus, dass ich alle meine Attribute usw. zwischen Web-API und MVC-Controllern teilen kann. Auf den ersten Blick scheint es für mich keine massive Änderung zu sein.

Viele der von Web API und MVC verwendeten Konzepte sind zwar auf den ersten Blick ähnlich, aber tatsächlich nicht kompatibel. Beispielsweise sind Web-API-Attribute System.Web.Http.Filters.Filterund MVC-Attribute System.Web.Mvc.Filter- und sie sind nicht austauschbar.

Gleiches gilt für viele andere Konzepte - Modellbindung (völlig unterschiedliche Mechanismen), Routen (Web-API verwendet HTTPRoutes, keine Routen, obwohl beide auf derselben zugrunde liegenden RouteTable arbeiten), Abhängigkeitsauflöser (nicht kompatibel) und mehr - obwohl ähnlich auf der Oberfläche, sind in der Praxis sehr unterschiedlich. Darüber hinaus verfügt die Web-API nicht über ein Konzept von Bereichen.

Wenn Sie letztendlich nur eine "neue, trendige" Art der Bereitstellung von JSON-Inhalten erreichen möchten, überlegen Sie zweimal, bevor Sie diesen Weg beschreiten. Ich würde auf keinen Fall empfehlen, vorhandenen Code umzugestalten, es sei denn, Sie möchten HTTP wirklich nutzen und Ihre App auf REST-artige Weise erstellen.

Es hängt wirklich davon ab, was Sie bauen. Wenn Sie ein neues Projekt starten und lediglich JSON bereitstellen müssen, um Ihre Web-App zu vereinfachen - vorausgesetzt, Sie sind bereit, mit möglicherweise doppeltem Code zu leben (wie den oben genannten), kann die Web-API problemlos darin gehostet werden das gleiche Projekt wie ASP.NET MVC.

Ich würde die Web-API nur dann in ein separates Projekt aufteilen, wenn Sie eine geeignete API für Ihren Onlinedienst erstellen - möglicherweise zur Verwendung durch externe Kunden oder durch verschiedene Geräte -, z. B. zum Betanken Ihrer mobilen Apps.

Filip W.
quelle
2
+1 Ausgezeichnete Antwort. Anfangs dachte ich, dass sowohl MVC als auch WebAPI einen Teil des Codes gemeinsam nutzen könnten, insbesondere bei Filtern, Modellbindungen usw., aber sie sind völlig unterschiedlich.
VJAI
5
Ja, in einem solchen Szenario starten Sie einfach ein neues MVC4-Projekt in Visual Studio und wählen Sie einfach die Web-API aus, wenn Sie zur Eingabe einer Projektvorlage (zweiter Bildschirm) aufgefordert werden. Dadurch wird die Web-API von Nuget installiert, und in dem von Ihnen beschriebenen Fall sollte dies vollkommen in Ordnung sein. Sie erhalten eine separate Web-API-Konfigurationsdatei, die an Global.asax angeschlossen ist. Darüber hinaus möchten Sie die API-Controller möglicherweise in einen separaten Ordner unterteilen (standardmäßig befinden sie sich zusammen mit MVC-Controllern). Schließlich sind die Standardrouten offensichtlich separat konfiguriert und stören sich nicht gegenseitig
Filip W
9
Ich wünschte, mein Lead hätte diesen Beitrag gelesen, bevor er unser aktuelles Projekt entworfen hat.
Billdr
2
@FilipW Danke für gute Erklärungen. Ich habe auch eine MVC-Anwendung und werde WebAPI2 für die Verwendung des Dienstes für Android-Anwendungen verwenden. Andererseits ist, wie David Peden weiter unten sagt, Sicherheit, Wartung und Bereitstellung auch sehr wichtig, wenn Sie sich entscheiden, ein neues separates Projekt für WebAPI zu erstellen. Was würden Sie in diesem Fall unter Berücksichtigung dieser Punkte vorschlagen? So erstellen Sie ein neues separates Projekt für WebAPI oder verwenden das aktuelle MVC-Projekt? Danke im Voraus.
Jack
1
Sehr gut "Ich würde die Web-API nur dann in ein separates Projekt aufteilen, wenn Sie eine geeignete API für Ihren Onlinedienst erstellen - möglicherweise zur Verwendung durch externe Kunden oder durch verschiedene Geräte -, z. B. zum Betanken Ihrer mobilen Apps." Schlagen Sie den Nagel auf den Kopf und machen Sie es einfach zu bestimmen, wie es geht.
Ozzy432836
27

IMO, Sicherheit und Bereitstellung sollten Ihre Entscheidung bestimmen. Wenn Ihre MVC-App beispielsweise die Formularauthentifizierung verwendet, Sie jedoch die Standardauthentifizierung (mit SSL) für Ihre API verwenden möchten, erleichtern separate Projekte Ihr Leben. Wenn Sie Ihre Website unter www.example.com hosten möchten, Ihre API jedoch als api.example.com (im Vergleich zu www.example.com/api) hosten möchten, erleichtern separate Projekte Ihr Leben. Wenn Sie Ihre Projekte trennen und entsprechend unterdomainieren und beabsichtigen, Ihre eigene API aus Ihrer MVC-App zu nutzen, müssen Sie herausfinden, wie Sie mit dem Problem der gleichen Ursprungsrichtlinie für clientseitige Aufrufe Ihrer API umgehen können . Übliche Lösungen hierfür sind die Nutzung von jsonp oder CORS (vorzugsweise wenn möglich).

Update (26.03.2013): Offizielle CORS-Unterstützung kommt: http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API

David Peden
quelle
Ich versuche, mich mit den Problemen zu befassen, die mit der Entscheidung verbunden sind, die Web-API in meine MVC-Anwendung zu integrieren oder als separates Projekt zu verwenden. Ich konnte eine Web-API-HelloWorld-App erfolgreich in einer Subdomain auf meinem Webhost bereitstellen. In diesem separaten Projekt werde ich wahrscheinlich das Modell aus meiner MVC-Webanwendung verwenden und Code in diesem separaten Projekt aufrufen. Es scheint vielleicht einfacher zu sein, diesen Weg eines separaten Projekts zu beschreiten, aber auf welche Probleme könnte ich mit diesem Ansatz stoßen?
Ciaran Gallagher
2
Persönlich würde ich Ihr Ansichtsmodell nicht als DTO für Ihre API verwenden. Ich würde erwarten, dass diese Entscheidung Ihnen später ernsthafte Schmerzen bereiten wird, da Ihre Ansichtsmodelle und API-Signaturen voneinander abweichen. SoC ( en.wikipedia.org/wiki/Separation_of_concerns ) ist sehr wichtig.
David Peden
@DavidPeden Sie schlagen vor, ein neues separates Projekt für WebAPI zu erstellen. Ist das wahr? Auf der anderen Seite werde ich ein neues separates Projekt für WebAPI erstellen (ich habe derzeit eine UI-Schicht (MVC) und eine Datenschicht (Klassenbibliothek) in meiner Anwendung. Daher verwende ich auch DI, aber ich frage mich, ob ich es verwenden kann Die gleichen Entitäten, Repositorys, Schnittstellen und abstrakten Klassen in der Datenschicht für das neu erstellte WebAPI-Projekt. Ich muss nur WebAPI-Controller erstellen oder auch alle (Entitäten, Repositorys, Schnittstellen und Zusammenfassung) Klassen) wieder für die WebAPI? Hilfe bitte?
Jack
1
@ H.Johnson Es ist schwierig, allgemeine Ratschläge zu geben, die sinnvoll sind, aber es scheint, als würden Sie von einer Anwendungsdienstschicht profitieren, die Ihre Entitäten und Repositorys kapselt, die von beiden Benutzeroberflächen (MVC und API) genutzt werden können.
David Peden
9

Nach einiger Erfahrung (Erstellen von API für Apps und für MVC). Ich mache meistens beides.

Ich erstelle ein separates Projekt für API-Aufrufe, die von anderen Clients oder anderen Geräten (Android / IOS-Apps) stammen. Einer der Gründe ist, dass die Authentifizierung unterschiedlich ist und auf Token basiert (um sie zustandslos zu halten). Ich möchte dies nicht in meiner MVC-Anwendung mischen.

Für meine Javascript / JQuery-API-Aufrufe an meine MVC-Anwendung halte ich die Dinge gerne einfach, sodass ich eine Web-API in meine MVC-Anwendung einbinde. Ich beabsichtige nicht, eine tokenbasierte Authentifizierung mit meinen Javascript-API-Aufrufen durchzuführen, da sich diese in derselben Anwendung befindet. Ich kann nur ein [authorize]Attribut auf einem API-Endpunkt verwenden. Wenn ein Benutzer nicht angemeldet ist, erhält er die Daten nicht.

Wenn Sie mit Einkaufswagen arbeiten und den Warenkorb eines Benutzers in einer Sitzung speichern möchten (während Sie nicht angemeldet sind), müssen Sie dies auch in Ihrer API haben, wenn Sie Produkte über Ihren Javascript-Code hinzufügen / löschen. Dies macht Ihre API sicher zustandsbehaftet, verringert aber auch die Komplexität Ihrer MVC-API.

CularBytes
quelle
4
Nun @Dimi, das ist eine nutzlose Bearbeitung, um ein paar Stimmen zu bekommen ... Wie kann ich diese ablehnen?
CularBytes
Tun Sie, was Sie wollen. Ich bearbeite nicht nach Stimmen, aber für den besten Look nehme ich an. Gehen Sie geradeaus.
Entwickler
3
@CularBytes Sie können Änderungen nicht ablehnen, aber Sie können sie erneut bearbeiten und die Änderungen rückgängig machen. Dies erfordert einen Peer-Review-Prozess unter 2.000 Wiederholungen, aber Sie haben genug Mitarbeiter, um dies sofort zu tun. Ich bin damit einverstanden, dass die Bearbeitung keinen Wert hinzugefügt hat und sie für Sie zurückgesetzt hat.
Dan Bechard
5

Ich habe kürzlich fast das Gleiche getan: Ich habe mit einem neuen MVC 4-Webanwendungsprojekt begonnen, bei dem die Web-API-Vorlage in VS2012 ausgewählt wurde.

Dadurch wird eine Web-API erstellt, die in derselben Anwendung wie MVC gehostet wird.

Ich wollte die ApiController in ein separates Klassenbibliotheksprojekt verschieben. Das war ziemlich einfach, aber die Lösung war etwas versteckt.

Fügen Sie in AssemblyInfo.cs des MVC 4-Projekts eine ähnliche Codezeile hinzu

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

Jetzt benötigen Sie die Klasse LibraryRegistrator (Sie können sie beliebig benennen).

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

Fügen Sie im MVC 4-Projekt auch einen Verweis auf die Api-Bibliothek hinzu.

Jetzt können Sie Api-Controller zu Ihrer eigenen Klassenbibliothek (yourown.dll) hinzufügen.

Fanvabra
quelle
2

Selbst wenn Ihr Projekt so komplex ist, dass zwei "Frontends" erforderlich sind, würde ich Webapi nur als letzten Ausweg in ein separates Projekt aufteilen. Sie haben Kopfschmerzen bei der Bereitstellung und es ist für einen Neuling schwierig, die Struktur Ihrer Lösung zu verstehen. Ganz zu schweigen von Routing-Problemen.

Ich würde versuchen, den system.web-Namespace in der einen "Präsentationsschicht" isoliert zu halten. Trotz der WebAPI nicht in der Präsentations ist es immer noch ein Teil der Schnittstelle der Anwendung. Solange Sie die Logik in Ihrer Domäne und nicht in Ihren Controllern behalten, sollten Sie nicht auf zu viele Probleme stoßen. Vergessen Sie auch nicht, Bereiche zu nutzen.

Nick
quelle
1
Mein Hauptgrund für den Wunsch nach separaten Projekten ist, dass die API nicht wirklich Front-End ist. Es ist Mittelklasse.
Lordcheeto
6
"Es wäre für einen Neuling schwer zu verstehen" ist kein guter Grund, einen Ansatz dem anderen vorzuziehen. Halten Sie es einfach, wenn möglich, sicher, aber komplexe Anforderungen erfordern oft komplexe Lösungen. Anstatt dummen Code für Neulinge zu schreiben, sollten wir Neulinge darin schulen, intelligenten Code zu verstehen und zu schreiben.
Dan Bechard
0

Zusätzlich zum Einrichten der separaten DLL für das Web.Api.

Nur ein Vorschlag:

  1. Erstellen Sie das Projekt
  2. Nugget WebActivatorEx
  3. Erstellen Sie eine Klassenmethode, die bei app_start aufgerufen werden soll

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

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

  4. Registrieren Sie eine web.api-Route innerhalb der Startmethode

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

  5. Verweisen Sie das Projekt auf das Webprojekt. um die Startmethode zu aktivieren.

Hoffe das hilft.

jayson.centeno
quelle
0

Ich habe versucht, die API-Controller in ein neues Projekt aufzuteilen. Ich habe lediglich ein neues Bibliotheksprojekt erstellt und die Controller in den Ordner API verschoben. Fügen Sie dann die Referenz des Bibliotheksprojekts zum MVC-Projekt hinzu.

Die webAPI-Konfiguration verbleibt im MVC-Projekt selbst. Es funktioniert gut.

jaicind
quelle