Geek. Coder. Gamer. Bayern Munich Fan.
Visit my blog stream http://writeline.io
My Name is Dariusz Parys
I'm also known as Writeline
I'm a Technical Evangelist @ Microsoft Germany and you can follow me on Twitter or visit my blog stream.
Soziale Netzwerke sind beliebter denn je. Ob Facebook, MySpace oder StudiVZ, jedes dieser Netzwerke hat eine enorme Benutzerzahl, gerade deswegen sind diese Plattformen auch für Entwickler interessant geworden. Eine funktional interessante Anwendung findet oft schnell mehrere Tausend Benutzer und so manche Softwareschmiede ist zu Ruhm und Reichtum gekommen (z.B. Zynga mit Farmville ).
Egal was die persönlichen Beweggründe sind Anwendungen für Soziale Netzwerke zu schreiben, es gibt für all diese Netzwerke eine Hürde: Die API der Plattform.
StudiVZ ist hier den Weg der Standardisierung gegangen. StudiVZ setzt bei der Plattform API ganz auf die OpenSocial API mit einigen speziellen VZ Erweiterungen. Für Entwickler hat die OpenSocial API den Vorteil das die Apps im Prinzip einfacher auf andere Plattformen, die ebenfalls die OpenSocial API implementieren, portiert werden können.
Gadgets spielen eine zentrale Rolle in der Anwendungsentwicklung für StudiVZ. Gadgets sind XML Dokumente die als Manifest für die Anwendungen fungieren. Im XML definiert man die API die verwendet wird, die Features die von der Plattform benötigt werden und die Views die verwendet werden. Die Inhalte sind ebenfalls in diesem XML definiert und bestehen in der Regel aus HTML, CSS und JavaScript. Durch die Definition der Inhalte für einen View lassen sich unterschiedliche Darstellungen realisieren. Zum Beispiel kann ein Gadget sich auf der Profil Seite anders darstellen als auf der Gruppenseite und auch so komplett andere Funktionalität mitbringen.
Im folgenden werde ich eine Web Anwendung schreiben und diese mittels eines Gadgets in die StudiVZ Plattform integrieren. Als Tool verwenden wir WebMatrix, eine kostenlose komplette Entwicklungsumgebung mit Editor, Webserver und Datenbank. Das ganze lässt sich elegant über den Web Plattform Installer auf dem Entwickler Rechner installieren und man kann loslegen.
Link: Installation von WebMatrix durch den Web Platform Installer
Neben PHP unterstützt WebMatrix ASP.NET Web Pages welche ich zur Erstellung der Seite wähle. Die Idee für das Szenario ist fiktiv und einfach, zeigt aber grundsätzlich alle wichtigen Konzepte.
Die Anwendung soll eine Petitionsliste für die Erhaltung des Internets darstellen. Die letzten 5 Unterschriften werden angezeigt und man kann sich direkt in die Liste eintragen. Wenn man sich Einträgt wird automatisch an die StudiVZ Pinnwand eine Nachricht erstellt mit dem Wortlaut “{name} hat sich in die Petition zum Erhalt des Internets unterschrieben!”
Die folgenden Schritte sind Notwendig um die Anwendung zu realisieren:
Um einen Entwickleraccount zu beantragen muss man natürlich bei StudiVZ registriert sein. Genauer gesagt langt es wenn man in einem der VZ Netzwerke registriert ist. Ich habe mich bei MeinVZ.net registriert und dort dann auf der Seite http://www.meinvz.net/developer einen Antrag gestellt.
Wer sich jetzt frägt wer Zsuirad ist der mag doch einfach das Wort Rückwärts lesen. Eigentlich hätte ich keinen Alter Ego Account anlegen müssen, die Developer Sandbox bietet bereits eine Reihe an Accounts die man zum Testen der App benutzen kann. Praktisch. Der Link führt einen zu einem weiteren Fragebogen, ausfüllen und warten bis man eine Bestätigung bekommt (Dieser Schritt kann auch mal 1 oder 2 Tage dauern).
Die Petitions Anwendung erstellen wir in WebMatrix. Dazu wähle ich aus den Projekt-Templates entsprechend das Empty Site Projekt und lege eine neue Datei mit dem Namen Petition.cshtml an.
Danach wechsel ich in den Database Workspace und lege eine neue Datenbank an und erstelle dort die Tabelle Signed. Die Tabelle enthält eine automatisch generierte Id, den Namen und das Datum der Signatur.
Der Grundstein ist gelegt. Nun kann die Anwendung mit Leben sprich Code gefüllt werden.
1: @{
2: var db = Database.Open("Petition");
3:
4: if( IsPost )
5: {
6: var errors = false;
7: var signature = Request["name"];
8:
9: if( signature.IsEmpty() )
10: {
11: errors = true;
12: @:Willst Du unterschreiben, dann trage Deinen Namen ein!<br/>
13: }
14:
15: if( errors == false )
16: {
17: var insert = "INSERT INTO Signed (Name, DateAndTime)
18: VALUES (@0, @1)";
19: db.Execute( insert, signature, DateTime.Now);
20: }
21: }
22:
23: var people = db.Query( "SELECT TOP(5) * FROM Signed
24: ORDER BY DateAndTime DESC");
25: var totalPeopleSigned = db.QueryValue( "SELECT COUNT(*) FROM Signed" );
26: }
27:
28:
29: <!DOCTYPE html>
30:
31: <html lang="en">
32: <head>
33: <meta charset="utf-8" />
34: <title>Petition</title>
35: </head>
36: <body>
37:
38: <h1>Petition zur Erhaltung des Internets</h1>
39:
40: <h2>Zuletzt unterschrieben von</h2>
41:
42: <ul>
43: @foreach( var person in people ) {
44: <li>@person.Name am @person.DateAndTime</li>
45: }
46: </ul>
47:
48: <h2>@totalPeopleSigned Menschen haben diese Petition unterschrieben</h2>
49:
50: <div id='petitionform'>
51: <form method="POST">
52: <fieldset>
53: <h4>Unterschreibe diese Petition</h4>
54: <label for="Name">Name: </label>
55: <input type="text" name="Name" />
56: <input type="submit" value="Signed"/>
57: </fieldset>
58: </form>
59: </div>
60: </body>
61: </html>
Das @ Zeichen deklariert einen Razor Code Block. Razor ist die Syntax der View Engine die für ASP.NET Web Pages benötigt wird. Die Zeilen 1 – 26 greifen auf die Datenbank zu und prüfen ob es sich um einen Postback der Seite handelt. Falls ja, wird ein neuer Datensatz in die Datenbank eingetragen.
In der Zeile 43 – 46 sieht man die dynamische Erstellung der Personen die bereits die Petition unterschrieben haben. Zum Schluß folgt noch die Form die den Postback auslösen kann.
Damit die Web Anwendung aus einem StudiVZ Gadget genutzt werden kann, muss ich diese erst noch bei einem Hoster veröffentlichen. WebMatrix bietet hierfür eine Publish Schaltfläche, die automatisch auch noch Provider anbietet die ASP.NET Web Pages hosten können.
Nach dem Eintragen meiner Publishing Credentials publiziere ich die Anwendung mittels Web Deploy auf den Server.
Die App ist nun publiziert und unter der URL http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml erreichbar.
Die Anwendung muss nun in ein Gadget gepackt werden. Hierfür gibt es entsprechende XML Schema Definitionen die auf dem Developer Wiki von StudiVZ zu finden sind. Das Gadget soll im Canvas View einfach die Anwendung kapseln und darstellen. Das ist leicht bewerkstelligt und sieht als Gadget folgendermaßen aus:
1: <?xml version="1.0" encoding="UTF-8" ?>
2: <Module>
3: <ModulePrefs title="Petition Gadget">
4: <Require feature="opensocial-0.9" />
5: <Require feature="minimessage"/>
6: <Require feature="views"/>
7: <AllowedDomain name="20313wdbv4.adhostbeta.com"/>
8: </ModulePrefs>
9: <Content view="canvas" type="url" href="http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml">
10: </Content>
11: </Module>
Doch bevor wir das Gadget testen wollen wir noch die Funktionalität erweitern. Das einbinden der externen Webseite im Canvas bringt zwar ein schnelles Resultat doch hat man hier nichts weiter als die Seite eingebunden und keinerlei Integration in die StudiVZ Plattform getätigt.
Den Canvas View lasse ich erstmal so. Ich erweitere das Gadget um einen Content Bereich für die Views Profile und Group. In diesem View soll sich das Gadget entsprechend in die Seite integrieren. Beachten muss man lediglich das dass Gadget mit den Maßen 390 x 400px angezeigt wird, Content darüber wird abgeschnitten. Unsere Seite eignet sich nicht direkt für die Profile und Group Views, da das generierte HTML mit der Form zusammen größer ist.
Auch die Integration mit der Möglichkeit an die Pinnwand zu schreiben muss in die Signierung der Petition integriert werden. Das erfordert ein “Refactoring” der eigentlichen Anwendung. Ich füge zur Anwendung zwei URL Endpunkte hinzu. Eine die die letzten Petitionen anzeigt und eine die als POST Endpunkt dient um neue Unterschriften hinzuzufügen.
Security über OAuth
Die Authorisierung zwischen Gadget und Web Anwendung erfolgt über OAuth, einem Standard der es erlaubt Anwendungen untereinander zu vertrauen und entsprechend Zugriffe zu gewähren. Im Gadget werde ich die Signatur Funktion von OAuth nutzen, in der Web Anwendung verzichte ich auf die Prüfung, diese sollte natürlich erfolgen damit nicht jeder x-beliebige Post einer beliebigen Seite angenommen wird. Es gibt zahlreiche OAuth Tutorials auf dem Developer Wiki, so dass diese Übung dem Leser überlassen bleibt.
Damit habe ich nun zwei weitere Endpunkte:
ListPetition.cshtml
4: var people = db.Query( "SELECT TOP(5) * FROM Signed ORDER BY DateAndTime DESC");
5: var totalPeopleSigned = db.QueryValue( "SELECT COUNT(*) FROM Signed" );
6: }
7:
9: <h1>Petition zur Erhaltung des Internets</h1>
10:
11: <h2>Zuletzt unterschrieben von</h2>
12:
13: <ul>
14: @foreach( var person in people ) {
15: <li>@person.Name am @person.DateAndTime</li>
16: }
17: </ul>
18:
19: <h2>@totalPeopleSigned Menschen haben diese Petition unterschrieben</h2>
20:
und SignPetition.cshtml
12: @:Es fehlt die Unterschrift!<br/>
17: var insert = "INSERT INTO Signed (Name, DateAndTime) VALUES (@0, @1)";
18: db.Execute( insert, signature, DateTime.Now);
19: @:Danke f�r Deine Unterschrift!<br/>
22: else
23: {
24: Response.Redirect("~/Petition.cshtml");
25: }
Wie schon gesagt, im richtigen Anwendungsfall sollte letztere auf jeden Fall die OAuth Signatur prüfen.
Da wir nun die Endpunkte haben können wir auch das Gadget um den Content Bereich für Profile und Group erweitern.
9: <Content view="profile,group" type="html">
10: <![CDATA[
11:
12: <script type="text/javascript"> 1: 2: 3: gadgets.util.registerOnLoadHandler( initializeApplication ); 4: 5: function initializeApplication() { 6: showAppVersionMessage(); 7: retrievePeopleSignedPetition(); 8: } 9: 10: function showAppVersionMessage() { 11: var msg = new gadgets.MiniMessage( '__MODULE_ID__'); 12: var statusMsg = msg.createDismissibleMessage("Petition Demo 13: Version 1.2"); 14: statusMsg.style.backgroundColor = "grey"; 15: statusMsg.style.color = "white"; 16: } 17: 18: function retrievePeopleSignedPetition() { 19: var url = 20: "http://20313wdbv4.adhostbeta.com/studivz/listpetition.cshtml"; 21: var params = {}; 22: params[ gadgets.io.RequestParameters.AUTHORIZATION ] = 23: gadgets.io.AuthorizationType.SIGNED; 24: gadgets.io.makeRequest( url, 25: onRetrievePeopleSignedPetition, params ); 26: } 27: 28: function onRetrievePeopleSignedPetition( response ) { 29: document.getElementById('peopleSigned').innerHTML = 30: response.data; 31: } 32: 33: function signPetition() { 34: var content = document.getElementById('message'); 35: postToPetition(content); 36: postToBuschfunk(content); 37: } 38: 39: function postToPetition(content) { 40: 41: var url = 42: "http://20313wdbv4.adhostbeta.com/studivz/signpetition.cshtml"; 43: 44: var data = { name: content.value }; 45: 46: var postdata = gadgets.io.encodeValues( data ); 47: 48: var params = {}; 49: params[ gadgets.io.RequestParameters.METHOD ] = 50: gadgets.io.MethodType.POST; 51: params[ gadgets.io.RequestParameters.POST_DATA ] = postdata; 52: params[ gadgets.io.RequestParameters.AUTHORIZATION ] = 53: gadgets.io.AuthorizationType.SIGNED; 54: gadgets.io.makeRequest( url, 55: onRetrievePeopleSignedPetition, params ); 56: } 57: 58: function postToBuschfunk(content) { 59: 60: var params = {}; 61: params[ opensocial.Message.Field.TITLE ] = 62: 'Petition zum Erhalt des Internets'; 63: params[ opensocial.Message.Field.TYPE ] = 64: opensocial.Message.Type.PUBLIC_MESSAGE; 65: 66: var message = opensocial.newMessage( content.value + 67: ' hat die Petition zum Erhalt des 68: Internets unterschrieben!', params ); 69: var recipient = "VIEWER"; 70: 71: opensocial.requestSendMessage(recipient, 72: message, onSendMessageComplete); 73: } 74: 75: function onSendMessageComplete( data ) { 76: if( data.hadError() ) { 77: alert( "Es gab ein problem: " + data.getErrorCode() ); 78: } 79: } 80: 81: </script>!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->!--crlf-->
1:
2:
3: gadgets.util.registerOnLoadHandler( initializeApplication );
4:
5: function initializeApplication() {
6: showAppVersionMessage();
7: retrievePeopleSignedPetition();
8: }
9:
10: function showAppVersionMessage() {
11: var msg = new gadgets.MiniMessage( '__MODULE_ID__');
12: var statusMsg = msg.createDismissibleMessage("Petition Demo
13: Version 1.2");
14: statusMsg.style.backgroundColor = "grey";
15: statusMsg.style.color = "white";
17:
18: function retrievePeopleSignedPetition() {
19: var url =
20: "http://20313wdbv4.adhostbeta.com/studivz/listpetition.cshtml";
21: var params = {};
22: params[ gadgets.io.RequestParameters.AUTHORIZATION ] =
23: gadgets.io.AuthorizationType.SIGNED;
24: gadgets.io.makeRequest( url,
25: onRetrievePeopleSignedPetition, params );
28: function onRetrievePeopleSignedPetition( response ) {
29: document.getElementById('peopleSigned').innerHTML =
30: response.data;
31: }
32:
33: function signPetition() {
34: var content = document.getElementById('message');
35: postToPetition(content);
36: postToBuschfunk(content);
37: }
38:
39: function postToPetition(content) {
40:
41: var url =
42: "http://20313wdbv4.adhostbeta.com/studivz/signpetition.cshtml";
43:
44: var data = { name: content.value };
45:
46: var postdata = gadgets.io.encodeValues( data );
48: var params = {};
49: params[ gadgets.io.RequestParameters.METHOD ] =
50: gadgets.io.MethodType.POST;
51: params[ gadgets.io.RequestParameters.POST_DATA ] = postdata;
52: params[ gadgets.io.RequestParameters.AUTHORIZATION ] =
53: gadgets.io.AuthorizationType.SIGNED;
54: gadgets.io.makeRequest( url,
55: onRetrievePeopleSignedPetition, params );
56: }
57:
58: function postToBuschfunk(content) {
59:
60: var params = {};
61: params[ opensocial.Message.Field.TITLE ] =
62: 'Petition zum Erhalt des Internets';
63: params[ opensocial.Message.Field.TYPE ] =
64: opensocial.Message.Type.PUBLIC_MESSAGE;
65:
66: var message = opensocial.newMessage( content.value +
67: ' hat die Petition zum Erhalt des
68: Internets unterschrieben!', params );
69: var recipient = "VIEWER";
70:
71: opensocial.requestSendMessage(recipient,
72: message, onSendMessageComplete);
73: }
74:
75: function onSendMessageComplete( data ) {
76: if( data.hadError() ) {
77: alert( "Es gab ein problem: " + data.getErrorCode() );
78: }
79: }
80:
81:
13:
14: <div id='main'>
15: <div id='peopleSigned'></div>
16: <div id='content'>
17: Unterschreibe auch Du!
18: <input type='text' id='message' />
19: <a href='javascript:void(0);' onclick='signPetition();'>Unterschreiben</a>
20: </div>
21: </div>
22: ]]>
23: </Content>
24: <Content view="canvas" type="url" href="http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml">
25: </Content>
26: </Module>
Eine kurze Erklärung der Funktionen. In Zeile 3 (JavaScript) registriere ich eine Funktion die beim Laden des Gadgets angesprungen wird. Die Funktion ruft showAppVersionMessage(); auf, welche über eine Mini Message einfach die aktuelle Versionsnummer des Gadgets anzeigt und dann schließlich die Funktion retrievePeopleSignedPetition();. Diese Funktion ruft letztlich den listpetition Endpunkt auf und erhält entsprechend ein Stück HTML zurück das in den aktuellen Gadget Bereich übergeben wird.
Weiter unten ab Zeile 13 (HTML) ist dann ein Anchor Tag angegeben welches die Funktion signPetition(); aufruft. Diese Funktion schreibt nun über den signPetition Endpunkt einen neuen Datensatz in die Petitions-Datenbank, zum anderen wird postToBuschfunk(); aufgerufen, welche eine Nachricht an die Pinnwand schreibt.
Das ist schon die komplette Funktionalität des Gadgets.
Um das Gadget zu testen muss man es in ein gleichnamiges ZIP packen. Das Gadget heißt PetitionGadget.xml und die Zip-Datei heißt demzufolge PetitionGadget.zip. Zum Testen nimmt man nun die Developer Sandbox von *VZ her und lädt das Gadget enstprechend hoch.
Ist das Gadget erfolgreich hochgeladen, so kann man sich in der Vorschau die Funktionalität des Gadgets anschauen. Zuerst einen Blick auf den Canvas View:
Dort wird die Web Anwendung 1:1, wie unter der ursprünglichen URL, integriert angezeigt. Schaltet man nun auf den Profile View erhält man das Mashup von dem HTML das im Gadget enthalten ist und dem Resultat des listpetition Endpunktes.
Gut zu sehen, die Mini Message mit der Versionsnummer und die letzten 5 Petitionsunterschriften. Möchte man nun die Petition unterschreiben, so einfach den Namen eintragen und auf Unterschreiben klicken. Sofort kommt die Meldung ob man das Gadget auf die Pinnwand posten lassen möchte:
Bestätigt man mit senden, so sieht man das Resultat auch in der Pinnwand:
Dieses einfache Beispiel hat gezeigt wie man eine bestehende Web Anwendung in StudiVZ mittels Gadgets und der OpenSocial API integrieren kann. Die Interaktion mit der OpenSocial API belief sich hierbei nur auf reinem JavaScript, es gibt sowohl noch die Möglichkeit über RPC und REST die API aus eigenen Web Anwendungen zu benutzen. Ich habe viele Bereiche nicht beschrieben die für eine richtige Produktiv-App wichtig wären, wie z.B. ein Melden Button für Custom Generated Content oder auch zusätzliche Informationen die zur Installation des Gadgets beigesteuert werden sollten. Komplett außen vorgelassen wurde das Thema OAuth Authentifizierung und Authorisierung. Das Thema ist umfangreich und mit Sicherheit einen eigenen Blogpost Wert und auf dem Developer Wiki findet man weitere Informationen zu diesem Thema. Das Gadget ist hier voll Funktionsfähig im Post enthalten und die Web Anwendung existiert noch bis mindestens Ende des Kalenderjahres 2010 unter dieser URL http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml.
Anmerkung: Dieser Blog Post ist auch auf dem Entwickler Blog von StudiVZ unter dem Titel OpenSocial Apps entwickeln mit ASP.NET erschienen.
Nach dem erscheinen vom Internet Explorer 9 Platform Preview 7 stellt sich nun das IE9 JavaScript Engine Team einer Q&A Session. Das ganze findet heute Abend auf Twitter ab 18.00 Uhr deutscher Zeit statt
Hier die Beschreibung wie man am Chat teilnimmt:
How to Participate: There are several simple ways to participate in the Twitter chat: Ask a Question: Send your question to @ie and use the hashtag #ie9. Vote Up a Question: Monitor the #ie9 hashtag, and retweet the questions you most want to see answered. Follow Along: Sit back from 9-11 am on 11/18 to see the questions and answers stream in live! That’s it!
How to Participate: There are several simple ways to participate in the Twitter chat:
That’s it!
Mehr Informationen gibt es auf dem Team Blog: Meet the Chakra Team Live on Twitter at #IE9
Interessant für jeden der vielleicht Details zum Sunspider Benchmark erfahren möchte.
Wir veranstalten wie letztes Jahr ein Windows Azure Gewinnspiel. Wer ein Windows Phone 7 gewinnen möchte oder eine Xbox mit einem Kinect Controller, der sollte sich das folgende Gewinnspiel mal durchlesen. Insgesamt verlosen wir
Hier geht es zum Gewinnspiel
Ich hatte das Vergnügen auf der TechEd Europe 2010 in Berlin mit Clemens Vasters ein Interview zum Thema Windows Azure AppFabric zu machen. Der Ton ist ein wenig "Noisy" was daran liegt das ich mit einer normalen Fotokamera drauf gehalten habe und kein externes Mikro hatte, doch man versteht alles was Clemens sagt.
Gewettet haben wir auch noch, Köln gegen Borussia Mönchengladbach, tja, habe einen Kasten Bier verloren.
Viel Spaß beim reinschauen,
Dariusz
Ich habe lange Zeit nichts zu diesem Thema geschrieben, es gab für mich eigentlich keinen Anlass hierfür. Na klar, es gab eine PDC Keynote die in aller Munde ist, es gab weitere Blogposts und viel Diskussion um das Thema, doch für mich selbst ist nichts dramatisches gesagt worden.
Silverlight soll tot sein? Ne, absolut nicht. Was vielmehr alle von der Keynote mitnehmen sollten ist dass HTML 5 in Zukunft einfach ein weiterer Bestandteil der Platform ist. In erster Linie im Browser. Genau wie Silverlight, ein Browser-Plugin das die Grenzen des Browsers erweitert und mehr Freiheiten für den Entwickler bietet.
Doch heute habe ich was zu sagen, zum Thema Silverlight. Am 2. Dezember veranstalten wir einen Silverlight Firestarter Event. Hier die Details:
Keynote Starts December 2, 2010 at 9:00 pacific time Hear what’s coming next from Microsoft’s Scott Guthrie Training, labs & swag Online or in-person at Microsoft HQ, December 2nd 2010 It’s just like an extra day of PDC, dedicated to Silverlight
Ein ganzer Tag rund um das Thema Silverlight. Die Agenda findet man unter http://www.silverlight.net/news/events/firestarter/ wie auch die Registrierung.
Die Keynote ist um 18.00 Uhr deutscher Zeit und kann live betrachtet werden. Wer sich für das Event anmelden möchte kann dies über den folgenden Link tun: Register — Watch Online
Interview mit Peter Kirchner auf der TechEd Europe 2010 zum Microsoft Platform Ready Programm.
WebMatrix kann zum erstellen von Webseiten die Razor Syntax benutzen. In diesem Screencast wird kurz erklärt wie man mit der Razor Syntax arbeitet und wie einfach sich in das HTML Markup .NET Code einbinden lässt.
Dieser Screencast zeigt wie man eine Web Anwendung basierend auf ASP.NET Web Pages erstellt und in das Web publiziert.
Dieser Screencast zeigt wie man einen interaktiven Sketchflow erstellt und das Kundenfeedback in den Team Foundation Server integriert. Das ganze Szenario basiert auf der Tailspin Demo Anwendung.