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.
Ich wünsche Euch allen einen guten Rutsch in ein für Euch wundervolles Jahr 2011!
Bis dann, Dariusz
In diesem Post geht es um den Twitter Helper der über das Admin UI eingebunden werden kann.
Nach der Installation erhält man eine Datei im App_Code Verzeichnis namens TwitterGoodies.cshtml. Darin sind einige Twitter Helper Funktionen enthalten. Die Funktionen haben eine Menge Default Parameter, die folgenden Aufrufe sind nur Beispielhaft:
@TwitterGoodies.TweetButton()
@TwitterGoodies.FollowButton("writeline")
@TwitterGoodies.Profile("writeline")
@TwitterGoodies.Search("html5")
@TwitterGoodies.Faves("asp_net")
@TwitterGoodies.List("asp_net", "dev")
Natürlich kann man über die optionalen Parameter auch noch die Farben anpassen. Aber im Prinzip war es das schon. Man gibt in der Regel einen User an und erhält dann ein Twitter Widget erstellt das die Inhalte darstellt.
1: <!DOCTYPE html>
2:
3: <html lang="de">
4: <head>
5: <meta charset="utf-8" />
6: <title></title>
7: </head>
8: <body>
9: <article>
10: Dies ist ein Text der im Browser angezeigt werden soll.
11: </article>
12:
13: @TwitterGoodies.TweetButton(language: TwitterGoodies.Languages.German)
14:
15: <div>
16: @TwitterGoodies.Profile("writeline", tweetsBackgroundColor: "#ffffff", tweetsColor: "#000000")
17: </div>
18: <div>
19: @TwitterGoodies.Search("schnee")
20: </div>
21: </body>
22: </html>
Gestern habe ich auf Twitter die Frage gestellt ob
a.Add( b );
lesbarer sei als
categoriesWithPosts.Add(categoryWithPosts);
und es kamen einige Antworten zurück. Klar, die Frage war natürlich sehr ketzerisch gestellt, da die meisten auf Clean Code schwören. Mir ging es, und das ist leider in 160 Zeichen nicht zu schreiben, einfach um die Problematik das man bei Variablen und Klassennamen die mit dem gleichen Wort anfangen, Intellisense einfach außer Kraft setzt, da Intellisense sich entscheiden muss welchen Eintrag es als Default anzeigt während man Tippt. Na und ratet mal, in meinem Fall nimmt es fast immer das falsche.
Neben der Problematik mit Intellisense finde ich den folgenden Code schlecht lesbar. Hier ein Screenshot
Klar man kann Leerzeilen einbauen und mit Sicherheit sich nochmal Gedanken machen ob die Variablen genauso heißen müssen wie die Klassen die instanziert werden, doch ich möchte beim codieren einfach intuitiv bleiben, um den Fluß des Arbeitens, des kreativen Hackens nicht zu unterbrechen. Intellisense macht mir da schon einen Strich durch die Rechnung, da es mich immer wieder kurz Zeit kostet zu schauen ob es die richtige Variable ist die ich auswähle. Mit “kurz Zeit” ist wirklich eine sehr kurze Zeitspanne gemeint.
Dann habe ich das ganze mal einfach auf Object Initializer Syntax umgestellt und siehe da, ich finde das der Code lesbarer geworden ist, obwohl immer noch die gleichen Variablen verwendet werden.
Object Initializer geben allein durch die füllende Präsenz dem Code einen überschaubaren Rahmen und ich muss sagen, er liest sich wirklich schneller als oben.
MIt HTML5 Labs stellen wir HTML5 Prototyp Implementierungen zur Verfügung. Ich habe mir mal die IndexedDB Implementierung angeschaut. Zuerst muss man sich die Frage stellen, wie erweitert man die JavaScript Funktionalität des Internet Explorers? Die Antwort heißt: Component Object Model oder kurz COM.
Die Implementierung kommt mit zwei COM Objekten daher die unter der Haube den SQL Server Compact 4 benutzen. Einmal mit einer Synchronen Schnittstelle und mit der asynchronen Variante. DIe Installation des Prototypen ist einfach. Zuerst lädt man sich das Paket herunter, danach registriert man in einem elevierten Kommandofenster die entsprechende COM dll mittels regsvr32.
regsvr32 sqlcejse40.dll
Nach der Registrierung muss man den IE9 allerdings auch priviligiert starten um mit dem Prototyp zu arbeiten.
Man benötigt immer ein Initialisierungsskript. Schliesslich ist die Funktionalität in der COM Komponente drinnen und wir möchten das ganze aus JavaScript nutzen. Das Paket kommt mit einem solchen Skript mit und nennt sich bootidb.js. Ein Blick in die entsprechende Codezeile verrät uns auch das auf dem window Element entsprechend eine Eigenschaft indexedDB hinzugefügt wird:
1: if (!window.indexedDB) {
2: window.indexedDB = new ActiveXObject("SQLCE.Factory.4.0");
3: window.indexedDBSync = new ActiveXObject("SQLCE.FactorySync.4.0");
Was mir so nie bewußt war ist die Möglichkeit jedes IDispatch fähige Objekt in das HTML DOM des Browser zu stecken. Schaut man sich nämlich mal die Typelibrary der COM Objekte an so sieht man die Methoden die man schliesslich aus JavaScript heraus direkt benutzt:
1: [
2: odl,
3: uuid(567270C8-E61A-4A8D-9C2E-2D2EC47D8704),
4: helpstring("ObjectStore - Asynchronous interface"),
5: dual,
6: nonextensible,
7: oleautomation
8: ]
9: interface IDBObjectStoreRequest : IDBObjectStore {
10: [id(0x60040000)]
11: HRESULT put(
12: [in] VARIANT value,
13: [in, optional] VARIANT key,
14: [out, retval] IDBRequest** ppWebRequest);
15: [id(0x60040001)]
16: HRESULT add(
17: [in] VARIANT value,
18: [in, optional] VARIANT key,
19: [out, retval] IDBRequest** ppWebRequest);
20: [id(0x60040002)]
21: HRESULT get(
22: [in] VARIANT key,
23: [out, retval] IDBRequest** ppWebRequest);
24: [id(0x60040003)]
25: HRESULT remove(
26: [in] VARIANT key,
27: [out, retval] IDBRequest** ppWebRequest);
28: [id(0x60040004)]
29: HRESULT createIndex(
30: [in] BSTR name,
31: [in] BSTR keyPath,
32: [in, optional] VARIANT unique,
33: [out, retval] IDBRequest** ppWebRequest);
34: [id(0x60040005)]
35: HRESULT index(
36: [in] BSTR indexName,
37: [out, retval] IDBRequest** ppWebRequest);
38: [id(0x60040006)]
39: HRESULT deleteIndex(
40: [in] BSTR indexName,
41: [out, retval] IDBRequest** ppWebRequest);
42: [id(0x60040007)]
43: HRESULT openCursor(
44: [in, optional] VARIANT range,
45: [in, optional] VARIANT direction,
46: [out, retval] IDBRequest** ppWebRequest);
47: };
Ach ja, ich möchte noch folgendes Erwähnen.
Wichtig: Diese Registrierung ist nur Notwendig für diese Prototyp Implementierung. Falls IndexedDB in einen stabilen Spec Zustand kommt und die Funktionalität in den Browser wandert, so wird die Implementierung Bestandteil des Browsers und kann somit auch direkt aus JavaScript heraus genutzt werden ohne irgendwelche Hacks wie es jetzt bei der Prototyp Implementierung der Fall ist! Wollte das nur mal Klarstellen.
Nach der Installation können wir auch die Funktionalität direkt nutzen. Im Paket sind neben den Readme’s und der DLL auch Beispiele enthalten. Eines der Beispiele ist ein BugTracking System. Lädt man die Seite nun lokal in den Browser so kann man direkt Bugs erfassen und auch wieder suchen.
Das untere Bild zeigt wie man nach dem “Test Projekt” sucht und die Ergebnisse angezeigt bekommt:
Die Daten werden letztlich in einer SQL CE Datebank abgelegt und zwar als serialisiertes JSON (JavaScript Object Notation). Mittels eines SQL Server Management Studios kann man auch einen Blick in die Datenbank werfen. Diese findet man unter
%localappdata%\Microsoft\IndexedDatabase
und öffent diese einfach über den Dialog des Management Studios und schon hat man Zugriff auf die Datebank.
Aufgrund der Binär Felder die im Schema benutzt werden kann man allerdings ohne Konvertierungen die Werte nicht direkt einsehen.
Die Funktionalität der BugTracker Beispielanwendung ist schnell ausprobiert, doch jetzt möchte ich selbst mal eine Datenbank anlegen und Daten speichern. Zuerst einmal entscheide ich mich für die Asynchrone Variante der API. Einfach aus dem Grund da jeder synchrone Aufruf den Browser Request blocken kann. Das möchte man nicht. Man möchte eine Webseite haben die, wie sagt man so schön, “Responsive” ist.
Eine einfache TODO Liste soll hier als Beispiel dienen. Zuerst definiere ich das UI:
3: <html lang="en">
9: <input type=text id=todoitem />
10: <input type=submit value=add id=actionAdd />
11: <div id=todos></div>
12: </body>
13: </html>
Um IndexedDB zu benutzen brauche ich das Init Script, das füge ich hinzu. Zudem setze ich einen Handler auf den Submit Button der aufgerufen wird sobald dieser gedrückt wird.
1: <script type="text/javascript" src="bootidb.js"></script>
2: <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.4.min.js"></script>
3: <script type="text/javascript">
4: $(document).ready( function()
5: {
6: $("#actionAdd").click(function() {
7: });
8: });
9: </script>
Der Rahmen ist gelegt, nun geht es um die Daten. Im Beispiel das mitgeliefert wird, wird ein JavaScript Objekt erzeugt das Variablen und Funktionen vorhält. Ich habe mich an diese Vorgehensweise gehalten, da es durchaus sinnvoll ist bei asynchronen Aufrufen alles in einander wiederzuverwenden.
Die eigentliche Implementierung bedient sich auch ein paar Hilfsfunktionen, aber im großen und ganzen läuft es auf diesen Code zum erstellen der Datenbank hinaus:
1: requestDatabase = window.indexedDB.open(todoDB.db, 'Todo Database');
Das öffnen der Datenbank legt auch gleichzeitig diese an, falls nicht vorhanden. Nun muss man prüfen ob die Tabelle mit der man arbeiten möchte schon erzeugt ist. Die Prüfung ist im Gesamtcode zum Blogpost enthalten, ich möchte nur noch aufzeigen wie man dann letztlich die Tabelle anlegt und gleich noch einen Index hinzufügt.
1: requestObjectStore = database.createObjectStore(
2: todoDB.objectStore,
3: todoDB.keyPath,
4: true );
5: requestObjectStore.onsuccess = function(evt)
6: {
7: store = evt.result;
8: requestIndex = store.createIndex(
9: todoDB.indexTodo,
10: todoDB.indexTodoKeyPath,
11: false);
12: requestIndex.onsuccess = function(evt)
13: {
14: whenReady();
15: }
16: }
Zur Vereinfachung habe ich die onerror Methoden entfernt. Zeile 1 legt die Tabelle an, Zeile 8 den entsprechenden Index auf ein Tabellenfeld. Benutzt man einen Index hat man die Möglichkeit mit dem Cursor gezielt zu arbeiten und bei einer Suche auch nur Teilbereiche zu ermitteln. Anders ist es wenn man keinen Index hat, da macht man einfach einen Tablescan bis man den gesuchten Datensatz hat.
Auf der anderen Seite bietet die IndexedDB auch die Möglichkeit immer über den Primärschlüssel direkt auf einen Datensatz zuzugreifen. Zum Beispiel ein Datensatz mit dem Primary Key Id 723 kann mittels
store.get(723)
Der Komplettheit nun der vollständige Code einer einfachen HTML5 TODO List.
Das UI ist nicht sonderlich hübsch, aber es geht ja erstmal nur um die Funktionalität
Eine Indexbasierte Datenbank im Browser des Clients zu haben kann für manche Anwendungsszenarien sinnvoll sein. So können zukünftige HTML 5 Anwendungen offline betrieben werden (ja, auch dafür gibt es Specs) die z.B. auch Referenzdaten benötigen. Die Verwendung der API ist Stand heute noch ein wenig mühselig, auch direktes Tooling im Browser fehlt noch komplett, trotzdem ist es ein erster funktionaler Ansatz, der auf Feedback wartet.
Als Slug bezeichnet man den URL freundlichen Teil eines Blog Posts oder Artikels. Blog und CMS Systeme benutzen oft den Titel als Teil der URL. Da der Titel über Sonderzeichen verfügen kann, müssen diese für eine URL entsprechend kodiert werden. Ein Slug hilft hierbei den Post wiederzufinden. Die Seite http://blogs.msdn.com/webmatrix ist ebenso mit einer eigenen Blog Implementierung und Slug Implementierung ausgestattet.
Die Verwendung ist denkbar einfach. Speichert man den Slug Helper z.B. in die Datei Slug.cshtml im Verzeichnis App_Code, so kann man aus der ASP.NET Web Page entsprechend den Helper benutzen
@Slug.Generate(“Titel mit häufigen Sonderzeichen!”)
Daraus wird entsprechend der Slug
titel-mit-haeufigen-sonderzeichen
generiert.
WebMatrix Slug Helper from Dariusz on Vimeo.
Kurzes Video zum WebMatrix Slug Helper, mehr Details auf http://www.webmatrixhelper.net
1: @using System.Text.RegularExpressions;
2: @*
3: Code by Kamran Ayub, from his post at
4: http://www.intrepidstudios.com/blog/2009/2/10/function-to-generate-a-url-friendly-string.aspx
5: just added German special characters
6: *@
7:
8: @helper Generate( string title, int maxLength = 50 )
9: {
10: var slug = title.ToLower();
11: slug = Regex.Replace( slug, "ä", "ae");
12: slug = Regex.Replace( slug, "ü", "ue");
13: slug = Regex.Replace( slug, "ö", "oe");
14: slug = Regex.Replace( slug, "ß", "ss");
15: slug = Regex.Replace( slug, @"[^a-z0-9\s-]", "");
16: slug = Regex.Replace( slug, @"[\s-]+", " ").Trim();
17: slug = slug.Substring( 0, slug.Length <= maxLength ? slug.Length : maxLength).Trim();
18: slug = Regex.Replace( slug, @"\s", "-");
19: @:@slug
20: }
Datenbank Inhalte mit ASP.NET Web Pages anzuzeigen ist einfach. Zuerst benötigen wir die Datenbank selbst. Im Video und für das Code Snippet wird eine Datenbank mit dem Namen Kontaktdaten verwendet. Diese kann man einfach in WebMatrix erstellen. Jetzt muss noch eine Tabelle mit dem Namen Kontakte erstellt werden, die Tabelle enthält die Felder Email, Vorname und Nachname, wie in der folgenden Abbildung:
Ist das Schema angelegt, kann nun in der Webseite damit gearbeitet werden. Das Code Snippet unten enthält die fertige Seite die genau auf dieses Schema zugreift. Erwähnenswert ist die Zeile 4
var kontakte = db.Query(“SELECT * FROM Kontakte”);
In dieser Zeile wird das Select Statement an die Datenbank geschickt und die Resultate wandern nun in die Variable kontakte. Die Variable enthält nun eine Liste von Objekten die man mittels einer foreach Anweisung durchgehen kann. Jedes dieser Objekte ist ein dynamische Objekt, zur Laufzeit zusammengebaut mit den gleichen Eigenschaftsnamen die die Datenbank-Tabelle als Felder definiert hat.
Das dynamische Kontakt Objekt enthält somit die Zugriffseigenschaften Email, Vorname und Nachname. Diese wird mittels der Razor Syntax entsprechend angesprochen z.B.
@kontakt.Vorname
gibt den Vornamen aus der momentanen Zeile aus dem Feld Vorname zurück.
1: @{
2: var db = Database.Open("Kontaktdaten");
3:
4: var kontakte = db.Query("SELECT * FROM Kontakte");
5: }
6: <!DOCTYPE html>
8: <html lang="en">
9: <head>
10: <meta charset="utf-8" />
11: <title></title>
12: </head>
13: <body>
14: <header>
15: <h1>Meine Kontakte</h1>
16: </header>
17: <ul>
18: @foreach( var kontakt in kontakte )
19: {
20: <li>@kontakt.Vorname @kontakt.Nachname (@kontakt.Email)</li>
21: }
22: </ul>
23: </body>
24: </html>
Gestern haben wir die Seite HTML5 Labs veröffentlicht. Ziel der Seite ist es Prototypen von noch nicht ausgereiften W3C HTML5 Spezifikationen zu implementieren und zu veröffentlichen, um eine Diskussions- und Feedbackgrundlage für Entwickler zur Verfügung zu stellen.
The HTML5 Labs site is the place where Microsoft prototypes early and unstable web standard specifications from standards bodies such as the W3C. Sharing these prototypes helps us have informed discussions with developer communities, and contributes to a better implementation experience with draft specifications.
Solche Prototypimplementierungen helfen Entwicklern Technologien zu verstehen und geben Ihnen auch Gelegenheit zum Feedback. Es hilft auch den Mitgliedern des W3C Spezifizierungsprozesses dieses Feedback in die Spezifikation mit einfließen zu lassen und so eine stabilbe Spec zu erarbeiten. Betrachtet man den HTML5 Standardisierungsfortschritt, so kann man diese in stabile und experimentelle Spezifikationen einordnen. Stabile Spezifikationen finden sich in allen gängigen modernen Web Browsern wieder, wie auch dem Internet Explorer 9. Die stabilen HTML5 Features können demzufolge auch in Webseiten ruhigen Gewissens eingebaut werden. Die semantischen Tags sind hier ein gutes Beispiel. Auf der anderen Seite gibt es Spezifikationen die noch nicht so ausgereift sind und die man eben als experimentell bezeichnen kann, wie zum Beispiel die WebSockets.
WebSockets im Browser klingt nach einer guten Idee. Direkte Kommunikation aus JavaScript mit dem Server, ohne Plugin. Die Spezifikation wurde schon in einem frühen Stadium von diversen Browser Herstellern implementiert, was zur Folge hat das Änderungen direkt an die API Schnittstelle für Entwickler durchgereicht werden und somit der geschriebene Code nicht funktioniert und umgestellt werden muss. Zudem ist nicht abzusehen ob eventuelle Sicherheitsrisiken in sich ändernden Spezifikationen auftun.
Als Beispiel können wir einen Blick auf die Mozilla Entwicklung werfen, die für jedermann einsehbar ist und dort konkret auf Fehler 602028. Hier die Beschreibung des Bugs:
The -76 implementation of websockets should be prefixed in an experimental namespace for ff 4, while the final websockets protocol is sorted out in the IETF.
Man möchte die implementierung in einen experimentellen Namespace überführen, da das Protokoll aussortiert wurde. Daraufhin gab es gleich einen Kommentar das man damit eine Inkompatibilität herbeiführt da andere Browser diesen Namespace nicht haben.
We most certainly should not. Chrome and Safari have released -76 support unprefixed, and Opera will do the same. Prefixing in Gecko doesn't gain anybody anything, because any new version that wants to see adoption will have to be compatible with the shipped implementations, regardless of what we do. It only hurts us, because "Firefox doesn't implement HTML5".
Ein weiterer Kommentar bestätigt das die Implementierung sich auf jeden Fall ändern wird und verweist auch darauf das andere Browser Hersteller dieses Feature ebenso in einen Namespace prefixen werden. [Comment 7]
Die Diskussion schreitet voran, ein weiterer Kommentar schlägt vor den Prefix wegzulassen, mit der Begründung das Entwickler wissen das Spezifikationen die in Entwicklung sind auch Code Änderungen mit sich ziehen und demzufolge ist es in Ordnung wenn der Code auf der Serverseite nicht mehr funktioniert und angepasst werden muss. Das Original liest sich einfach besser [Comment 26]:
As for prefixing with x-, I would prefer not to do that as we would then keep it around forever and probably not migrate. I think the best strategy is to just keep breaking people to force the expectation that this is still a work in progress, and if you're not aware of that you shouldn't be using it...
Die Kommentar Diskussion kommt dann an eine entscheidende Stelle [Comment 51], als jemand die Sicherheitsproblematik der WebSockets Spezifikation anspricht, die es theoretisch ermöglicht Kommunikation zu manipulieren. Kurz es gibt ein Sicherheitsproblem.
Genau das ist der entscheidende Unterschied zwischen stabilen und experimentellen Spezifikationen. Bisher hat Microsoft im Internet Explorer 9 die WebSockets Implementierung nicht angegangen, denn es bringt dem Entwickler nichts mit Features zu arbeiten die noch sehr weit weg von Produktionsreife sind. Firefox und Opera haben nun die WebSockets Implementierungen deaktiviert, vor allem die Sicherheits- und Kompatibilitätsprobleme waren hier ausschlaggebend.
Ist dass das Aus für WebSockets? Nein, wir sind nach wie vor mit in der Diskussion um die Spezifikation und auch andere Browser Hersteller sind daran beteiligt (draft-montenegro-hybi-upgrade-hello-handshake-00).
Auf der anderen Seite möchten aber Entwickler genau mit diesen Featuren experimentieren und genau hier kommt HTML5 Labs ins Spiel. Wir bieten nun auf HTML5 Labs Implementierungen für diese experimentellen Zweige an. Zwei Prototyp Implementierungen stehen zur Verfügung. Einmal für WebSockets und einmal für IndexedDB.
WebSockets is a technology designed to simplify much of the complexity around bi-directional, full-duplex communications channels, over a single Transmission Control Protocol (TCP) socket. It can be implemented in web browsers, web servers as well as used by any client or server application. The WebSockets API is currently being standardized by the W3C Web Applications Working Group and the protocol is being standardized by IETF Hypertext Bidirectional (HyBi) Working Group. Link: WebSockets Prototype IndexedDB is a W3C draft Web specification for the storage of large amounts of structured data in the browser, using indexes that allow for high performance searches on this data. The IndexedDB API is currently being standardized by the W3C Web Applications Working Group. IndexedDB can be used for browser implemented functions like bookmarks, and as a client-side cache for web applications such as email. Link: IndexedDB Prototype
WebSockets is a technology designed to simplify much of the complexity around bi-directional, full-duplex communications channels, over a single Transmission Control Protocol (TCP) socket. It can be implemented in web browsers, web servers as well as used by any client or server application. The WebSockets API is currently being standardized by the W3C Web Applications Working Group and the protocol is being standardized by IETF Hypertext Bidirectional (HyBi) Working Group.
Link: WebSockets Prototype
IndexedDB is a W3C draft Web specification for the storage of large amounts of structured data in the browser, using indexes that allow for high performance searches on this data. The IndexedDB API is currently being standardized by the W3C Web Applications Working Group. IndexedDB can be used for browser implemented functions like bookmarks, and as a client-side cache for web applications such as email.
Link: IndexedDB Prototype
Letztere Spezifikation hat mehr an Bedeutung gewonnen und für uns eine Prototyp Implementierung Wert. Diese Implementierungen müssen gesondert und bewußt installiert werden. Somit ist jedem Entwickler klar das es sich um eine experimentelle Implementierung handelt und diese sich natürlich ändern kann.
Es gibt noch weitere Spezifikationen die man als experimentell bezeichnen kann, hierzu gehören unter anderem die File API und auch WebGL. Wer mit diesen Featuren experimentiert muss sich im klaren sein das diese sich auch ändern. Browser die diese direkt implementieren laufen Gefahr das geschriebener Code nicht mehr Funktioniert und unter Umständen auch Sicherheitslücken entdeckt werden. Eine Spezifikation in der realen Welt draußen zu benutzen macht Sinn sobald diese die Hürde des W3C genommen hat und als Stabil gekennzeichnet ist.
Anders gesagt: Der Internet Explorer 9 unterstützt den HTML5 Standard und die stabilen Spezifikationen. Der IE9 ist damit bereit HTML5 fähige Seiten Millionen von Benutzern, hardware unterstützt, performant anzuzeigen. Der IE9 bietet damit Entwicklern eine gute Basis zur HTML5 Webseiten Entwicklung. Wer darüberhinaus mit den experimentellen Spezifikationen arbeiten möchte, kann dies mit den Prototyp Implementierungen der HTML5 Labs tun.
Mein Kollege Oliver Scheer hat eine Challenge gestartet. Er sucht die ultimative Herausforderung für eine Demo im Bereich Windows 7 und / oder Silverlight. Wer Interesse hat Ihm mal zu zeigen wo der Hammer hängt, der kann Ihn einfach anpingen.Amplify’d from blogs.msdn.comWelche Demos wollt ihr sehen? Fordert mich heraus!Welche Demos im Bereich Windows 7 (Desktop) und Silverlight würdet ihr gerne sehen? Welche Themen in diesen Bereichen interessiert euch am meisten?Was wolltet ihr schon immer mal wissen, aber habt euch nicht getraut zu fragen?Viel Spaß beim Ausdenken von Herausforderungen an mich. OliverRead more at blogs.msdn.com
Mein Kollege Oliver Scheer hat eine Challenge gestartet. Er sucht die ultimative Herausforderung für eine Demo im Bereich Windows 7 und / oder Silverlight. Wer Interesse hat Ihm mal zu zeigen wo der Hammer hängt, der kann Ihn einfach anpingen.
Welche Demos wollt ihr sehen? Fordert mich heraus!
Welche Demos im Bereich Windows 7 (Desktop) und Silverlight würdet ihr gerne sehen?
Welche Themen in diesen Bereichen interessiert euch am meisten?
Was wolltet ihr schon immer mal wissen, aber habt euch nicht getraut zu fragen?
Viel Spaß beim Ausdenken von Herausforderungen an mich. OliverRead more at blogs.msdn.com
Viel Spaß beim Ausdenken von Herausforderungen an mich. Oliver
Microsoft Platform Ready ist die neue Plattform für Softwarehersteller weltweit, auf der zu aktuellen Microsoft-Technologien, Ressourcen, Veranstaltungen, Kompatibilitätstests, Vertriebs- und Marketingunterstützung zusammengefasst werden.
In Deutschland bieten wir Ihnen im Frühjahr 2011 vier neue Veranstaltungen zu den Themen SQL Server 2008 R2 und SharePoint 2010 an. Und damit Sie auch die Informationen erhalten, die Sie in Ihrer Rolle in Ihrem Unternehmen benötigen, haben wir die Veranstaltungen aufgeteilt in Briefings für Geschäftsführer und IT-Leiter sowie in Camps für technische Leiter sowie Entwickler.
Für weitere Informationen, Agenda und zur Anmeldung folgen Sie den einzelnen Links:
Für meine aktuelle Demo benötige ich eine generierte Slug. In der Suchmaschine meiner Wahl bin ich auch fündig geworden. Das ganze benötige ich als Razor Helper, dementsprechend habe ich den Code an die Helper Syntax angepasst.
Das Schnipsel habe ich auf Gist gelegt, hat den Vorteil das andere den Code verändern können und man so eine Historie der entsprechenden Schnipsel hat. Here we go:
Ich denke ich werde Gist noch öfters für diese Art von Schnipsel nutzen.