<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>A Donkey&#039;s Point of View</title>
	<atom:link href="http://elplatero.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://elplatero.wordpress.com</link>
	<description>Programmierung. Politik. Spaß. Leben.</description>
	<lastBuildDate>Sat, 01 Aug 2009 18:48:05 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='elplatero.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>A Donkey&#039;s Point of View</title>
		<link>http://elplatero.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://elplatero.wordpress.com/osd.xml" title="A Donkey&#039;s Point of View" />
	<atom:link rel='hub' href='http://elplatero.wordpress.com/?pushpress=hub'/>
		<item>
		<title>RESTful Web Services mit .NET und ExtJs: Service-Hosting</title>
		<link>http://elplatero.wordpress.com/2009/08/01/restful-web-services-mit-net-und-extjs-service-hosting/</link>
		<comments>http://elplatero.wordpress.com/2009/08/01/restful-web-services-mit-net-und-extjs-service-hosting/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 16:00:00 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ExtJs]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=73</guid>
		<description><![CDATA[Dieser Artikel ist Teil 4 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt. Ein WCF-Service läuft nicht als eigenständiges Programm. Der Normalfall wird sein, dass ein Programm auf den konfigurierten Endpunkten lauscht, und sobald ein passender Request eines Clients angeschwemmt wird, eine [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=73&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#c0c0c0;">Dieser Artikel ist Teil 4 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt.</span></p>
<p>Ein WCF-Service läuft nicht als eigenständiges Programm. Der Normalfall wird sein, dass ein Programm auf den konfigurierten Endpunkten lauscht, und sobald ein passender Request eines Clients angeschwemmt wird, eine Instanz der WCF-Service-Klasse erstellt und ihr die richtigen Parameter übergibt. Der Service befindet sich also in einer Umgebung, die weiß, wie sie zu lauschen hat, und die weiß, von welcher Klasse der Service ist, und wie er zu erzeugen ist. Diese Umgebung ist der <code>ServiceHost</code>, und um den passenden ServiceHost für unseren WCF-Service geht es im viertel Teil meiner Serie.</p>
<p><span id="more-73"></span>
<p>Wie überall in .NET, gibt es zwei Möglichkeiten, die Dinge anzugehen: die einfache Variante, die sich stark auf Konfiguration verlässt, oder die Variante, alles per Code selbst zu machen. Die einfache Variante, einen <code>ServiceHost</code> zu starten, ist wie folgt:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
using (ServiceHost serviceHost = new ServiceHost(typeof(ServiceImplementationClass)))
{
   serviceHost.Open();
   Console.WriteLine("The service is ready.");
   Console.WriteLine("Press  to terminate service.");
   Console.ReadLine();
}
</pre>
<p>Dieser Codeschnipsel kann in jeder Anwendung eingefügt werden &#8211; sei es eine Konsolenanwendung, ein Windows-Dienst, eine WPF-Applikation oder was auch immer. Hauptsache, ausführbar. Welches Protokoll verwendet wird, wie die URI ist, auf der gelauscht wird, und all die anderen Einstellungen passieren werden dabei im <code>system.serviceModel</code>-Abschnitt der Konfigurationsdatei der Anwendung festgelegt.</p>
<p>ServiceHosts sind, wie zu sehen ist, an sich unabhängig von der Klasse des Services, dem sie eine Umgebung bieten. Dagegen muss man beim obigen Ansatz fest programmieren, welcher Service gehostet werden soll &#8211; nicht sehr gut wiederverwendbar in anderen Projekten. Wenn man mal darüber nachdenkt, liegt es also recht nahe, eine Factory-Klasse zu schreiben, die anhand einer Service-Klasse den passenden ServiceHost zurückliefert. Nun ist es nicht sehr überraschend, dass im .NET-Framework so eine Factory-Infrastruktur bereits vorhanden ist. </p>
<p>Die Factory-Klasse für ServiceHosts nennt sich &#8211; wieder keine wirkliche Überraschung &#8211; <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.servicehostfactory.aspx" title="ServiceHostFactory in der MSDN" target="_blank">ServiceHostFactory</a> und kann für beliebige Familien von ServiceHosts so überschrieben werden, wie das notwendig erscheint. Dabei gibt es bereits einige Implementierungen für verschiedene Szenarien: unter anderem auch das Szenario eines Webservice, das wir benötigen, nämlich <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.webservicehostfactory.aspx" title="WebServiceHostFactory in der MSDN" target="_blank">WebServiceHostFactory</a>. Die MSDN bietet einen kleinen, sehr treffenden Satz, der diese Klasse beschreibt:</p>
<blockquote><p>
A factory that provides instances of <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webservicehost.aspx" target="_blank" title="WebServiceHost in der MSDN">WebServiceHost</a> in managed hosting environments where the host instance is created dynamically in response to incoming messages.
</p></blockquote>
<p>REST-Services sind nicht zuletzt, weil sie sich auf HTTP verlassen, natürlich prädestiniert dafür, im Kontext eines Webservers zu laufen (man könnte so weit gehen zu behaupten, dass sie nur dort einen Sinn ergeben). Unser REST-Web-Service wird also von einer <code>WebServiceHost</code>-Umgebung gehostet, die wiederrum von einer <code>WebServiceHostFactory</code> erzeugt wird. Wir haben die Wahl der Anwendung, die diese Klassen in ihrem ausführbaren Part benutzt. Wir werden später sowieso noch eine Webanwendung brauchen: sie soll ja unseren Client darstellen, der per Javascript auf den Service zugreift. Daher lassen wir unseren Service einfach gleich mit vom IIS hosten.</p>
<p>Das bietet uns noch einen weiteren Vorteil. Sagen wir, unsere Webseite (der Client) läuft später unter der Adresse</p>
<pre style="font-size:11px;">http://localhost/MyServiceClient/</pre>
<p>(also auf Port 80). Dann müsste unser Service so konfiguriert werden, dass er auf derselben Adresse auf irgendeinem anderen Port lauscht &#8211; 80 ist bereits vom IIS besetzt. Das wiederum hätte alllerdings zur Folge, dass das Javascript auf localhost:80 zugreifen muss auf einen Service, der auf localhost:1223 (beliebiger anderer Port) lauscht. Und das wiederum eröffnet eine ganze Reihe von potentiellen Problemen, die darin begründet sind, dass Javascript (aus Sicherheitsgründen) nicht einfach auf Drittressourcen ungeprüft zugreifen können darf &#8211; Stichwort <a href="http://de.wikipedia.org/wiki/Cross-Site_Scripting" title="Cross Site Scripting in der Wikipedia" target="_blank">XSS</a>.</p>
<p>Diesen ganzen Ärger umgehen wir, indem wir eine Webanwendung erstellen, und den Service innerhalb dieser Webanwendung hosten lassen.</p>
<p>Alles, was dazu nötig ist, ist eine Datei &#8222;MessageService.svc&#8220; mit folgendem Inhalt:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
&lt;%@ ServiceHost
  Language="C#"
  Service="MessageService.MessageService"
  Factory="System.ServiceModel.Activation.WebServiceHostFactory"
%&gt;
</pre>
<p>That&#8217;s it. Die Angabe beim Parameter &#8222;Service&#8220; bezieht sich dabei auf den vollen Namen (Namespace + Klasse) der Service-Implementierung. Wenn die Webanwendung gestartet wird und die Adresse  http://localhost:PORT/Webanwendungsname/ExampleService.svc im Browser aufgerufen wird, sollte bereits eine Antwort erfolgen &#8211; &#8222;Es wurde kein Endpunkt gefunden.&#8220;, was logisch ist, da keiner unserer Schnittstellenoperationen auf &#8222;/&#8220; zugeordnet wurde.</p>
<p>Weiter geht&#8217;s im nächsten Teil mit der Programmierung des Zugriffs auf den neuen Service per Javascript.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=73&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/08/01/restful-web-services-mit-net-und-extjs-service-hosting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>Angel&#8217;s Share</title>
		<link>http://elplatero.wordpress.com/2009/08/01/angels-share/</link>
		<comments>http://elplatero.wordpress.com/2009/08/01/angels-share/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 14:55:59 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Leben]]></category>
		<category><![CDATA[luxus]]></category>
		<category><![CDATA[spiel]]></category>
		<category><![CDATA[whisky]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=80</guid>
		<description><![CDATA[Es gibt ja so Artikel, die ein &#8222;haben-wollen&#8220;-Gefühl auslösen. Für die, denen wie mir das nötige Kleingeld für einen Emperor fehlt, und die das schlechte Gefühl deshalb auch nicht mit einem 74er Ardbeg aus der Ardbeg Double Barrel-Kollektion wegspülen können, noch ein Tipp: Ardbeg bietet als Ausgleich noch ein kleines, aber witziges Flash-Spielchen, in dem [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=80&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Es gibt ja so Artikel, die ein &#8222;haben-wollen&#8220;-Gefühl auslösen. Für die, denen wie mir das nötige Kleingeld für einen <a href="http://www.basicthinking.de/blog/2009/07/31/emperor-workstation-todestern-feeling-fuer-nerds/" title="Emperor Workstation auf basicThinking" target="_blank">Emperor</a> fehlt, und die das schlechte Gefühl deshalb auch nicht mit einem 74er Ardbeg aus der <a href="https://www.ardbeg.com/shop.asp?Cat=16#505" target="_blank" title="Ardbeg Double Barrel im Ardbeg-Shop">Ardbeg Double Barrel</a>-Kollektion wegspülen können, noch ein Tipp:</p>
<p>Ardbeg bietet als Ausgleich noch ein kleines, aber witziges <a href="https://www.ardbeg.com/barreloflaughs/angel.asp" target="_blank" title="Ardbeg Angel's Share Game">Flash-Spielchen</a>, in dem man den blöden Engeln den <a href="http://de.wikipedia.org/wiki/Angel%27s_share" target="_blank" title="Angel's Share in der Wikipedia">Angel&#8217;s Share</a> streitig machen darf.</p>
<p>Weg ist er, der Frust über monetäre Engpässe.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=80&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/08/01/angels-share/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>RESTful Web Service mit .NET und ExtJs: Service-Implementierung</title>
		<link>http://elplatero.wordpress.com/2009/07/30/restful-web-service-mit-net-und-extjs-service-implementierung/</link>
		<comments>http://elplatero.wordpress.com/2009/07/30/restful-web-service-mit-net-und-extjs-service-implementierung/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 17:00:00 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ExtJs]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=60</guid>
		<description><![CDATA[Dieser Artikel ist Teil 3 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt. Die Implementierung unserer IMessageService-Schnittstelle geht in der Klasse MessageService vor sich. Wir haben in dieser Schnittstelle Methoden für Erstellen, Löschen, Verändern und Abrufen, sowie für das Abrufen einer Liste [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=60&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#c0c0c0;">Dieser Artikel ist Teil 3 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt.</span></p>
<p>Die Implementierung unserer <code>IMessageService</code>-Schnittstelle geht in der Klasse MessageService vor sich. Wir haben in dieser Schnittstelle Methoden für Erstellen, Löschen, Verändern und Abrufen, sowie für das Abrufen einer Liste von einzelnen Instanzen der <code>ChatMessage</code>-Klasse deklariert.</p>
<p>In <code>MessageService</code> bereiten wir nun den Programmcode vor, der festlegen wird, wie diese Methoden auszuführen sind.</p>
<p>  <span id="more-60"></span>
<p>Die Service-Implementierung beinhaltet den Code, der auf gespeicherte Daten zugreift und sie abruft, oder verändert. Um nicht unnötig vom Wesentlichen &#8211; dem Service selbst &#8211; abzulenken, beschränke ich mich dabei auf die Speicherung in einer XML-Datei.</p>
<p>Für die Zugriffsschicht auf das XML muss <a href="http://msdn.microsoft.com/de-de/library/bb308960%28en-us%29.aspx" target="_blank" title="LinQ To Xml auf MSDN">LinQ To Xml</a> herhalten: so blasen wir den Code nicht unnötig weiter auf.</p>
<p>Die Informationen über die XML-Datei, in der die Daten gespeichert werden sollen, werden durch zwei Membervariablen gehalten: <code>m_XmlFileName</code> beinhaltet den Namen der Datei, <code>m_MessageXml</code> bereits das <code><a href="http://msdn.microsoft.com/de-de/library/system.xml.linq.xdocument.aspx" title="XDocument auf MSDN" target="_blank">XDocument</a></code>, mit dessen Hilfe wir den Zugriff auf die Daten realisieren. Beide werden im Konstruktor des Service gefüllt:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public class MessageService : IMessageService
{
  private XDocument m_MessageXml;
  private string m_XmlFilename;

  public MessageService()
  {
    // ich gehe davon aus, dass in der app.config ein
    // Eintrag in den AppSettings vorhanden ist, der
    // "messagefile" heisst und den Namen der Datei
    // enthält - und davon, dass jene Datei auch im
    // Hauptverzeichnis der Applikation ist
    m_XmlFilename = AppDomain.CurrentDomain.BaseDirectory +
             ConfigurationManager.AppSettings["messagefile"];

    //Anlegen, falls nicht vorhanden
    if (!File.Exists(m_XmlFilename))
    {
      m_MessageXml = new XDocument(
        new XDeclaration("1.0", "utf-8", "yes"),
        new XElement("Messages")
      );
      m_MessageXml.Save(m_XmlFilename);
    }
    //Oder laden, falls vorhanden.
    else
      m_MessageXml = XDocument.Load(m_XmlFilename);
  }
</pre>
<p>Nachdem die Daten nun griffbereit in einem <code>XDocument</code> verfügbar sind, machen wir uns an das Auslesen einer Liste von <code>ChatMessage</code>-Objekten. Die Schnittstelle hat dafür die Methode <code>ListMessages</code> vorgesehen.</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public List ListMessages()
{
  var result = m_MessageXml.Descendants("Message")
              .Select(p =&gt; new ChatMessage().Parse(p));
  return result.OrderByDescending(p =&gt; p.Time).ToList();
}
</pre>
<p>Dem kundigen Auge wird bereits die Methode <code>Parse()</code> aufgefallen sein. Keine Sorge, dazu kommen wir noch. Gut zu sehen dagegen ist, wieso ich mich für LinQ To Xml entschieden habe &#8211; sehr viel kürzer geht&#8217;s wirklich nicht mehr.</p>
<p>Der Zugriff auf einen einzelnen Datensatz, in der Schnittstelle durch die Methode <code>GetMessage()</code> deklariert, sieht ganz ähnlich aus. Allerdings gibt es einen kleinen Unterschied: wenn es den angeforderten Datensatz nicht gibt, geben wir nicht nur nichts zurück, sondern setzen den HTTP-Status der Antwort auf NotFound (Status Code 404). Sollte unser Client (also das Javascript im Browser) in der Lage sein, diese Status Codes auszuwerten, dann können wir sie auch benutzen, um den Grund eines Fehlschlags zu übermitteln.</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public ChatMessage GetMessage(string messageId)
{
    XElement element = m_MessageList.Descendants("Message")
                      .FirstOrDefault(p =&gt;
                        p.Attribute("id").Value == messageId
                      );
    if (element != null)
    {
        return new ChatMessage().Parse(element);
    }
    else
    {
        WebOperationContext.Current.OutgoingResponse.StatusCode =
                                              HttpStatusCode.NotFound;
        return null;
    }
}
</pre>
<p><code>Parse()</code> wurde schon wieder verwendet, ich weiß. Merkt&#8217;s euch, die Liste mit den unbekannten Methoden wird noch zwei Einträge länger.</p>
<p>Die nächsten zwei Methoden &#8211; erstellen und löschen einer Nachricht &#8211; können ohne große Erläuterung für sich selbst sprechen:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public ChatMessage CreateMessage(ChatMessage message)
{
    ChatMessage saveMessage = new ChatMessage(
                     message.Author, message.Text);
    //Nachricht im XML speichern
    saveMessage.Save(m_MessageList);
    //und XML speichern
    m_MessageList.Save(m_XmlFilename);  

    WebOperationContext.Current.OutgoingResponse.StatusCode =
                                       HttpStatusCode.Created;
    return saveMessage;
}

public ChatMessage DeleteMessage(string messageId)
{
    ChatMessage removeMessage = GetMessage(messageId);
    if (removeMessage != null)
    {
        removeMessage.Remove(m_MessageList);
    }
    m_MessageList.Save(m_XmlFilename);
    return removeMessage;
}
</pre>
<p>Da beim Löschen einer Nachricht auf die Methode <code>GetMessage()</code> zurückgegriffen wird, ist bereits für den Fall gesorgt, dass eine Nachricht gelöscht werden soll, die gar nicht existiert: in diesem Fall setzt <code>GetMessage()</code> bereits wie gehabt den Status Code auf 404.</p>
<p>Zu Kommentieren bleibt bloss, dass von der übermittelten Nachricht beim Erstellen lediglich die Inhalte benutzt werden: ID und die Zeit des Eintrags übernimmt offenbar unser <code>ChatMessage</code>-Objekt.<br />
Die letzte verbleibende Methode dienst dem Aktualisieren von Einträgen:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public ChatMessage ModifyMessage(string messageId,
                             ChatMessage messageToModify)
{
    if (GetMessage(messageId) != null)
    {
        messageToModify.MessageId = new Guid(messageId);
        messageToModify.Save(m_MessageList);
        m_MessageList.Save(m_XmlFilename);
        return messageToModify;
    }
    return null;
}
</pre>
<p>Auch das sollte einfach so verstanden werden &#8211; das einzig bemerkenswerte ist: die Nachricht wird anhand der übergebenen ID identifiziert, nicht etwa anhand der ID des übergebenen <code>ChatMessage</code>-Objekts: deshalb die Zuweisung der MessageId.</p>
<p>Na, die drei Methoden schon wieder vergessen, die neu waren? Wie versprochen, der überladene Konstruktur, die <code>Save()</code>-Methode, die <code>Remove()</code>-Methode, und die <code>Parse()</code>-Methode &#8211; alle drei zu <code>ChatMessage</code> gehörend. Im Wesentlichen erledigen sie das Mapping hin von einer Property von <code>ChatMessage</code> zu einem Knoten im XML.</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:1em;font-size:11px;">
public ChatMessage Parse(XElement xElement)
{
  MessageId = new Guid(xElement.Attribute("id").Value);
  Text = xElement.Element("text").Value;
  Time = DateTime.Parse(xElement.Element("time").Value);
  Author = xElement.Element("author").Value;
  return this;
}

public void Save(XDocument doc)
{
  XElement messageNode = doc.Descendants("Message")
          .FirstOrDefault(p =&gt;
            p.Attribute("id").Value == MessageId.ToString());
  if (messageNode == null)
  {
    doc.Root.Add(
      new XElement("Message",
        new XAttribute("id", MessageId),
        new XElement("time",
                       Time.ToString("dd.MM.yy HH:mm:ss")),
        new XElement("author", Author),
        new XElement("text", Text)
      )
    );
  }
  else
  {
    messageNode.Element("text").Value = Text;
    messageNode.Element("author").Value = Author;
    messageNode.Element("time").Value =
                 Time.ToString("dd.MM.yy HH:mm:ss");
  }
  return this;
}

public ChatMessage Remove(XDocument doc)
{
  XElement messageNode = doc.Descendants("Message")
          .FirstOrDefault(p =&gt;
            p.Attribute("id").Value == MessageId.ToString());
  if(messageNode != null) messageNode.Remove();
  return this;
}
</pre>
<p>Und damit kann der Service eigentlich bereits gestartet und durch einen Client angesprochen werden. Wie genau das funktioniert, wird im nächsten Teil geklärt.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=60&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/07/30/restful-web-service-mit-net-und-extjs-service-implementierung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>Zugangserschwerung mit erschwertem Zugang</title>
		<link>http://elplatero.wordpress.com/2009/07/29/zugangserschwerung-mit-erschwertem-zugang/</link>
		<comments>http://elplatero.wordpress.com/2009/07/29/zugangserschwerung-mit-erschwertem-zugang/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 17:03:47 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Politik]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=54</guid>
		<description><![CDATA[Klingt komisch, ist aber so: das &#8222;Gesetz zur Erschwerung des Zugangs zu kinderpornographischen Inhalten in Kommunikationsnetzen&#8220; &#8211; liebevoll je nachdem, wen man fragt, auch als &#8222;Zensurgesetz&#8220; oder &#8222;Kinderpornoverhinderungs-Weltfriedens-Antigewalt-und-Mordgesetz&#8220; bekannt, ist wohl auf dem Weg durch die legislative Bürokratie ein wenig ins Stocken geraten. Meldet jedenfalls Heise und kann sich eine gewisse Süffisanz nicht verkneifen: Das [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=54&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Klingt komisch, ist aber so: das &#8222;Gesetz zur Erschwerung des Zugangs zu kinderpornographischen Inhalten in Kommunikationsnetzen&#8220; &#8211; liebevoll je nachdem, wen man fragt, auch als &#8222;Zensurgesetz&#8220; oder &#8222;Kinderpornoverhinderungs-Weltfriedens-Antigewalt-und-Mordgesetz&#8220; bekannt, ist wohl auf dem Weg durch die legislative Bürokratie ein wenig ins Stocken geraten. Meldet jedenfalls <a title="Heise-Artikel" href="http://www.heise.de/newsticker/Startprobleme-beim-Netzsperren-Gesetz--/meldung/142760" target="_blank">Heise </a>und kann sich eine gewisse Süffisanz nicht verkneifen:</p>
<blockquote><p>Das vom Bundestag Mitte Juni <a title="Bundestag verabschiedet Gesetz für Web-Sperren" href="http://www.heise.de/ct/Bundestag-verabschiedet-Gesetz-fuer-Web-Sperren--/news/meldung/140746">beschlossene</a> und vom Bundesrat am 10. Juli <a title="Gesetz zu Web-Sperren passiert den Bundesrat" href="http://www.heise.de/newsticker/Gesetz-zu-Web-Sperren-passiert-den-Bundesrat--/meldung/141849">abgesegnete</a> Gesetz befindet sich demnach noch auf dem Weg durch die Instanzen. Bevor es beim Bundespräsidialamt aufschlägt, wird es von den zuständigen Fachministerien noch einmal gegengelesen.</p></blockquote>
<p>Damit es beim prophezeiten Aufschlag keine Verletzten gibt, hätte ich schon einen Vorschlag:</p>
<p>Wie wär&#8217;s mit einem großen, roten Stoppschild?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=54&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/07/29/zugangserschwerung-mit-erschwertem-zugang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>RESTful Web Service mit .NET und ExtJs: Service-Interface</title>
		<link>http://elplatero.wordpress.com/2009/07/29/restful-web-service-mit-net-und-extjs-service-interface/</link>
		<comments>http://elplatero.wordpress.com/2009/07/29/restful-web-service-mit-net-und-extjs-service-interface/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 16:06:38 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ExtJs]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=33</guid>
		<description><![CDATA[Dieser Artikel ist Teil 2 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt. WCF unterstützt seit der .NET-Frameworkversion 3.5 das Erstellen von RESTful Webservices durch das WebInvokeAttribute. Auf die Properties dieses Attributs möchte ich kurz anhand von Beispielen eingehen. UriTemplate Dieses Property [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=33&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#c0c0c0;">Dieser Artikel ist Teil 2 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt.</span></p>
<p>WCF unterstützt seit der .NET-Frameworkversion 3.5 das Erstellen von RESTful Webservices durch das WebInvokeAttribute. Auf die Properties dieses Attributs möchte ich kurz anhand von Beispielen eingehen. </p>
<p><span id="more-33"></span>
<p><strong>UriTemplate</strong> </p>
<p>Dieses Property legt die Adresse für die Schnittstelle (also die URI) fest. Dabei können Platzhalter für Zeichenketten-Parameter hinterlegt werden. </p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
[OperationContract]
[WebInvoke(RequestUri = &quot;Message/{messageId}&quot;;)]
ChatMessage GetMessageDetails(string messageId); </pre>
<p>Wenn der Service unter der Adresse </p>
<pre style="font-size:11px;">http://service.example.com/MessageService/</pre>
<p>veröffentlicht wird, wäre der Endpunkt für die Methode GetMessageDetails demnach </p>
<pre style="font-size:11px;">http://service.example.com/MessageService/Message/{messageId},</pre>
<p>wobei {messageId} lediglich ein Platzhalter für eine Zeichenkette ist, die der Methode GetMessageDetails() als Parameter übergeben wird.</p>
<p><strong>Method</strong></p>
<p>RESTful Webservices veröffentlichen ihre Schnittstellen durch Uri und das HTTP-Verb. WCF stellt den Zugriff auf das HTTP-Verb, mit dem der Zugriff auf die Schnittstelle erfolgte, durch die Property &quot;Method&quot; des WebInvokeAttribute zur Verfügung. Deshalb stellt folgende Deklaration eine Schnittstelle bereit, die über &quot;PUT&quot; angesprochen wird:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
[OperationContract]
[WebInvoke(
    RequestUri = &quot;Message/{messageId}&quot;,
    Method = &quot;PUT&quot;)]
ChatMessage ModifyMessage(
	string messageId,
	ChatMessage messageToModify);</pre>
<p><strong>RequestFormat / ResponseFormat</strong></p>
<p>Diese Properties legen fest, wie die zu übertragenden Objekte serialisiert werden. Die möglichen Werte sind vom Typ WebMessageFormat, also XML oder Javascript Object Notation. Für ersteres wird für die Serialisierung die Klasse <a title="Eintrag auf MSDN" href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx" target="_blank">DataContractSerializer</a> verwendet, für JSON folgerichtig <a href="" title="Eintrag auf MSDN" target="_blank">DataContractJsonSerializer</a>. Das Ergebnis der Serialisierung &#8211; und damit der Inhalt der Antwort einer Serviceanfrage &#8211; würde zum Beispiel so aussehen:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
&lt;chatmessage&gt;
  &lt;messageid&gt;
    f1fe94db-f859-404e-bada-213f296b13a6
  &lt;/messageid&gt;
  &lt;time&gt;21.04.2009 12:00:00.0000&lt;/time&gt;
  &lt;author&gt;LaTino&lt;/author&gt;
  &lt;text&gt;Beispieltext der Nachricht&lt;/text&gt;
&lt;/chatmessage&gt;</pre>
<p>Oder für WebMessageFormat.Json:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
{
  &quot;Author&quot;:&quot;LaTino&quot;,
  &quot;MessageId&quot;:&quot;f1fe94db-f859-404e-bada-213f296b13a6&quot;,
  &quot;Text&quot;:&quot;Beispieltext der Nachricht&quot;,
  &quot;Time&quot;:&quot;\/Date(1240320060000+0200)\/&quot;
}
</pre>
<p>Erwähnenswert ist dabei vielleicht, dass durch die Einteilung in RequestFormat und ResponseFormat für die Deserialisierung von eingehenden Objekten durchaus andere Regeln gelten können als für die Serialisierung ausgehender Objekte.</p>
<p><strong>BodyStyle</strong></p>
<p>Dieses Property ist vom Typ <a href="http://msdn.microsoft.com/de-de/library/system.servicemodel.web.webmessagebodystyle.aspx" target="_blank" title="Eintrag auf MSDN">WebMessageBodyStyle</a> und legt fest, ob die serialisierten Daten noch einmal als Kindknoten (im Fall von XML) oder als Subobjekt (im Fall von Json) serialisiert werden.</p>
<p>WebMessageBodyStyle.Bare steht dabei für die oben angeführten Serialisierungen, Wrapped für das Wrappen &#8211; Bare ist die Voreinstellung, durch Auswahl der WrappedRequest und WrappedResponse-Werte kann diese Eigenschaft also einzeln für Anfragen und Antworten festgelegt werden. </p>
<p>Für eine ChatMessage, die wrapped nach JSON serialisiert wird, ergibt sich im Gegensatz dazu folgender Output:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
{
  &quot;GetMessageResult&quot;: {
    &quot;Author&quot;:&quot;LaTino&quot;,
    &quot;MessageId&quot;:&quot;f1fe94db-f859-404e-bada-213f296b13a6&quot;,
    &quot;Text&quot;:&quot;Beispieltext der Nachricht&quot;,
    &quot;Time&quot;:&quot;\/Date(1240320060000+0200)\/&quot;
  }
}
</pre>
<p>Ein möglicher Nachteil dieses Formats ist, wie schon zu sehen ist, das mögliche Offenlegen der hinter dem Request stehenden Schnittstelle (hier: GetMessage). Im Beispiel werden wir daher auf das BodyStyle-Attribut verzichten und Nachrichten grundsätzlich unwrapped serialisieren. </p>
<p>Es ist an der Zeit, zu definieren, was für Nachrichten wir eigentlich hin- und herschicken möchten. Dafür benötigen wir eine (sehr einfache) Klasse <span style="font-family:Courier New;">ChatMessage</span>, die wir mit Hilfe des DataContractAttribute und des DataMemberAttribute so markieren, dass der gewählte DataContractJsonSerializer seine Arbeit tun kann:</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
[DataContract]
public class ChatMessage
{
    [DataMember] public Guid MessageId { get; set; }
    [DataMember] public DateTime Time { get; set; }
    [DataMember] public string Author { get; set; }
    [DataMember] public string Text { get; set; }
}
</pre>
<p>Die fertige Schnittstelle unseres Beispieldienstes wird Json für die Kommunikation verwenden und stellt für die Ressource &quot;Message&quot; alle notwendigen Endpunkte mit den im ersten Teil erwähnten vier HTTP-Verben &#8222;GET&#8220;, &#8222;POST&#8220;, &#8222;PUT&#8220; und &#8222;DELETE&#8220; bereit. </p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
[ServiceContract]
public interface IMessageService
{
  [OperationContract]
  [WebInvoke(
	UriTemplate = &quot;Message&quot;,
	Method = &quot;GET&quot;,
	RequestFormat = WebMessageFormat.Json,
	ResponseFormat = WebMessageFormat.Json)]
  List ListMessages(); 

  [OperationContract]
  [WebInvoke(
	UriTemplate = &quot;Message/{messageId}&quot;,
	Method = &quot;GET&quot;,
	RequestFormat = WebMessageFormat.Json,
	ResponseFormat = WebMessageFormat.Json)]
  ChatMessage GetMessage(string messageId); 

  [OperationContract]
  [WebInvoke(
	UriTemplate = &quot;Message&quot;,
	Method = &quot;POST&quot;,
	RequestFormat = WebMessageFormat.Json,
	ResponseFormat = WebMessageFormat.Json)]
  ChatMessage CreateMessage(ChatMessage message); 

  [OperationContract]
  [WebInvoke(
	UriTemplate = &quot;Message/{messageId}&quot;,
	Method = &quot;DELETE&quot;,
	RequestFormat = WebMessageFormat.Json,
	ResponseFormat = WebMessageFormat.Json)]
  ChatMessage DeleteMessage(string messageId); 

  [OperationContract]
  [WebInvoke(
	UriTemplate = &quot;Message/{messageId}&quot;,
	Method = &quot;PUT&quot;,
	RequestFormat = WebMessageFormat.Json,
	ResponseFormat = WebMessageFormat.Json)]
  ChatMessage ModifyMessage(
	string messageId,
	ChatMessage messageToModify);
}
</pre>
<p>Im nächsten Teil schauen wir uns die Implementierung des Service an, und überlegen, wie er am besten veröffentlicht wird.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/33/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=33&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/07/29/restful-web-service-mit-net-und-extjs-service-interface/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>RESTful Web Service mit .NET und ExtJs: Einleitung</title>
		<link>http://elplatero.wordpress.com/2009/07/28/restful-web-service-mit-net-und-extjs-einleitung/</link>
		<comments>http://elplatero.wordpress.com/2009/07/28/restful-web-service-mit-net-und-extjs-einleitung/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 16:56:13 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ExtJs]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=8</guid>
		<description><![CDATA[Dieser Artikel ist Teil 1 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt. Bevor wir richtig loslegen &#8211; und hoffentlich auch, bevor die ersten &#8222;show the code&#8220; brüllen &#8211; ein kleines Vorwort. REST steht für Representational State Transfer, ein Paradigma für den [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=8&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#c0c0c0;">Dieser Artikel ist Teil 1 einer mehrteiligen Serie, die sich mit dem Erstellen und Nutzen eines RESTful Web Service mit Hilfe von .NET und ExtJs beschäftigt.</span></p>
<p>Bevor wir richtig loslegen &#8211; und hoffentlich auch, bevor die ersten &#8222;show the code&#8220; brüllen &#8211; ein kleines Vorwort.</p>
<p><strong>REST</strong> steht für Representational State Transfer, ein Paradigma für den Zugriff auf Services. REST benutzt dabei grundsätzliche, teilweise vernachlässigte Technologien, die unter anderem das <a title="HTTP in Wikipedia" href="http://de.wikipedia.org/wiki/HTTP" target="_blank">HTT-Protokoll</a> zur Verfügung stellt. Der Begriff wurde von <a title="Roy Fieldings Website" href="http://roy.gbiv.com/" target="_blank">Roy Fielding</a> geprägt, der zuvor auch an der Spezifikation von HTTP beteiligt war.<br />
Webservices, die Schnittstellen per REST zur Verfügung stellen (auch RESTful Service genannt), veröffentlichen Daten unter Verwendung sogenannter Ressourcen. Jede Ressource erhält eine eindeutige Adresse (<a title="URI in Wikipedia" href="http://de.wikipedia.org/wiki/URI" target="_blank">URI</a>). Die durchzuführende Aktion ergibt sich aus der Kombination der URI einer Ressource und der Art und Weise, wie diese URI angesprochen wird.</p>
<p><span id="more-8"></span>&lt;p&lt;Im Gegensatz zu RPC (<a title="RPC in Wikipedia" href="http://de.wikipedia.org/wiki/Remote_Procedure_Call" target="_blank">remote procedure call</a>, ein anderes verbreitetes Paradigma) veröffentlichen RESTful Webservices keine Informationen über die Methode, die aufgerufen wird. Die Schnittstellen werden einzig und allein durch die veröffentlichten Ressourcen definiert.</p>
<p>Eine Webservice-Schnittstelle, die mit RPC-Adressierung so angesprochen wird:</p>
<pre style="font-size:11px;">
http://example.com:8080/MessageService?op=GetMessage&amp;id=7862</pre>
<p>würde, wenn der Webservice RESTful ist, so angesprochen werden:</p>
<pre style="font-size:11px;">
http://example.com/MessageService/Message/7862
</pre>
<p>HTTP, also das Protokoll, mit dem Webservices kommunizieren, unterstützt verschiedene so genannte &#8222;Verben&#8220;, die die Art und Weise des Zugriffs spezifizieren. GET und POST sind den meisten Webentwicklern gut bekannt, daneben existieren jedoch noch andere Verben, die sich REST zunutze macht:</p>
<ul>
<li>GET: Abruf von Inhalten</li>
<li>POST: Übertragung von Daten</li>
<li>HEAD: Anforderung eines reinen HTTP-Headers</li>
<li>PUT: Aktualisierung von Daten</li>
<li>DELETE: Löschen von Daten</li>
<li>TRACE: liefert die Anfrage zurück, die der Server empfangen hat</li>
<li>OPTIONS: Liste der unterstützten Methoden</li>
<li>CONNECT: von Proxyservern unterstützt</li>
</ul>
<p>Üblicherweise benutzen RESTful Webservices die Verben GET (Abruf), PUT (Ändern), POST (erstellen) und DELETE (löschen). Dem Benutzer des Webservice muss also nur mitgeteilt werden, welche Ressourcen zur Verfügung stehen. Abrufen und manipulieren kann er sie dann, indem er sie mit den entsprechenden HTTP-Methoden aufruft.</p>
<p>Folgendes Beispiel mit der Ressource &#8222;ChatMessage&#8220; soll das verdeutlichen.</p>
<pre style="border:#222222 1px solid;background-color:#dddddd;padding-left:30px;font-size:11px;">
http://example.com:8080/MessageService/ChatMessage
//     POST: erzeugt eine neue Nachricht und liefert ihre URI zurück
//     PUT: kein Effekt
//     DELETE: kein Effekt
//     GET: liefert eine Liste mit Nachrichten

http://example.com:8080/MessageService/ChatMessage/7862
//     POST: kein Effekt
//     PUT: verändert die Nachricht mit der ID 7862
//     DELETE: löscht die Nachricht mit der ID 7862
//     GET: liefert die Nachricht mit der ID 7862</pre>
<p>RESTful Webservices erzwingen eine ressourcenorientierte Servicearchitektur. Der Service ist vollkommen entkoppelt von jeglicher Anwendung, er ist leicht adressierbar, vollkommen zustandslos und bietet eine einheitliche, vorhersehbare Schnittstelle für Ressourcen. Im Gegensatz zu &#8222;dicken&#8220; RPC-Webservices enthalten die versendeten und empfangenen Nachrichten das absolut notwendige Minimum &#8211; Metainformationen wie angesprochene Schnittstelle entfallen komplett. Das macht RESTful Services sowohl flexibler, als auch universeller einsetzbar. Der Client muss lediglich HTTP beherrschen, SOAP-Kommunikationsverträge und dergleichen können entfallen.</p>
<p>Gleichzeitig sind sie spezialisiert auf die Web-Infrastruktur, da sie wesentlich mehr Eigenschaften von HTTP nutzen als RPC. Antworten an den Client können bei &#8222;reinen&#8220; RESTful Webservices lediglich aus HTTP-Statuscodes bestehen: 404 dürfte jedem bekannt sein, es existieren allerdings noch etliche andere, die dem Client bei einem Minimum an übertragenen Daten Auskunft über den Erfolg (oder den Grund eines Misserfolgs) einer Aktion geben können.</p>
<p>Wir fassen zusammen:</p>
<ul>
<li>schlank</li>
<li>(dadurch) schnell</li>
<li>erzwingen Entkopplung</li>
<li>fördern leicht verständliche Interfaces</li>
<li>universell abrufbar</li>
</ul>
<p>Weiter geht&#8217;s im nächsten Teil, in dem wir uns heraussuchen, was unser Service machen soll, und die Datenverträge schreiben.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=8&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/07/28/restful-web-service-mit-net-und-extjs-einleitung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
		<item>
		<title>Genau. Noch ein Blog.</title>
		<link>http://elplatero.wordpress.com/2009/07/28/genau-noch-ein-blog/</link>
		<comments>http://elplatero.wordpress.com/2009/07/28/genau-noch-ein-blog/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 15:34:59 +0000</pubDate>
		<dc:creator>Platero</dc:creator>
				<category><![CDATA[Esel]]></category>

		<guid isPermaLink="false">http://elplatero.wordpress.com/?p=4</guid>
		<description><![CDATA[So ziemlich das, was die Welt noch gebraucht hat. Dieser Blog ist für mich &#8211; das heisst: hier wird gepostet, was mich interessiert, in der Hoffnung, dass hin und wieder etwas dabei ist, das noch andere Leser findet.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=4&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So ziemlich das, was die Welt noch gebraucht hat. Dieser Blog ist für mich &#8211; das heisst: hier wird gepostet, was mich interessiert, in der Hoffnung, dass hin und wieder etwas dabei ist, das noch andere Leser findet.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elplatero.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elplatero.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elplatero.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elplatero.wordpress.com&amp;blog=1204659&amp;post=4&amp;subd=elplatero&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elplatero.wordpress.com/2009/07/28/genau-noch-ein-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3234be03b09614d796d8a3d22370ba59?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Platero</media:title>
		</media:content>
	</item>
	</channel>
</rss>
