RESTful XHTML
RESTful Services mit ASP.NET MVC
Aaron Skonnard
Themen in diesem Artikel:
-
REST
-
XHTML
-
XML-Webdienste MVC
|
In diesem Artikel werden die folgenden Technologien verwendet:
REST, XHTML XML-Webdienste
|

Inhalt
A RESTful service ist ein Web von ressourcen, die programme können navigieren.
Beim Entwerfen eines REST-Diensts müssen Sie genau überlegen, wie Ihr Web funktioniert.
Dies bedeutet entwerfen Ressource Darstellungen mit Verknüpfungen, die die Navigation, Eingabe irgendwie und berücksichtigen wie Consumer den Dienst zur Laufzeit navigieren werden Dienst beschreibt erleichtern.
Diese Dinge rechten Abrufen häufig übersehen, jedoch sind zentrale Realisierung das volle Potenzial, das Rest zu bieten hat.
Heute navigieren Menschen Websites mithilfe von Webbrowsern, die wissen, wie HTML und andere beliebten Inhaltstypen zu rendern.
HTML enthält die Syntax und Semantik zum Einrichten von Verknüpfungen zwischen Ressourcen (< a > Element) und für beschreiben und Senden von Anwendung Eingaben (<form> und <input> Elemente).
Wenn ein Benutzer auf ein <a> klicktElement in der gerenderten Seite weiß der Browser eine HTTP GET-Anforderung für die Zielressource ausstellen und Rendern der Antwort.
Wenn ein Browser < Formular > entdecktElement, er weiß, wie die Formularbeschreibung in einer Benutzeroberfläche darstellen, die der Benutzer ausfüllen und Absenden mit einem kann Get- oder POST-Anforderung.
Wenn der Benutzer eine Absenden-Schaltfläche klickt, wird der Browser die Daten codiert und sendet die angegebene Anforderung.
Diese beiden Funktionen sind größtenteils für den Erfolg der im Web verantwortlich.
Mithilfe von Verknüpfungen in Verbindung mit der universellen HTTP-Schnittstelle ermöglicht es zum Umleiten von Anforderungen an neue Speicherorte über einen Zeitraum und bestimmte Aspekte der Sicherheit im Handumdrehen ändern, ohne den Clientcode.
Eine Standardmethode für Formulare bedeutet, dass Sie können hinzufügen oder input Eigenschaften entfernen und Standardwerte, erneut ohne den Clientcode geändert.
Beide Funktionen sind sehr nützlich zum Erstellen von Anwendungen, die Zeit weiterentwickeln.
Die REST-Dienste sollten auch irgendwie diese beiden Funktionen über alle Ressource-Darstellung bereitstellen, die Sie verwenden möchten.
Z. B. Wenn Sie eine benutzerdefinierte XML-Dialekt für Ihren Dienst entwerfen, sollten Sie wahrscheinlich Lieferumfang Einrichten Ihrer eigenen Elemente für Verknüpfungen einrichten und beschreiben Dienst Eingaben, die Kunden über Ihre Website führt.
Oder Sie können einfach XHTML verwenden.
Die meisten Entwickler nicht sofort XHTML als eine Option für "Dienste", in Betracht ziehenaber das ist tatsächlich eine der Möglichkeiten für ihn vorgesehen wurde.
XHTML-Dokumente sind definitionsgemäß wohlgeformtes XML, die automatische Verarbeitung mithilfe von standardmäßigen XML-APIs ermöglicht.
Und da XHTML auch HTML ist, es kommt mit < a >, < Formular > und < input >Elemente für die Modellierung Link Navigations- und Dienst eingeben wie zuvor beschrieben.
Das einzige, was, das etwas seltsam an zuerst ist wie benutzerdefinierte Datenstrukturen modellieren, jedoch können Sie modellieren, Klassen und Felder mit < Div >und < span >Elemente und Auflistungen von Entitäten mit < Ol >und < li >Elemente.
Ich durch dazu weiter unten in Artikel ausführlicher alle werde nötig sind.
Um zusammenzufassen, gibt es mehrere Gründe, XHTML als Standard-Darstellung für den Rest-Dienste in Betracht ziehen.
Erstens können Sie die Syntax nutzen und Semantik für wichtige Elemente wie < a >, < Formular > und < input >anstelle von inventing eigene.
Zweitens müssen Sie mit Diensten landen, die viel wie Sites fühlen, da Sie browsebar von Benutzern und Anwendungen werden.
XHTML-wird noch von einer Person interpretiert, es ist lediglich ein Programmierer während der Entwicklung anstelle eines Benutzers zur Laufzeit.
Dies vereinfacht Dinge im gesamten Entwicklungsprozess und erleichtert es Kunden erfahren Sie, wie der Dienst funktioniert.
Und schließlich können Sie standard Web Development Frameworks, erstellen die Rest-Dienste nutzen.
XML-Webdienste MVC ist eine solche Framework, die ein grundsätzlich Rest Modell zum Erstellen von XHTML-basierte Dienste bereitstellt.
In diesem Artikel einige XHTML-Entwurfskonzepten durchläuft und zeigt dann zum Erstellen eines vollständigen XHTML-basierte REST-Diensts, das Sie von der Website MSDN Magazin herunterladen können.
XHTML: Darstellung von Daten und links
Bevor ich die Einzelheiten von XML-Webdienste MVC eintauchen, zunächst sehen wir uns wie allgemeine Datenstrukturen und Auflistungen in XHTML darstellen kann.
Dieser Ansatz ist nicht die einzige Möglichkeit, dies zu erreichen, aber es ist relativ allgemein üblich in XHTML-basierten Diensten heute.
In diesem Artikel werde ich zum Implementieren eines Dienstes einfache Textmarke beschreiben.
Der Dienst ermöglicht Benutzern erstellen, abrufen, aktualisieren, und Löschen von Textmarken und navigieren Sie ein Web von Lesezeichen in einer Vielzahl von Möglichkeiten.
Genommen Sie an, Sie haben eine C#-Klasse darstellt, eine Textmarke, die wie folgt aussieht:
public class Bookmark
{
public int Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public string User { get; set; }
}
Ist die erste Frage, wie Sie eine Textmarke Instanz in XHTML darstellen können?
Ein Ansatz besteht darin kombinieren < Div >, < span > und < >Elemente, wobei < Div >Elemente Strukturen darstellen, < span >Elemente repräsentieren Felder und < >Elemente werden Identität und Verknüpfungen zu anderen Ressourcen darstellen.
Zusätzlich können Sie diese Elemente mit XHTML "Klasse" versehen.Attribut, das zusätzliche Typmetadaten bereitzustellen.
Hier ist ein vollständiges Beispiel:
<div class="bookmark">
<span class="bookmark-id">25</span>
<span class="bookmark-title">Aaron's Blog</span>
<a class="bookmark-url-link" href="http://pluralsight.com/aaron"
>http://pluralsight.com/aaron</a>
<span class="bookmark-username">skonnard</span>
</div>
Ist die nächste Frage, verarbeitet der Consumer für diese Informationen?
Da es wohlgeformtes XML Consumer können beliebige XML-API die Textmarke Informationen extrahieren.
Die meisten .NET Programmierer werden wahrscheinlich feststellen, dass XLinq das am häufigsten natürliche Programmiermodell für XHTML programmgesteuert verbrauchen bietet.
Darüber hinaus können Sie eine Schritt weitere wechseln, indem erweitern XLinq mit einige hilfreiche XHTML ausgerichteten Erweiterungsmethoden, die das Programmiermodell noch leichter machen.
In diesem Artikel werde ich eine Reihe von XLinq Erweiterungsmethoden verwenden, die ich im herunterladbaren Beispielcode enthalten haben.
Diese Erweiterungen erhalten Sie eine gute Vorstellung von was möglich ist.
Der folgende Code zeigt wie das Lesezeichen XHTML, die zuvor mit XLinq und einige der Erweiterungen angezeigt:
var bookmarkDetails = bookmarkDoc.Body().Struct("bookmark");
Console.WriteLine(bookmarkDetails["bookmark-id"].Value);
Console.WriteLine(bookmarkDetails["bookmark-url"].Value);
Console.WriteLine(bookmarkDetails["bookmark-title"].Value);
Nun, wenn verbessern, wie dieses Lesezeichen in einem Browser gerendert werden soll, können Sie hinzufügen ein Cascading Stylesheet (CSS) zum Steuern von Rendering der browserspezifischen Details oder einige zusätzliche UI-Elementen und Text, die der Consumer Möglichkeit zum Extrahieren der Daten von Interesse gefährden nicht hinzufügen.
Beispielsweise werden folgende XHTML einfacher für Menschen zum verarbeiten, jedoch noch können Sie das vorherige Codebeispiel .NET um Informationen ohne jegliche Änderung zu verarbeiten:
<h1>Bookmark Details: 3</h1>
<div class="bookmark">
BookmarkID: <span class="bookmark-id">25</span><br />
Title: <span class="bookmark-title">Aaron's Blog</span><br />
Url: <a class="bookmark-url-link" href="http://pluralsight.com/aaron"
>http://pluralsight.com/aaron</a><br />
Username: <span class="bookmark-username">skonnard</span></a><br />
</div>
Auflistungen von Ressourcen nicht schwer zu entweder Modell.
Sie können eine Liste der Textmarken mit einer Kombination von < Ol > darstellen < li > und < >Elemente wie hier gezeigt:
<ol class="bookmark-list">
<li><a class="bookmark-link" href="/bookmarks/1">Pluralsight Home</ a></li>
<li><a class="bookmark-link" href="/bookmarks/2">Pluralsight On- Demand!</a></li>
<li><a class="bookmark-link" href="/bookmarks/3">Aaron's Blog</a></li>
<li><a class="bookmark-link" href="/bookmarks/4">Fritz's Blog</a></li>
<li><a class="bookmark-link" href="/bookmarks/5">Keith's Blog</a></li>
</ol>
Der folgende Code veranschaulicht die Liste der Textmarken in der Konsole zu drucken:
var bookmarks = bookmarksDoc.Body().Ol("bookmark-list").Lis();
bookmarks.Each(bm => Console.WriteLine("{0}: {1}",
bm.Anchor().AnchorText, bm.Anchor().AnchorLink));
Beachten Sie, wie jede < li >enthält eine < a >Element, das mit einer bestimmten Textmarke verknüpft.
Wenn Sie eines der Anchor-Elemente zu navigieren, würden Sie die Textmarke Details Darstellung zuvor gezeigten abrufen.
Sie beginnen, Verknüpfungen zwischen Ressourcen wie folgt definiert, startet der Dienst immer ein Web von verknüpften Ressourcen.
Ist es ziemlich offensichtlich, wie Menschen zwischen Ressourcen einen Webbrowser verwenden, aber wie verbrauchen Anwendungen wechseln können?
Eine verbrauchende Anwendung muss nur programmgesteuert suchen Sie das Anchor-Element von Interesse und anschließend eine GET-Anforderung Zielgruppenadressierung in "Href" angegebene URIDas Attribut.
Diese Details können auch hinter eine Erweiterungsmethode XLinq ausgeblendet werden, die Anchor Navigation kapselt.
Der folgende Code veranschaulicht die auf die erste Textmarke in der Liste Textmarke und dann auf die Textmarke Ziel-URL zu navigieren.
Die resultierende XHTML wird an die Konsole gedruckt:
var bookmarkDoc = bookmarks.First().Anchor().Navigate();
var bookmarkDetails = bookmarkDoc.Body().Struct("bookmark");
var targetDoc = bookmarkDetails.Anchor("bookmark-url-link").Navigate();
Console.WriteLine(targetDoc);
Sobald Sie denken zum Erstellen von Consumern, die den Dienst als Web von Ressourcen zu navigieren, beginnen Sie sind offiziell in eine weitere Rest Möglichkeit vorstellen.
XHTML: Eingabe mit darstellt
Nachdem wir sagen ein Consumer ein neues Lesezeichen im System erstellen möchte.
Wie der Consumer ermitteln, welche Daten senden und wie ohne WSDL zu senden?
Die Antwort ist einfach: XHTML-Formulare.
Der Consumer stellt eine GET-Anforderung zuerst der URI zum Abrufen von Formular Lesezeichen erstellen.
Der Dienst gibt ein Formular, die etwa folgendermaßen aussieht:
<h1>Create Bookmark</h1>
<form action="/bookmark/create" class="create-bookmark-form" method="post">
<p>
<label for="bookmark-title">Title:</label><br />
<input id="bookmark-title" name="bookmark-title" type="text" value="" />
</p>
<p>
<label for="bookmark-url">Url:</label><br />
<input id="bookmark-url" name="bookmark-url" type="text" value="" />
</p>
<p><input type="submit" value="Create" name="submit" /></p>
</form>
Das Formular beschreibt, wie eine HTTP POST-Anforderung für ein neues Lesezeichen erstellen erstellt wird.
Das Formular gibt an, dass Sie die Lesezeichen-Titel und Url Textmarke Felder bieten müssen.
In diesem Beispiel Lesezeichen-Id wird automatisch während der Erstellung und Lesezeichen-Benutzername wird von die Identität des angemeldeten Benutzers abgeleitet werden.
Das Formular teilt Sie auch, um senden, benötigen Sie und wie Sie Sie senden.
Wenn dieses Formular in einem Browser gerendert wird, kann einfach einen Menschen füllen Sie das Formular und klicken Sie auf senden, um ein neues Lesezeichen erstellen.
Eine verbrauchende Anwendung wird im Wesentlichen das gleiche Absenden des Formulars programmgesteuert.
Erneut kann diesen Vorgang einfacher mithilfe erstellt werden einige formularbasierte Erweiterungsmethoden, die hier gezeigte:
var createBookmarkForm = createBookmarkDoc.Body().Form("create-bookmark- form");
createBookmarkForm["bookmark-title"] = "Windows Live";
createBookmarkForm["bookmark-url"] = "http://live.com/";
createBookmarkForm.Submit();
Wenn dieser Code ausgeführt wird, generiert die Submit-Methode eine HTTP POST-Anforderung "Aktion" ZielgruppenadressierungURL und die Eingabefelder werden zusammen als eine URL-codierte Zeichenfolge (Application/X-Www-Form-Urlencoded) formatiert.
Am Ende ist es nicht anders mithilfe des Browsers, das Ergebnis ist ein neues Lesezeichen.
Obwohl heutigen Browsern nur für die Formularmethode GET und POST unterstützen, wird nichts Sie von der Angabe auch PUT beendet oder das Formular "Methode" DELETEWenn Nonbrowser Consumer abzielt.
Die Übermittlung Erweiterung-Methode führt gleichermaßen gut für alle HTTP-Methode Sie angeben.
Informationen zum Verständnis der ASP.NET MVC-Architektur
Die XML-Webdienste MVC-Architektur basiert auf das beliebte Modell-Ansicht-Controller-Entwurfsmuster, die für die Jahrzehnte um wurde.
Abbildung 1 veranschaulicht die verschiedenen XML-Webdienste MVC-Komponenten und deren Beziehungen zu anderen.
Im Lieferumfang von XML-Webdienste MVC ist ein Routingmodul, die vor der anderen MVC-Komponenten befindet.
Das Routingmodul empfängt eingehende HTTP-Anforderungen und leitet diese an eine Controller-Methode.
Das Routingmodul beruht auf einem zentralen Satz von Routen, die Sie in der Datei Global.asax definieren.
Abbildung 1 XML-Webdienste MVC Architektur
Die zentralisierten Routen definieren Zuordnungen zwischen URL-Muster und bestimmte Domänencontroller Methoden und Argumente.
Beim Generieren von Hyperlinks verwenden Sie diese Routen, um die Verknüpfungen entsprechend zu generieren.
Dies erleichtert den URL-Entwurf im gesamten Entwicklungsprozess an einem zentralen Ort ändern.
Es ist die Auftrag des Domänencontrollers, um Informationen aus der eingehenden Anforderung zu extrahieren und die user-defined Modell Schicht interagieren.
Die Modell-Schicht kann nichts (XML-Webdienste SQL, ADO.NET Entity Framework, NHibernate und usw.) – Dies ist die Ebene, die Geschäftslogik ausgeführt und kommuniziert mit der zugrunde liegenden Datenbank.
Beachten Sie, wie das Modell nicht innerhalb des System.Web.Mvc-Namespace ist.
Nach der Controller mithilfe des Modells wird eine Ansicht, Angabe der Ansicht mit Modelldaten für die Ansicht verwenden, während die Ausgabe rendern erstellt.
In den folgenden Abschnitten werde ich durch alle Schritte implementieren einen vollständigen Textmarke Dienst XML-Webdienste MVC-Architektur, die nötig.
Der Dienst unterstützt mehrere Benutzer und öffentlichen und privaten Lesezeichen.
Benutzer können wechseln, alle öffentlichen Lesezeichen und Filtern Sie anhand der Benutzername oder Tags, und Sie können eigene Sammlung von privaten Lesezeichen (CRUD) vollständig verwalten.
Um zu Beginn müssen Sie ein XML-Webdienste MVC-Projekt erstellen.
Finden Sie XML-Webdienste MVC Webanwendung Projekt Vorlage in der Liste der Web-Projekttypen.
Die Standard-Projekt Vorlage bietet Ihnen eine MVC Starter Beispielanwendung auf, der Sie tatsächlich führen können, indem Sie F5 drücken.
Beachten Sie, wie die Lösungsstruktur Verzeichnisse für Modelle, Ansichten und Domänencontroller bereitstellt – Dies ist, platzieren Sie den Code für diese verschiedenen Komponenten.
Standard-Vorlage wird mit zwei Domänencontrollern geliefert: eine für das Verwalten von Benutzerkonten (AccountController) und andere für die Unterstützung der Anforderungen an das Basisverzeichnis (HomeController).
Beide werden in den Lesezeichen-Dienst verwendet.
Implementieren des Modells
Als Erstes auf konzentrieren sollten ist das Modell für den Dienst Textmarke.
Ich eine einfache SQL Server-Datenbank mit drei Tabellen zum Verwalten von Lesezeichen-Informationen erstellt haben – Lesezeichen, Tags und BookmarkTag (siehe Abbildung 2), und Sie sind relativ selbsterklärend.
Abbildung 2 Lesezeichen Service LINQ to SQL-Modell
Der einzige Nachteil ist, dass das Beispiel stützt sich auf den integrierten ASP.NET Formulare Authentifizierungs- und Mitgliedschaft Dienst, der standardmäßig AccountController, die im Lieferumfang des Projekts enthalten ist bereitgestellt wird, den Service-Benutzer zu verwalten, daher Konten Benutzerkonto Informationen in einer anderen Datenbank (aspnetdb.mdf), getrennt von der Textmarke Informationen gespeichert werden.
Der Benutzername ist einfach in der Tabelle Lesezeichen gespeichert.
Es ist die Auftrag des Modells Geschäftsobjekte und Logik on top of der Datenbank bereitstellen.
In diesem Beispiel habe ich definiert die XML-Webdienste SQL-Modell im Abbildung 2 angezeigt.
Dieses Modell, definiert in BookmarksModel.dbml, erzeugt der C#-Code, die in BookmarksModel.designer.cs gefunden.
Hier finden Sie Klassen mit dem Namen Lesezeichen, Tags und BookmarkTag.
Finden Sie auch eine BookmarksModelDataContext-Klasse, die die Entitäten verknüpft.
Zu diesem Zeitpunkt können Sie direkt mit dem LINQ to SQL-Klassen als der MVC-Modell-Ebene arbeiten, oder Sie können eine Schritt weitere wechseln, indem eine auf höherer Ebene Repository-Klasse, die logische Geschäftsvorgänge definiert und abschirmt Controller/Ansicht aus der zugrunde liegenden Daten Manipulation Details noch mehr definieren.
Abbildung 3 zeigt die Definition für die BookmarksRepository-Klasse, die in den Lesezeichen-Dienst verwendet.

Abbildung 3 BookmarksRepository-Klasse
public class BookmarksRepository
{
// generated Linq to SQL DataContext class
BookmarksModelDataContext db = new BookmarksModelDataContext();
// query methods
public IQueryable<Bookmark> FindAllBookmarks() { ... }
public IQueryable<Bookmark> FindAllPublicBookmarks() { ... }
public IQueryable<Bookmark> FindBookmarksByUser(string username) { ... }
public IQueryable<Bookmark> FindPublicBookmarksByUser(string username) { ... }
public IQueryable<Bookmark> FindBookmarksByTag(string tag) { ... }
public Bookmark FindBookmarkById(int id) { ... }
public IQueryable<string> FindUsers(){ ... }
public IQueryable<Tag> FindTags() { ... }
public Tag FindTag(string tag) { ... }
// insert/delete methods
public void AddBookmark(Bookmark bm) { ... }
public void AddTag(Tag t) { ... }
public void AddTagForBookmark(string tagText, Bookmark bm) { ... }
public void DeleteBookmark(Bookmark bm) { ... }
// persistence
public void Save() { ... }
}
Implementieren des Controllers
Der Controller ist der Teil des Codes für die Verwaltung des Lebenszyklus von HTTP-Anforderung zuständig ist.
Wenn eine Anforderung eintrifft, wird das XML-Webdienste MVC-Routingmodul bestimmt die zu verwendenden Controller (basierend auf den URL) und leitet dann die Anforderung an den Controller durch Aufrufen von einer bestimmten-Methode.
Beim Schreiben von eines Domänencontrollers sind Sie daher die Einstiegspunkte schreiben, die vom Routingmodul aufgerufen wird.
Für den Dienst Textmarke möchten wir authentifizierte Benutzern erstellen, bearbeiten und Löschen von Textmarken ermöglichen.
Wenn Lesezeichen zu erstellen, sollten Benutzer um Sie als Public (freigegeben) oder Private markieren können.
Alle Benutzer sollten möglicherweise öffentliche Lesezeichen durchsuchen und Filtern Sie nach Benutzernamen oder Tags.
Private Lesezeichen sollte jedoch nur für den Besitzer sichtbar sein.
Verbraucher sollten auch Lage Abrufen der Details für eine bestimmte Textmarke vorausgesetzt Sie dazu autorisiert sind.
Wir sollten auch durchsuchen alle Benutzer und -Tags im System als eine Möglichkeit, die öffentlichen Lesezeichen zugeordnet navigieren können.
Abbildung 4 zeigt die Methoden die BookmarkController-Klasse muss die Anforderungen unterstützen beschriebenen.
Die ersten drei Abfragemethoden ermöglichen das Abrufen aller öffentlichen Lesezeichen, Lesezeichen durch Benutzer oder Lesezeichen nach Tag.
Die Klasse enthält auch Methoden zum Abrufen der Benutzer und -Tags und zum Abrufen der Details einer bestimmten Textmarke-Instanz.
Alle diese Methoden auf HTTP GET-Anforderungen reagieren, aber jeweils wird an einen anderen URI-Vorlage gebunden werden, wenn die Routen definiert sind.

Abbildung 4 BookmarkController-Klasse
[HandleError]
public class BookmarkController : Controller
{
// underlying model
BookmarksRepository bmRepository = new BookmarksRepository();
// query methods
public ActionResult BookmarkIndex() { ... }
public ActionResult BookmarksByUserIndex(string username) { ... }
public ActionResult BookmarksByTagIndex(string tag) { ... }
public ActionResult UserIndex() { ... }
public ActionResult TagIndex() { ... }
public ActionResult Details(int id) { ... }
// create boomark
[Authorize]
public ActionResult Create() { ... }
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection) { ... }
// update bookmark
[Authorize]
public ActionResult Edit(int id) { ... }
[Authorize]
[AcceptVerbs(HttpVerbs.Put | HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
// delete bookmark
[Authorize]
public ActionResult Delete(int id) { ... }
[Authorize]
[AcceptVerbs(HttpVerbs.Delete | HttpVerbs.Post)]
public ActionResult Delete(int id, FormCollection collection) { ... }
}
Die verbleibenden Methoden handelt es sich zum Erstellen, bearbeiten und Löschen von Lesezeichen-Instanzen.
Beachten Sie, dass zwei Methoden für jedes logische Operation sind – eine für das Abrufen im Eingabeformular und andere für die Reaktion auf die Übertragung des Formulars – und jeweils dieser Methoden erfordert Autorisierung.
Das Autorisieren Attribut gewährleistet, dass der Aufrufer authentifiziert und autorisiert, auf die Domänencontroller-Methode zuzugreifen.
(Das Attribut ermöglicht auch Sie Benutzer und Rollen angeben.) Wenn ein nicht authentifizierter oder nicht autorisierter Benutzer, versucht auf eine Controller-Methode, mit [autorisieren] Anmerkungen zuzugreifen, leitet der Autorisierungsfilter den Benutzer automatisch an die AccountController-Anmeldung-Methode, die "Logon" stelltan den Consumer anzeigen.
Sie das AcceptVerbs-Attribut verwenden, um die HTTP-Verben anzugeben, die eine bestimmter Domänencontroller-Methode behandelt (der Standardwert ist GET).
Eine einzelne Methode kann mehrere Verben durch OR zusammen HttpVerb Werte behandeln.
Der Grund habe ich die zweite bearbeiten-Methode sowohl einfügen und POST gebunden ist um Browsern aufzunehmen.
Diese Konfiguration ermöglicht Browsern rufen Sie den Vorgang mit POST, während Nonbrowser Consumer PUT verwenden können (was mehr richtigen ist).
Ich haben ungefähr auf der zweiten Methode löschen es sowohl DELETE als auch POST binden.
Ich habe vorsichtig sein, dass meine Methodenimplementierungen Idempotency, Sicherstellen der ist eine Voraussetzung für PUT und DELETE.
Sehen Sie sich wie ein paar Methoden implementiert wurden.
Zunächst ist BookmarkIndex:
public ActionResult BookmarkIndex()
{
var bms = bmRepository.FindAllPublicBookmarks().ToList();
return View("BookmarkIndex", bms);
}
Diese Implementierung ruft einfach die Liste der öffentlichen Lesezeichen Entitäten aus dem Repository ab und gibt dann eine Ansicht namens BookmarkIndex (in der Liste Textmarke Entitäten übergeben) zurück.
Die Ansicht ist verantwortlich für die Anzeige der Textmarke Entitäten, die vom Controller bereitgestellt.
Die Details-Methode sucht die Ziel-Textmarke und gibt Fehler 404 Not Found zurück, wenn er nicht vorhanden ist.
Und es wird sichergestellt, dass der Benutzer zum Anzeigen der Textmarke autorisiert ist.
Wenn dies der Fall ist, gibt es die Detailansicht, Angabe der identifizierten Lesezeichen Entität zurück.
Andernfalls wird eine nicht autorisierte Antwort an den Consumer zurückgegeben.
public ActionResult Details(int id)
{
var bm = bmRepository.FindBookmarkById(id);
if (bm == null)
throw new HttpException(404, "Not Found");
if (!bm.Shared)
{
if (!bm.Username.Equals(HttpContext.User.Identity.Name))
return new HttpUnauthorizedResult();
}
return View("Details", bm);
}
Als letzten Beispiel betrachten die beiden Methoden erstellen.
Der erste ist tatsächlich ziemlich einfach – wird die Ansicht erstellen, um die Formularbeschreibung für das Erstellen eines neuen Lesezeichens vorhanden:
[Authorize]
public ActionResult Create()
{
return View("Create");
}
Abbildung 5 zeigt die zweite erstellen-Methode, die auf die Formular absenden Anforderung reagiert.
Erstellt eine neue Textmarke Entität aus den Lesezeichen-Informationen in das eingehende FormCollection-Objekt gefunden und speichert es in der Datenbank.
Es wird die Datenbank auch mit jeder neuen Tags, die die Textmarke zugeordnet waren aktualisiert, und leitet Benutzer auf Ihre Listen persönliche Lesezeichen um Erfolg anzuzeigen.

Abbildung 5 der Methode, die zu einer Form senden-Anforderung antwortet erstellen
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
try
{
Bookmark bm = new Bookmark();
bm.Title = collection["bookmark-title"];
bm.Url = collection["bookmark-url"];
bm.Shared = collection["bookmark-shared"].Contains("true");
bm.LastModified = DateTime.Now;
bm.Username = HttpContext.User.Identity.Name;
bm.Tags = collection["bookmark-tags"];
bmRepository.AddBookmark(bm);
bmRepository.Save();
... // create any new tags that are necessary
return RedirectToAction("BookmaryByUserIndex",
new { username = HttpContext.User.Identity.Name });
}
catch
{
return View("Error");
}
}
Es nicht Speicherplatz für die gesamte Controller-Implementierung abgedeckt ist, aber diese Codebeispiele sollten Ihnen einen Eindruck für die Art von Code in der Steuerung schreiben.
Entwerfen von URIs mit Routen
Der nächste Aspekt Sie müssen ist URL-Routen definieren, die die verschiedenen BookmarkController Methoden zugeordnet.
Ihre Anwendung Routen werden in Global.asax definiert, innerhalb der RegisterRoutes-Methode.
Wenn Sie zuerst ein MVC-Projekt erstellen, enthält Ihr Global.asax den routing Standardcode in Abbildung 6 angezeigt.

Abbildung 6 Standard Routing Code
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller="Home", // Parameter defaults
action="Index", id="" }
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
Der einzige Aufruf MapRoute erstellt eine Standard-Routingregel, die wie ein Catchall für alle URIs fungiert.
Diese Route werden, dass das erste Pfadsegment den Controllernamen gibt, des zweiten Pfadsegments den Namen Aktion (Domänencontroller-Methode gibt) und dritten Pfadsegment stellt einen ID-Wert dar beschrieben.
Diese Regel kann behandelt die folgenden URIs und leiten diese an die entsprechenden Domänencontroller-Methode:
/Account/Logon
/Bookmark/Create
/Bookmark/Details/25
/Bookmark/Edit/25
Abbildung 7 zeigt den Routen ich beispielsweise Dienst dieses Lesezeichen mit bin.
Mit dieser zusätzlichen Routen können Consumer wechseln Sie zu "/ Benutzer"Abrufen die Liste von Benutzern, "/ tags"Abrufen die Liste der Tags, oder "/ Lesezeichen"Um die Liste der öffentlichen Lesezeichen abzurufen.
Verbraucher können auch auf "/tags/ {Tagname}" suchen.oder "/users/ {Benutzername}"Um Lesezeichen nach Tag oder Benutzername, bzw. zu filtern.
Alle anderen URIs werden von der Standardroute im Abbildung 6 angezeigten behandelt.

Abbildung 7 Lesezeichen Service Routen
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// customer routes
routes.MapRoute("Users", "users",
new { controller = "Bookmark", action = "UserIndex" });
routes.MapRoute("Tags", "tags",
new { controller = "Bookmark", action = "TagIndex" });
routes.MapRoute("Bookmarks", "bookmarks",
new { controller = "Bookmark", action = "BookmarkIndex" });
routes.MapRoute("BookmarksByTag", "tags/{tag}",
new { controller = "Bookmark", action = "BookmarksByTagIndex", tag = "" });
routes.MapRoute("BookmarksByUser", "users/{username}",
new { controller="Bookmark", action="BookmarksByUserIndex", username="" });
// default route
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = ""});
}
Implementieren der Ansichten
Bis zu diesem Zeitpunkt gilt die meisten wir haben für beide MVC "Sites"und "Dienste". Alle MVC-Anwendungen benötigen Modelle, Domänencontroller und Routen.
Die meisten unterschiedliche zum Erstellen von MVC "Dienste Neuigkeiten"befindet sich in der Ansicht.
Statt eine herkömmliche HTML-Ansicht für Benutzer zu erstellen, muss ein Dienst eine Sicht erstellen, die für Menschen und programmgesteuerte Verbrauch geeignet ist.
Wir XHTML für unsere Standard Service Darstellung und die für die Zuordnung Textmarke Daten zu XHTML beschriebenen Techniken anwenden.
Wir müssen Datenentitäten, < Div > zuordnen.und < span >Elemente und wir werden Auflistungen mithilfe einer Kombination aus < Ol > darstellen.und < li >.
Wir müssen auch diese Elemente mit "Klasse" versehen.Attribut, das zusätzliche Typmetadaten Consumer bereitzustellen.
XML-Webdienste MVC "Ansichten"sind Sie gerade ASPX-Seiten, die eine Ansicht Vorlage definieren.
Die .aspx-Seiten sind nach Name des Domänencontrollers innerhalb des Verzeichnisses Ansichten angeordnet.
Jede Ansicht kann eine ASP.NET-Masterseite zum Verwalten eines konsistenten Vorlage zugeordnet werden.
Abbildung 8 zeigt die master Seite für den Dienst Textmarke.

Abbildung 8 Lesezeichen Service-Masterseite
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html >
<head runat="server">
<title><asp:ContentPlaceHolder ID="Title" runat="server" /></title>
</head>
<body>
<div style="text-align:right">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<h1><asp:ContentPlaceHolder ID="Heading" runat="server" /></h1>
<hr />
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<hr />
<div class="nav-links-footer">
<%=Html.ActionLink("Home", "Index", "Home", null,
new { @class = "root-link" } )%> |
<%=Html.ActionLink("Public Bookmarks", "BookmarkIndex", "Bookmark", null,
new { @class = "public-bookmarks-link" } )%> |
<%=Html.ActionLink("User Bookmarks", "BookmarksByUserIndex", "Bookmark",
new { username = HttpContext.Current.User.Identity.Name },
new { @class = "my-bookmarks-link" })%> |
<%=Html.ActionLink("Users", "UserIndex", "Bookmark", null,
new { @class = "users-link" } )%> |
<%=Html.ActionLink("Tags", "TagIndex", "Bookmark", null,
new { @class = "tags-link" } )%>
</div>
</body>
</html>
Die Masterseite definiert drei Platzhaltern: eine für den Seitentitel, ein weiteres für < h1 >Überschrift, und andere für den Hauptinhaltsbereich.
Diese Platzhalter werden durch jede einzelne Ansicht gefüllt werden.
Darüber hinaus die Masterseite zeigt ein Anmeldesteuerelement am oberen Rand der Seite und bietet eine Fußzeile enthält die Stamm Dienst Verknüpfungen zum Vereinfachen der Navigation.
Beachten Sie, wie ich die HTML.ActionLink-Methode verwende diese Verknüpfungen basierend auf den vordefinierten Routen und Controller-Aktionen zu generieren.
Abbildung 9 zeigt die wichtigste Lesezeichen Index-Ansicht, die Sie wieder, erhalten Wenn Sie wechseln zu "/bookmarks".
Es zeigt die Liste der Textmarken, die mithilfe einer Kombination aus <ol>, <li> und <a> Elemente.
<ol> Elemente werden mit-Klasse Anmerkungen = "Lesezeichen-Liste", und jede <a> Element ist mit-Klasse Anmerkungen = "Lesezeichen-Link".
Diese Ansicht bietet auch eine Verknüpfung zu die Formularbeschreibung Textmarke erstellen (rechts über der Liste) abrufen.
Wenn Sie auf die Verknüpfung navigieren, stammt die erstellen-Ansicht in Abbildung 10 dargestellt in Aktion.

Abbildung 9 Lesezeichen Index anzeigen
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.
Master" Inherits="System.Web.Mvc.ViewPage
<IEnumerable<MvcBookmarkService.Models.Bookmark>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Title" runat="server">
Public Bookmarks</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Heading" runat="server">
Public Bookmarks</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ActionLink("Create bookmark", "Create", "Bookmark", new { id = "" },
new { @class = "create-bookmark-form-link" } )%>
<ol class="bookmark-list">
<% foreach (var item in Model) { %>
<li><%= Html.ActionLink(Html.Encode(item.Title), "Details", "Bookmark",
new { id = item.BookmarkID }, new { @class = "bookmark-link" })%></li>
<% } %>
</ol>
</asp:Content>

Abbildung 10 Textmarke erstellen Ansicht
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcBookmarkService.Models.Bookmark>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Title" runat="server">
Create Bookmark</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Heading" runat="server">
Create Bookmark</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm("Create", "Bookmark", FormMethod.Post,
new { @class = "create-bookmark-form" } ))
{%>
<p>
<label for="Title">Title:</label><br />
<%= Html.TextBox("bookmark-title")%>
</p>
<p>
<label for="Url">Url:</label><br />
<%= Html.TextBox("bookmark-url")%>
</p>
<p>
<label for="Tags">Tags:</label><br />
<%= Html.TextBox("bookmark-tags")%>
</p>
<p>
<label for="Shared">Share with public: </label>
<%= Html.CheckBox("bookmark-shared")%>
</p>
<p>
<input type="submit" value="Create" name="submit" />
</p>
<% } %>
</asp:Content>
Die Ansicht erstellen erstellt ein einfaches XHTML-Formular, aber das < Formular >Element ist mit-Klasse Anmerkungen = "erstellen-Textmarke-Form", und jede < >Element hat einen kontextbezogenen Namen-ID-Wert zugewiesen wurde, der jedes Textmarkenfeld gibt.
Dieses Formular bietet Consumer eine vollständige Beschreibung XHTML wie programmgesteuert ein neues Lesezeichen über unseren Dienst (indem Sie einfach das Formular absenden) erstellt.
Abbildung 11 zeigt als letzte beispielsweise den Anfang der Textmarke Detailansicht.
Hier verwende ich ein < Div >Element, um die Textmarke Struktur darzustellen (Klasse = "Lesezeichen") zusammen mit < Span >und < >Elemente, die die Textmarke Felder darstellen.
Jeder führt "Klasse"Attribut, das den Feldnamen des angeben.

Abbildung 11 Bookmark-Detailansicht
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcBookmarkService.Models.Bookmark>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Title" runat="server">
Bookmark Details: <%= Model.BookmarkID %></asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Heading" runat="server">
Bookmark Details: <%= Model.BookmarkID %></asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<br />
<div class="bookmark">
BookmarkID: <span class="bookmark-id"><%= Html.Encode(Model.BookmarkID) %></span><br />
Title: <span class="bookmark-title"><%= Html.Encode(Model.Title) %></span><br />
Url: <a class="bookmark-url-link" href="<%= Html.Encode(Model.Url) %>">
<%= Html.Encode(Model.Url) %></a><br />
Username: <%=Html.ActionLink(Model.Username, "BookmarksByUserIndex", "Bookmark",
new { username=Model.Username }, new { @class="bookmark-username-link" }) %><br />
...
Auch nicht genug Speicherplatz für alle Ansicht Beispiele im Detail betrachten, aber ich hoffe, dies veranschaulicht, wie saubere XHTML-Resultsets erzeugen können, die leicht für Anwendungen und Menschen nutzen sind.
Verarbeiten des Bookmark-Dienstes
Lesezeichen-Dienstes am einfachsten über einen Webbrowser werden.
Dank an den XHTML-Entwurf sollten Sie möglicherweise wechseln Sie zu der Dienst Stamm-URL und Navigation von dort aus zu starten.
Abbildung 12 zeigt, wie der Browser beim Navigieren Sie zum Stammverzeichnis des Lesezeichens-Dienstes und melden Sie sich aussieht.
Sie können Öffentliche Lesezeichen zu der Liste der öffentlichen alle Lesezeichen navigieren und navigieren Sie zu einer bestimmten Textmarke in der Liste klicken.
Wenn Sie auf Bearbeiten klicken, können Sie tatsächlich die Textmarke Details bearbeiten (siehe Abbildung 13).
Der Dienst ist vollständig in einem beliebigen Webbrowser verwendet werden.
Abbildung 12 dem MVC Lesezeichen Service durchsuchen
Abbildung 13 bearbeiten eine bestimmte Textmarke
Während Sie, um den Dienst aktivieren Datenquelle gelegentlich in Ihrem Browser durchsuchen gerade, und Sie sehen, wie einfach die resultierende XHTML sucht, wodurch erneut zum Programmieren mit erleichtert.
Abbildung 14 zeigt den Code für eine vollständige .NET Clientanwendung, die den Lesezeichen-Dienst nutzt.
Er verwendet den Satz von XLinq Erweiterungsmethoden, die zuvor zum Vereinfachen der XHTML und HTTP-Verarbeitungsdetails beschrieben.
Das interessante an diesem Beispiel ist, dass es mehr wie ein Mensch fungiert – benötigt nur den Stamm-URI Navigieren zu ansonsten von Interesse von Lesezeichen-Dienst verfügbar gemacht werden.

Abbildung 14 Schreiben eines .NET Clients für den Lesezeichen-Dienst mit XLinq verwenden
class Program
{
static void Main(string[] args)
{
// navigate to the root of the service
Console.WriteLine("Navigating to the root of the service...");
Uri uri = new Uri("http://localhost:63965/");
CookieContainer cookies = new CookieContainer();
var doc = XDocument.Load(uri.ToString());
doc.AddAnnotation(uri);
// navigate to public bookmarks
Console.WriteLine("Navigating to public bookmarks...");
var links = doc.Body().Ul("nav-links").Lis();
var bookmarksLink = links.Where(l => l.HasAnchor("public-bookmarks-link")).First();
var bookmarksDoc = bookmarksLink.Anchor().Navigate();
bookmarksDoc.AddAnnotation(cookies);
// display list of bookmarks
Console.WriteLine("\nPublic bookmarks found in the system:");
var bookmarks = bookmarksDoc.Body().Ol("bookmark-list").Lis();
bookmarks.Each(bm => Console.WriteLine("{0}: {1}",
bm.Anchor().AnchorText, bm.Anchor().AnchorLink));
// navigate to the first bookmark in the list
Console.WriteLine("\nNavigating to the first bookmark in the list...");
var bookmarkDoc = bookmarks.First().Anchor().Navigate();
var bookmarkDetails = bookmarkDoc.Body().Struct("bookmark");
// print the bookmark details out to the console window
Console.WriteLine("Bookmark details:");
Console.WriteLine("bookmark-id: {0}", bookmarkDetails["bookmark-id"].Value);
Console.WriteLine("bookmark-url-link: {0}",
bookmarkDetails["bookmark-url-link"].Value);
Console.WriteLine("bookmark-title: {0}", bookmarkDetails["bookmark-title"].Value);
Console.WriteLine("bookmark-shared: {0}", bookmarkDetails["bookmark-shared"].Value);
Console.WriteLine("bookmark-last-modified: {0}",
bookmarkDetails["bookmark-last-modified"].Value);
// retrieving login form
Console.WriteLine("\nRetrieving login form...");
Uri logonUri = new Uri("http://localhost:63965/Account/Logon");
var logonDoc = XDocument.Load(logonUri.ToString());
logonDoc.AddAnnotation(logonUri);
logonDoc.AddAnnotation(cookies);
// logging on as skonnard
Console.WriteLine("Logging in as 'skonnard'");
var logonForm = logonDoc.Body().Form("account-logon-form");
logonForm["username"] = "skonnard";
logonForm["password"] = "password";
logonForm.Submit();
Console.WriteLine("Login successful!");
// create a new bookmark as 'skonnard'
var createBookmarkDoc = bookmarksDoc.Body().Anchor(
"create-bookmark-form-link").Navigate();
createBookmarkDoc.AddAnnotation(cookies);
var createBookmarkForm = createBookmarkDoc.Body().Form("create-bookmark-form");
createBookmarkForm["bookmark-title"] = "Test from console!";
createBookmarkForm["bookmark-url"] = "http://live.com/";
createBookmarkForm["bookmark-tags"] = "Microsoft, Search";
createBookmarkForm.Submit();
Console.WriteLine("\nBookmark created!");
}
}
Der Client beginnt durch navigieren zu der Stamm-Adresse, und sucht dann für die Verknüpfung zu der öffentlichen Lesezeichen.
Nächstes navigiert zur Liste öffentlichen Lesezeichen und identifiziert eine bestimmte Textmarke Zinsen (in diesem Fall die erste Datei).
Als Nächstes es navigiert zu der Textmarke Details und im Konsolenfenster angezeigt.
Anschließend ruft das Anmeldeformular und führt eine Anmeldung mit einem Satz von Anmeldeinformationen.
Einmal angemeldet, wird die Anwendung ruft Formular Textmarke erstellen, füllt es aus und ein neues Lesezeichen an das System sendet.
Es gibt einige wichtige Beobachtungen zu diesem Zeitpunkt.
Zunächst ist die Konsolenanwendung in der Lage auf diese Weise alles, was einen Menschen über den Webbrowser ausführen kann.
Das ist der diesem Design XHTML-killer Funktion.
Zweitens müssen Consumer nur gegen den Stamm hartcodierte URIs durch den Dienst verfügbar gemacht werden.
Alle anderen URIs werden zur Laufzeit durch navigieren Links innerhalb der XHTML gefunden sichtbar.
Und schließlich XHTML-Strukturen verarbeitet, viel anders etwas – es ist nur die Daten.
Plus, diese Art von Code ruft nur einfacher, Sie gegen dynamischer Sprachen in zukünftigen Versionen von .NET verschieben.
Schließlich bietet XML-Webdienste MVC ein grundsätzlich Rest Framework für implementieren ein Web von XHTML-basierte Ressourcen, die von Menschen und Anwendungen gleichzeitig verwendet werden können.
Sie können die gesamte Beispielanwendung in diesem Artikel aus der MSDN Magazin-Website downloaden.
Ein weiteres vollständiges Beispiel für ein XHTML-basierte REST-Diensts in der realen Welt gefunden Sie, suchen Sie die Content Services von Microsoft-TechNet Publishing System (MTPS).
Dieser Dienst verwendet viele der Methoden, die ich in diesem Artikel skizziert haben.
Danksagung
Dank Tim Ewald und Craig Andera bereitgestellt, deren kreative Denken in diesem Bereich Treibstoff für meine Artikel.
Tim bereitgestellt auch die XLinq Erweiterungsmethoden in der zugehörigen Beispielanwendung gefunden.
Aaron Skonnard ist Mitbegründer von Pluralsight, einem Microsoft-Schulung-Anbieter beide Trainern und on-Demand-Entwickler-Kurse anbieten.
Heutzutage verbringt er Großteil seiner Zeit aufzeichnen Pluralsight bei Bedarf!
Kurse auf Wolke Computing, Windows Azure, WCF und REST konzentriert.
Sie erreichen ihn unter http://pluralsight.com/aaron und http://twitter.com/skonnard.