.
Anmeldung | Registrieren | Hilfe

.NET-Blogs Archiv Mai 2008

Microsoft Source Analysis for C#

31.05.2008 14:59:00 | Klaus Bock

Mit Microsoft Source Analysis for C#, aka StyleCop, wurde ein weiteres Werkzeug zur Codeanalyse freigegeben. Im Gegensatz zu FxCop, der den IL-Code analysiert, untersucht Source Analysis den Quellcode. Das Tool wird als VS-AddIn oder während des Build-Vorgangs verwendet. Da ich nur die C# Express Version besitze, kam für mich nur die Verwendung im Build-Prozess in Frage. Wie Source Analysis in den Build-Prozess eingebunden wird, ist sehr ausführlich in diesem Blog Artikel beschrieben. An das UI von Source Analysis kommt man in der Express Edition nicht so schön heran wie in Visual Studio Standard oder Professional. Aber dafür gibt es in den Express Editions unter Extras den Menüpunkt Externe Tools. Hier kann nun die SourceAnalysisSettingsEditor.exe mit der Einstellungsdatei Settings.SourceAnalysis als Parameter eingetragen werden. Hier ein ScreenShot wie der Menüeintrag aussehen sollte.

Externe Tools SourceAnalysis Da ich nicht für jedes Projekt neue Einstellungen benötige, verwende ich nur die Einstellungen der Datei im Installationsordner von Source Analysis. Für Leute die in ihren Projekten unterschiedliche Einstellungen benötigen, kann hier mit den Argumenten, etwa dem Projektverzeichnis, von C# Express gearbeitet werden.

Nach dem der Menüpunkt jetzt zur Verfügung steht, können die Einstellungen von Source Analysis den eigenen Anforderungen angepasst werden. Ich kann allen die ihre Kommentare in deutsch ausführen nur empfehlen die Regel SA1623 zu deaktivieren. Diese Regel prüft den Kommentar von Eigenschaften ob dieser, je nach Accessor, mit Get's oder Set's beginnt. Macht ja im deutschen wenig Sinn.

Wer eigene Regeln verwenden will findet in diesem Blog eine recht ausführliche Anleitung um Bibliotheken mit eigenen Regeln für Source Analysis zu erstellen.

Nach dem Source Analysis das erste mal über eine Bibliothek gelaufen war, bekam ich große Augen. Ich dachte immer ich würde mich an die Entwurfsrichtlinien halten. Aber über 500 Warnungen sagen etwas anderes aus. Gut, zum größten Teil waren es Meldungen der Regel SA1027: Tabs are not allowed. Use spaces instead. Was Source Analysis auch gar nicht gefällt, sind private Felder die mit einem "_" beginnen. Auch die Regel SA1201: All properties must be placed after all constructors. wurde oft angezeigt. Bisher habe ich immer wie folgt strukturiert: private Felder, Eigenschaften, Konstruktoren, öffentliche Methoden und zum Schluss die privaten Methoden. War anscheinend falsch.

Für einzelne Personen wie mich ist es relativ einfach den Stiel zu ändern. Aber was ist mit großen Teams? Wer Interesse hat, kann sich einmal die Diskussionen zu Source Analysis zu Gemüte führen.

 

Technorati-Tags: |

Unbeschwertes Debugging von WebApps und Breakpoint Condition

31.05.2008 12:45:00 | Peter Bucher

Auf einen Request warten / Nicht an eine Browserinstanz gebunden

Standardmässig ist unter den Web-Einstellungen in den Projekt-Einstellungen jeweils die per Visual Studio markierte Applikation + ggf. eine Startseite markiert.

Beim Starten des Debugging geht ein neues Fenster auf, und bei einem Breakpoint meldet sich VS wieder.

Soweit alles bekannt und nicht mal so schlecht. Allerdings ist die gestartete Browser Instanz direkt mit dem derzeitigen Debugging verkettet und beim Schliessen der Browserinstanz bricht das Debugging im Visual Studio ab.

Eine weitaus komfortablere Lösung ist folgendes:

weitforarequest

Zu finden über: Rechtsklick auf die WebApp -> Eigenschaften -> Web

Mit dieser Einstellung kann das Debugging gestartet werden, ohne dass direkt an eine Browserinstanz gebunden wird.
Wenn dann seperat irgend ein Browser oä. einen Request an die aktive Adresse sendet, wird das Debugging aktiv.

So geht nicht immer ein neues Fenster auf, das Debugging läuft durch (Nicht nur ein Request + immer wieder Neustarten) und es können bspw. (obwohl das IMHO kein Sinn macht) mehrere Browserinstanzen verschiedener Typen gleichzeitig invoviert sein.

Eine ganz nette Sache und die Geschichte funktioniert sowohl mit dem integrierten Webserver, wie auch mit einem IIS.

Jürgen setzt das auch schon längere Zeit ein und fährt gut damit.

Breakpoint Condition

Breakpoints kennen wir ja alle, eine Breakpoint Condition ist eine Einschränkung - sodass der Debugger nur bei Erfüllung einer Kondition anhält.

Beispiel aus der Praxis:
Ein Datengebundenes Control ist mehrfach auf einer Seite vorhanden, das muss auch so sein.
Jedoch verhält sich das Control in einem Fall nicht so wie es sollte, evt. sogar im Zusammenhang mit den anderen Contorlinstanzen.

Beim Debuggen hänge ich mich in die Methode "PerformDataBinding" ein, möchte jedoch nur dann hängen bleiben, wenn ich tatsächlich bei meinem gewünschten Control bin.

Nichts leichter als das - einfach ein Breakpoint anlegen, anschliessend ein Rechtsklick darauf und auf "Condition" klicken.
Im folgenden Fenster kann - sogar mithilfe von Intellisense - direkt eine Kondition im aktuellen Kontext gestellt werden.

In diesem Beispiel überprüfe ich per this.ID == "meinControl", ob das gewünschte Control erreicht ist. Wenn wahr hält der Debugger dort an.

breakpointcondition 

Möglich ist sowas auch in Handarbeit per System.Diagnostics.Debugger-Klasse.
Beispiel (Macht schlussendlich das selbe wie oben):

if (this.ID == "meinControl")
    Debugger.Break();

 

Viel Spass beim Debuggen!

VSTO 3.0 / Office 2007: Whitepaper für MSI-Deployment

30.05.2008 15:29:37 | Jens Häupel

Lange hat's gedauert, aber nun ist das Whitepaper verfügbar. Darin wird erklärt, was alles zu tun ist, um VSTO 3.0 Lösungen für Office 2007 in einem Windows Installer Package zu verteilen.

Teil 1 und Teil 2

Inhalt:

You can develop a Visual Studio Tools for the Office system 3.0 solution for the 2007 Microsoft Office system, and deploy the solution by using a Visual Studio 2008 Setup project to create a Windows Installer package. The discussion includes steps for deploying a simple add-in, including additional files and components, and trusting the solution. This applies to both application-level add-ins and document-level solutions.

PDC 2008 - Open for Registration

30.05.2008 15:05:54 | Jens Häupel

PDC2
Die Professional Developers Conference (PDC) steht in diesem Jahre wieder vor der Tür.

Vom 27. bis 30. Oktober 2008 wird im Convention Center von Los Angeles wieder ein Feuerwerk an Developer Technologien entfacht.

Über 160 technische Sessions zu IE8, Windows 7, Cloud Services, Silverlight, VSTS, Windows Mobile und vielem mehr.

Sie können dabei sein.

Die Registrierung ist jetzt offen.

PDC

Sandcastle Mai 2008 CTP released

30.05.2008 09:55:00 | Rainer Schuster

Anand Raman, der Group Manager bei Microsoft hat heute Nacht eine neue Version von Sandcastle (2.4.10520) released. Sie kommt etwas verspätet, da sie schon für Ende April angekündigt war. Nun wird es nicht mehr lange dauern und die neuen Version von Sandcastle Help File Builder und DocProject mit dem visuellen Editor für konzeptuelle Hilfe mit MAML werden ebenfalls in einer neuen Version freigegeben. Ich habe mit beiden Authoren Kontakt aufgenommen und so kann ich sagen, dass SHFB z.B. Ende nächster Woche erscheinen soll. Das wäre dann die Version 1.7.0.0. In der Diskussionsliste hatte ich gestern bereits nach einer BETA der Version gefragt und hätte sie auch fast bekommen, wenn sich der Release des Sandcastle Mai 08 CTP noch weiter verschoben hätte. So dürfen wir alle gespannt sein, wie die erste Integration der Editoren umgesetzt ist. Ich habe schon überlegt ein eigenes Projekt für einen solchen Editor als VSPackage für das Visual Studio zu starten und habe bereits im VSX Forum einen entsprechenden Post gemacht. Kennt sich vielleicht jemand hier mit Microsoft.VisualStudio.XmlEditor aus? Nebenbei bemerkt, haben die Foren von MS einen neuen Anstrich bekommen. Das Design ist jetzt an das neue Layout von MyMSDN angepasst und sieht nun wieder zeitgemäß und sehr ansprechend aus.

Mit UI Automation Web Anwendungen testen

29.05.2008 15:51:37 | Christian Binder

Gestern hatte ich einen Vortrag zum Thema Rosario bei der .Net User Group in Ulm. Ein Demo war die UI Automatisierung einer Web Application vom Manual-test zum automatisierten Unit Test, Thomas hat die Idee gleich mal aufgenommen und das Ganze mit dem UI Automation Framework getestet, zu dem wir schon mal ein Webcast gemacht haben. Natürlich gibt es noch keinen Recorder, aber Hier findet Ihr das Ergebnis :-)

Viel Spass

Chris

System.Drawing.Color von Html / Win32 / Ole und zurück

28.05.2008 20:24:00 | Peter Bucher

Wenn ein Farbwert als System.Drawing.Color Objekt vorliegt und ein Stringwert (Name oder Hex.) für die Html-Ausgabe benötigt wird, gibt es eine einfache Lösung dafür.
Die Klasse System.Drawing.ColorTranslator bietet einige statische Methoden an, die eine einfache und saubere Übersetzung ermöglichen (Auch Win32- oder Ole-Farbwerte).

Darin ist auch die Methode FromHtml enthalten, womit es eine bessere Möglichkeit gibt, als mein Hilfsmethode.
Nach einem schnellen Blick, wird da intern auch nicht der WebColorConverter benutzt, so stelle ich mir die Frage: Wieso zwei Klassen die das selbe anbieten?

Via C#-Farben in HTML-Farben umwandeln

Artikel: StyleSwitcher selbst gemacht

28.05.2008 19:15:18 | Peter Bucher

asp0208-cover-300px

In der aktuellen ASP.NET Professional 05/2008 Ausgabe  findet sich ein Artikel von mir über das StyleSwitcher-Control.
Im Artikel finden sich Informationen über das Innere des Controls, die Überlegungen dazu und die Implementation wird Schritt für Schritt erklärt.

Wer kein Abonnement von ASP.NET Professional besitzt, trotzdem mal reinschnuppern möchte und meinen Artikel interessant findet, kann sich ein kostenloses Probeabo zukommen lassen (Dort ist der aktuelle Artikel drin).

Steve & Bill…

28.05.2008 07:18:20 | Robert Mühsig

Herrlich was man auf YouTube für alte Microsoft Werbung findet:

Ein paar weitere Videos gibts auf Microsoft Watch - oder YouTube ;)

ASP.NET MVC Preview 3 released

28.05.2008 00:02:40 | Robert Mühsig

Das ASP.NET Team (siehe Scotts Blog) hat die 3. Preview des MVC Modells zum Downloaden freigegeben:

Die 3. Preview knüpft an den Code Release im April an und bringt eine ganze Reihe Verbesserung:

  • Control Action Methods & ActionResults z.B. für…
    • AJAX: JsonResult
    • Streaming Data: ContentResult
    • Web: HttpRedirect / RedirectToAction/Route
    • Dies ermöglicht sehr elegantes Unit-Testen
  • HTML Helper wurden verbessert
  • URL Routing & Mapping wurde erweitert (und ist nun Teil des .NET 3.5 SP1 für WebForms und MVC)

Was leider noch nicht enthalten ist, sind Sub-Controller, bessere AJAX Integration, Authentication, Authorization, Components - dies soll in späteren Releases nachgeschoben werden (Achtung: Zum Teil geht es hier auch um eine nettere Integration - Logingeschichten können sehr wohl mit dem MVC Framework gemacht werden.).

Weitere Infos einfach bei Scott nachschauen

Back in Black - Me too

27.05.2008 18:52:20 | Peter Bucher

VS08_h_rgb_r

Nachdem viele andere zur schwarzen Seite gewechselt sind, musste ich das auch mal probieren.

Seit Mitte April habe ich ein schwarzes Farb-Theme für Visual Studio eingestellt (Wink an Albert :).
Am Anfang ist die Benutzung etwas komisch und es braucht eine gewisse Gewöhnung.

Nach dieser Zeit muss ich sagen, dass es mir in schwarz besser gefällt :-)

backInBlack

Probiert es einfach selber mal aus.

PS: Im Forum bitte nicht schwarz Posten :))

Neu in TFS mit dem VS2008 Sp1 Beta

27.05.2008 16:53:05 | Christian Binder

Ich wurde nun doch des öfteren gefragt, was alles neu sein wird mit VS2008 Sp1.

  • Support for Windows Server 2008.
  • Support for SQL Server Codename Katmai CTP6.
  • The Add to Source Control dialogs have been improved to be easier to use and more scalable.
  • Drag & Drop from Windows Explorer to add to Source Control.
  • Support for Version control operations on files not in bound solutions.
  • Right-click access to set Working Folder/Cloak of folders from within Source Control Explorer.
  • Check in date/time column in Source Control Explorer.
  • Editable path field for the Source Control Explorer.
  • Email work items and queries to someone.
  • A new API to download files to a stream.
  • Links to Team System Web Access pages from notifications.
  • Improvements to the number of projects per server.
  • Performance and scale improvements.
  • Improvements to the VSS converter to make it much more robust.
  • Support for creating Team Projects from the command line.

Die Beta Version  ist schon verfügbar von TFS Sp1 und ist hier zu bekommen.

Viel Spass
Chris

Videos: das neue C++ Feature Pack und VSTS für native C++ Developer

27.05.2008 13:50:24 | Christian Binder

Boris Jabes aus dem C++ Product Team war zu Besuch in Bad Homburg und hat das neue C++ Feature Pack vorgestellt. Wir haben das wichtigste für Euch aufgenommen :-) und kleinere Videos zerteilt.

C++ what is new with Visual Studio 2008  : Vista Development and Security
Was ist neu in VS 2008 für C++ Entwickler? Fokus liegt hier for allem auf Vista Development und Security Features wie UAC.

video

C++ what is new with Visual Studio 2008 :  Build and Marshaling Features
Was ist neu in VS 2008 für C++ Entwickler? Fokus liegt hier auf Productivity Features wie den neuen Build- und Marshaling Features

video

Building Modern User Interfaces with the new MFC 
Die neuen MFC Features aus dem Feature Pack im Überblick. Oder wie Ihr Eurer MFC Applikation mit geringem Aufwand ein modernen Look geben könnt.

video

TR1 in Visual Studio 2008 and beyond
Was im TR1 Standard drin? Shared_ptr, weak_ptr, regex, mem_fn(),bind(), function, tuple, array, ......... 

video

The next C++ Generation: C++0x
Ein Blick in die Zukunft: C++0x

video

 

Die Präsentationen gibt's hier:

Building Modern UI with the new MFC

TR1 in VC 2008 and beyond

 

Dann hab ich mit Boris gleich noch zwei Videos zum Thema VSTS für native C++ Entwickler aufgenommen. Dabei haben wir folgende Features beleuchtet:

VSTS Profiler for native C++ Developer
Video, Demo Solution hier

VSTS Static and Dynamic Code Analysis for native C++ Developer
Video, Demo Solution hier

Viel Spass

Chris

Sandcastle und seine Helfer

27.05.2008 11:04:00 | Rainer Schuster

Rund um Sandcastle hat sich über die Jahre hinweg eine wachsende OpenSource Community entwickelt. Die meiner Meinung nach zwei größten Leistungsträger sind Sandcastle Help File Builder (SHBF) und DocProject. Dazu gesellt sich jetzt ein weiteres sehr interessantes Projekt - Sandcastle Assist, das sich die Hilfe für die Hilfe zur Aufgabe gestellt hat. Paul Selormey hat das Projekt eröffnet und will eine weitere Bibliothek zum Erstellen Hochwertiger Dokumentationen bereitstellen, sowie zusätzliche Build-Componenten für die beiden bereits genannten Projekte. Aus einem Artikel bei Codeproject über konzeptuelle Hilfe ist diese neue Version entstanden. Der Artikel ist im übrigen einen Blick wert. Das Ergebnis ist durchaus beeindruckend, obwohl es im Moment noch relativ umständlich ist, sich diese Dokumentation per MAML zusammen zu bauen. Doch hier wird es bald Abhilfe geben. Sandcastle soll noch Ende dieser Woche in einer neuen CTP erscheinen. Diese Version sollte es ursprünglich bereits Ende April geben. Sobald diese Version fertig ist, wird es von DocProject und SHFB jeweils kurze Zeit später (laut Aussage der Projektleiter und aus eigener Erfahrung ca. 1-2 Wochen später) eine neue Version der Tools geben, die das Erstellen der konzeptuellen Hilfe mit einem rudimentären visuellen Designer unterstützen. Ich bin schon gespannt, wie diese ersten Versionen aussehen. Danach wird es dann kurze Zeit später von mir einen kleinen Erfahrungsbericht geben.

Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, C#, Entity Framework, WPF, Javascript

26.05.2008 22:29:49 | Robert Mühsig

ASP.NET MVC:

ASP.NET:

ADO.NET Entity Framework:

Source Analysis for C#:

Architektur / Design:

Silverlight 2:

WPF:

Tipp / C#:

Design / CSS / Javascript:

Verschiedenes:

Extra-Session auf der Webinale - Kostenloses von Microsoft

26.05.2008 17:19:12 | Oliver Scheer

Diese Session gibt eine Übersicht über kostenlose Tools, Services und Komponenten von Microsoft für professionelle und semiprofessionelle Webentwickler. Von der Programmier-IDE, über das Webdesigntool bis hin zur Datenbank bietet Microsoft viele kostenlose Lösungen an. Neben den Basistools der Webentwicklung werden auch Enterprise-fähige Komponenten und Technologien vorgestellt, die es erlauben von kleinen Homepages bis hin zu Portalen alles zu bauen, was das Webentwickler- und Webdesignerherz begehrt – ohne Software-Lizenzkosten.

Mehr Infos: http://entwickler.com/konferenzen/planer/show_details.php?konferenzid=61&sessionid=8494

Sonntag 2.0

26.05.2008 12:45:00 | Lori Grosland

Gestern war Sonntag 2.0 in München, ein Mini-BarCamp zu Themen Web 2.0 und Sicherheitsaspekte.  Es war Microsoft Deutschlands erstes Mal, ein BarCamp ähnliches Event zu veranstalten. 

 

Obwohl es eine sehr kleine Runde war, war das Gespräch interessant.  Ich habe zumindest etwas neues zum Thema Sicherheit gelernt. :-)

 

In der Zukunft werden wir versuchen, ähnliche Events zu veranstalten. Aber nächstes mit ein bisschen mehr Anlaufzeit. Ich glaube 2 Wochen Anlaufzeit war wahrscheinlich zu wenig.

 

Weil das Event kurzfristig geplant war, wussten wir nicht wie viele Leute kommen würden.  Wir haben deswegen ein bisschen zu viel Essen bestellt und was übrig war, haben wir an der Bahnhofsmission gespendet.  Ich denke die Leute da haben sich darüber gefreut.  :-)

 

Hier sind ein paar Foto-Impressionen von Sonntag 2.0…

 

CIMG0317 CIMG0318  CIMG0319 IMAGE_170

Ze Germans - In die Mongolei und Zurück

25.05.2008 20:10:00 | Lori Grosland

Martin Saternus hat so viel Spaß mit unserem englischen Gespräch über Mongol Rally, dass er unbedingt ein zweites Mal befragt werden wollte - aber das zweite Mal auf Deutsch.  Ok, vielleicht habe ich ihn gezwungen.  ;-)  Aber es hat einfach Spaß gemacht, mit Richard und Martin darüber zu reden.  Ich glaube es war immer mein Traum  sowas ähnliches zu machen.  Mal gucken, ob ich es je schaffe. 

Hier ist das deutsche Interview mit Martin über Mongol Rally 2007, die Highlights und sein Lieblings-Fotos.  Mehr Info und Highlights von der Abendteuer und der Reise, findet Ihr auf ihrem Blog:

http://www.mongolrally.de/

Geeks in a Crap Car - Mongol Rally -> Photos & More

25.05.2008 19:25:00 | Lori Grosland

Last year in May I spoke with Martin Saternus at the STC in Duisburg about the Mongol Rally and he showed me the car that he and Richard Süselbeck would be driving from London to Ulan Bator.  Martin was at the STC to raise money for two charities, so they would be able to participate in the rally.  Students were given the opportunity to donate a little money to help the team out and in return they were able to sign their names on the rally car. 

I traveled back to Duisburg late last year to get the scoop from Martin about the adventure and to find out if the car and signatures made it to Ulan Bator.  Martin filled me in on his highlights from the trip and showed me some of his souvenirs and favorite photos from the trip.

Check out their blog for more highlights from the trip:

http://www.mongolrally.de/

ASP.NET 3.5 Extensions Preview

24.05.2008 23:14:00 | Ozgur Aytekin

Die neuen Features der Version ASP.NET 3.5 Service Pack 1 Beta werden auf der folgende Seite mit Videos vorgestellt:

ASP.NET Dynamic Data: ASP.NET Dynamic Data helps you quickly build a fully customizable, data-driven application without writing code. Dynamic Data provides a rich scaffolding framework that is easily extensible by using the traditional ASP.NET programming model.

ASP.NET AJAX browser history: ASP.NET AJAX history provides support for navigating within an AJAX application by using the Forward and Back buttons in the browser.

ASP.NET AJAX script combining: The ASP.NET AJAX script combining feature improves the performance of AJAX applications by reducing the number of scripts that have to be individually downloaded to the browser.

ADO.NET Data Services: ADO.NET Data Services provide new services that find, manipulate and deliver data over the web using simple URIs. Benefits include an easy and flexible way to access data over the web, while enabling the separation of presentation and data access code.

ADO.NET Entity Framework: ADO.NET Entity Framework is a new modeling framework that enables developers to define a conceptual model of a database schema that closely aligns to a real world view of the information. Benefits include easier to understand and easier to maintain application code that is shielded from underlying database schema changes.

Die URL: ASP.NET 3.5 Extensions Preview

ADO.NET Entity Framework - How Do I - Videos

24.05.2008 20:02:00 | Ozgur Aytekin

ADO.NET Team hat auf ihrem Blog mehrere Videos zum Thema ADO.NET Entity Framework veröffentlicht.

Für eine Einführung in das Thema Entity Framework kann euch diese Videos emfehlen:

How Do I Get Started with the Entity Framework?

How Do I Use the new Entity Data Source?

How Do I Serialize a Graph with the Entity Framework?

How do I use Entity Client?

Viel Spass...

Silverlight String.Format Tool

24.05.2008 19:40:00 | Ozgur Aytekin

Mit Silverlight implementiertes String.Format Tool "String.Format" kann vielen Entwicklern helfen, die verschiedenen Möglichkeiten der String-Formatierungen direkt Online auszuprobieren.

Silverlight_String_Format_Tool

Das Tool findet ihr unter: String Format - Made Simple

Geeks in a Crap Car - Mongol Rally -> They made it!

24.05.2008 15:10:00 | Lori Grosland

Whatever happened to those two German PhD Computer Science students that took part in the Mongol Rally 2007?!  Just as a reminder, the Mongol Rally is a charity event where participants drive from London to Ulan Bator in Mongolia in a crap car without a GPS or a navigation system.  Well...

They made it!  And in one piece!

Late last year I visited with both Martin Saternus and Richard Süselbeck to find out how the Mongol Rally 2007 went.  In this video, I chat with Richard about their experience during the trip, how much money they were able to donate to charities and of course their plans for the future. 

Check out their blog for more highlights from the trip:

http://www.mongolrally.de/

 

NOTE:  Why is this video coming so late, you may ask?  Well, some of you may remember that I had a small audio problem with some of my videos around the November and December timeframe.  Ok, if you have watched some of my videos from Innovation Day in Brussels then you know that it was more than a small problem.  Let’s just say that whole thing was a learning experience.  Somebody changed the audio settings on the camera from auto to manual and I didn’t notice that the setting had been changed.  I didn’t check it and just used the camera.  Grrrrr.  :-(  At any rate, I had to do some extra editing on many of my videos to make them more audible.  This Mongol Rally video - as well as two others that I will be posting soon - turned out well, but it just took some extra time to get them edited.  By the time I was done with the editing, it was CeBIT time and I had tons of videos to shoot, edit and upload there and for a couple of weeks after.  These videos unfortunately got pushed to the back of the line.  I debated whether or not I should still post them but decided even though they aren't that up-to-date anymore, they are still worth a view.  For any of you that love a good travel story or wonder what it would be like to travel from London to Mongolia in a less than perfect car and under adventurous circumstances, check these videos out and consider signing yourself up for Mongol Rally 2008 or 2009!

ReSharper 4.0 Beta ist verfügbar

24.05.2008 13:40:00 | Ozgur Aytekin

JetBrains hat die ReSharper 4.0 Beta Version veröffentlicht und steht für den Download bereit.

ReSharper ist ein Visual Studio Add-In und unterstützt die Entwickler in den Bereichen Code-Analyse, Code-Refactoring, Intellisense und Software-Testing.

In dieser Version unterstüzt ReSharper auch die C# 3.0 Features und LINQ.

Gemäss JetBrains Homepage sind folgende Features in der Version 4.0 Beta vorhanden:

  • Full Support for C# 3.0 and LINQ
    • ReSharper 4 Full Edition and C# Edition provide comprehensive support for C# 3.0, including LINQ, implicitly typed locals and arrays, extension methods, automatic properties, lambda expressions, object & collection initializers, anonymous types, expression trees, and partial methods.
  • Comprehensive Insight into .NET Framework
    • We have analyzed a great share of .NET Framework Class Library, as well as NUnit Framework, and annotated it through external XML files, using a set of custom attributes from the JetBrains.Annotations namespace.
  • Solution-Wide Analysis
    • ReSharper 4.0 provides a full-fledged feature called Solution-Wide Analysis, which looks for erroneous C# code in your whole solution on-the-fly, without compiling it first.
  • Code Cleanup
    • A new, extended reincarnation of what was previously known as Reformat Code. You can now save a myriad of "go-to-next-highlight-then-apply-a-quick-fix" iterations by simply running Code Cleanup!
  • New Refactorings
    • In line with the major message of the current release, all refactorings support C# 3.0. New members of the refactoring family are available, including a pack of C# 3.0-specific refactorings. Plus, we have a surprise for VB.NET aficionados: all refactorings that were previously limited to C# 2.0 are now available for Visual Basic 8.
  • ASP.NET Speedup
    • ReSharper 4.0 significantly speeds up analysis of ASP.NET pages, to enable more web developers benefit from the great toolset that ReSharper provides.

Die URL für den Download: ReSharper 4.0 Beta

Detail Informationen findet ihr unter: What's New in ReSharper 4.0 Beta

Sonntag 2.0, Girl Geek Dinners und TechTalks

23.05.2008 15:43:00 | Lori Grosland

Sonntag 2.0 Am Sonntag den 25. Mai bin ich auf Sonntag 2.0 in München.  Sonntag 2.0 ist unser erstes Mini- Barcamp zum Thema: Web 2.0 und Sicherheits-Aspekte.  Veranstaltungs-Ort ist das NH Hotel München-Dornach (Einsteinring 20, D-85609 Aschheim-Dornach). Mehr Informationen und kostenfreie Anmeldung unter: http://sonntag.mixxt.de/

 

Nächste Woche findet die Webinale in Karlsruhe statt.  Ich bin dabei, um Popfly und Photosynth zu promoten. 

Girl Geek DinnerAm Vorabend von der Webinale (25. Mai) findet ein Girl Geek Dinner statt.  Ein zweites Girl Geek Dinner findet im München am 4. Juni statt.  Ich bin auf beide Veranstaltungen dabei. 

Girl Geek Dinners sind international bereits etabliert, in Deutschland noch neu. Das Konzept basiert auf den London Girl Geek Dinners von Sarah Blow. Ein Girl Geek ist per Definition „eine weibliche Person mit Interesse an Technologie, insbesondere an Computern und Neuen Medien. Allerdings nicht zwangsläufig aus strikt technischer Perspektive, sondern die auch vor allem Technologie als Hilfsmittel sehen und keine Angst davor haben.“  Ein Girl Geek Dinner (GGD) ist ein Event bei dem diese Frauen die Chance haben sich auszutauschen, voneinander zu lernen und Frauen kennen zu lernen, die es in der IT „geschafft“ haben. Girl Geek Dinner sind nicht zwangsläufig „100% Frauen, keine Männer!“-Events, sondern Events an denen Frauen auf Augenhöhe teilnehmen und mindestens 50% der Teilnehmer stellen: Männer sind herzlich eingeladen, aber nur wenn sie von einer Frau mitgebracht werden.  Mehr Info findest Du dazu auf der Webseite: http://girlgeekdinner.de/

 

TECHTALKS

Am Anfang Juni machen mein Kollege Dirk Primbs und ich TechTalks in sechs deutsche Städten zum Thema „Technologieperlen unter der Haube.“  Wir stellen Tools und Technologien wie Deep Zoom, die Live APIs sowie das ein oder andere Research-Projekt vor. Weitere Infos und Anmeldemöglichkeiten gibt es in der Event-Rubrik auf MSDN. Die Teilnahme ist kostenlos. 

Termine und Städte

02.06.2008, Karlsruhe
03.06.2008, Köln
05.06.2008, Berlin
10.06.2008, München
11.06.2008, Hamburg

GirlGeek - Dinner

23.05.2008 12:11:49 | Oliver Scheer

Girl Geek Dinner sind international bereits etabliert, in Deutschland noch neu. Das Konzept basiert auf den London Girl Geek Dinners von Sarah Blow. Ein Girl Geek ist per Definition „eine weibliche Person mit Interesse an Technologie, insbesondere an Computern und Neuen Medien. Allerdings nicht zwangsläufig aus strikt technischer Perspektive, sondern die auch vor allem Technologie als Hilfsmittel sehen und keine Angst davor haben.“  Ein Girl Geek Dinner (GGD) ist ein Event bei dem diese Frauen die Chance haben sich auszutauschen, voneinander zu lernen und Frauen kennen zu lernen, die es in der IT „geschafft“ haben. Girl Geek Dinner sind nicht zwangsläufig „100% Frauen, keine Männer!“-Events, sondern Events an denen Frauen auf Augenhöhe teilnehmen und mindestens 50% der Teilnehmer stellen: Männer sind herzlich eingeladen, aber nur wenn sie von einer Frau mitgebracht werden.  Mehr Info findest Du dazu auf der Webseite: http://girlgeekdinner.de/

Girl Geek Dinner in Karlsruhe am 26.05:

Location - BarRestaurant Coppa Dos

Waldstraße 50

D-76133 Karlsruhe

http://www.coppados.de/

Anmeldung auf der Webseite…

http://girlgeekdinner.de/entry/12/girl_geek_dinner_karlsruhe_260

Girl Geek Dinner in München am 04.06:

Location - Restaurant nam nam

Amalienstraße 25

80333 München

http://www.nam-nam.eu/

Anmeldung auf der Webseite…

http://girlgeekdinner.de/entry/13/girl_geek_dinner_muenchen_0406

Microsoft Research mit erstem Release von Pex

23.05.2008 10:36:00 | Rainer Schuster

Das Pex Team hat diese Woche die erste frühe Version von Pex veröffentlicht. Pex ist eine neuartige Methode Unittests zu erstellen. Pex analysiert eine parametrisierte Testfunktion und erstellt dazu automatisch Eingabeparameter. Schlägt die Funktion fehl, gibt Pex einen Hinweis darauf, an welcher Stelle im Code der Fehler aufgetreten ist und kann unter Umständen einen Codefix für den Fehler vorschlagen. Meiner Meinung nach fast schon revolutionär. Ein gutes Tutorial, einen Webcast und die Dokumentation findet sich auf der Microsoft Research Seite von Pex. Die Version 0.5 ist unter der Microsoft Research License freigegeben. Auf Codeplex gibt es seit gestern dazu eine Community Seite mit dem Namen Pex Extensions. Ich bin schon gespannt, wie sich Pex anfühlt und werde sobald ich es austesten konnte einen ganz kleinen Testbericht dazu abgeben. Dazu werde ich es mit Visual Studio 2008 (keine Unterstützung für 2005 - hier werde ich mich mal erkundigen ob sich das in Zukunft ändert) und mit Gallio - einem neuen Testframework - testen.


EDIT: Wie ich soeben von Peli erfahren habe wird es das Add-In nur für das VS2008 geben. Benutzt werden kann Pex natürlich auch mit dem VS2005. Allerdings muss die eigentliche Funktion, nähmlich das Generieren von parametrisierten Testfunktionen, per Kommandozeile aufgerufen werden. Das heißt also, wer den Komfort und die integrierte Funktion nutzen will muss auf VS2008 umsteigen.


HowTo: Einfache Tests - UnitTests (oder keine Angst vor UnitTests…)

22.05.2008 23:33:03 | Robert Mühsig

Einführung

Das Konzept der UnitTests (es gibt noch ein paar weitere Formen) ist bereits seit etlichen Jahren (oder Jahrzehnten?) bekannt. Es gibt viele Testframeworks für fast jede Sprache.
Im Visual Studio 2008 (jedenfalls der Professional/Team System Edition) sind UnitTests sehr einfach zu erstellen - und trotzdem hab ich erst vor kurzem die UnitTests für mich entdeckt. Trotz der Gründe für UnitTests und der Einfachheit kenn ich etliche Projekte, wo diese nicht existieren oder angewendet werden.
Die meisten Entwickler denken, dass UnitTests ziemlich komplex sind und eigentlich unnötig.
Die Gründe der Entwickler sind vielfältig (auch ich hab früher so oder so ähnlich gedacht ;) ) :

  • “Warum nicht einfach ein Konsolenprogramm erstellen oder per Debugger prüfen?”
  • “Ich seh es doch wenn eine bestimmte Komponente nicht funktioniert.”
  • “Für den extra Aufwand hab ich leider keine Zeit.”
  • “UnitTests klingt doch recht kompliziert, da ist mir die Einarbeitungszeit zu hoch.”

Ich bin kein Experte in UnitTests, allerdings haben sie mich bereits nach wenigen Minuten begeistert :)

UnitTests sind sehr schnell gemacht

(Achtung: Diese Aussage nicht auf die Goldwaage legen. Gute und durchdachte UnitTests sind keine leichte Aufgabe - darum gibt es ja z.B. auch eine extra Test Edition von Visual Studio wo sich)
Aber für den Anfang wollen wir die Behauptung mal so stehen lassen - Einfache Tests können sehr schnell durchgeführt werden)

Im Visual Studio 2008 wurde ein extra Template für Tests bereitgestellt:

image

Zudem kann man direkt in einem Projekt per Kontextmenü auf eine Klasse/Methode ein UnitTest erstellen:

image

Aber erst mal zur Grundfrage:

Warum sollte ich Tests machen?

Jeder Entwickler will (hoffentlich) gute und funktionstüchtige Software schreiben, die möglichst fehlerfrei ihren Dienst tut.
In der Zeit wo die Software entwickelt wird, werden sicherlich an vielen Ecken (oder Software-Schichten) Änderungen eingepflegt oder die Applikation muss erweitert werden. Insbesondere in einem Team oder wenn eine größere Umstellung ansteht (Datenbasis wechselt, Logik muss abgeändert werden) wird es kritisch: Laufen alle Komponenten noch wie erhofft?
Je größer die Anwendung, desto größer wird der Aufwand der Betrieben muss, um sicherzustellen, dass alles noch läuft.
Ein Test im UserInterface ist zwar machbar, ist allerdings meist sehr anstrengend und zeit intensiv (sollte natürlich auch gemacht werden).
Es wäre doch viel schöner, wenn die Tests automatisch erfolgen könnten - ohne viel Zeit mit Klicken zu verlieren - auch das die Tests jederzeit ausgeführt werden können wäre doch nett, oder?
Hier kommen die UnitTests: Genau sowas machen UnitTests (und noch mehr ;) ).

Stellen wir uns mal vor…

… dass wir eine nicht ganz triviale Software haben, welche verschiedene Layer (Data/Business etc.) hat. Die Software funktioniert gut - der Kunde ist zufrieden und als Entwickler fühlt man sich wohl.
Wie es meistens ist: Der Kunde möchte eine Änderung. Ein neues Attribut soll hier und da angefügt werden, eine Abfragelogik verändert werden und die Validation der Daten soll anders verlaufen.
Das Problem: Die Änderungen können viele Bereiche betreffen, sodass es leicht passieren kann, dass plötzlich garnichts mehr geht. Aber wo genau hakt es denn? Erstmal überall den Debugger ansetzen und nachverfolgen… hoffentlich übersicht man kein Fehler.
Ergebnis: An dieser Stelle ist es meist für den Entwickler ein etwas mulmiges Gefühl - wird die Software noch genauso funktionieren wie vorher (natürlich mit den Änderungen)?

… nun mal mit Tests vorstellen (ein Gedankenspiel) :

Die verschiedenen Methoden wurden während der Entwicklung der Version 1 bereits mit UnitTests getestet. Daten eintragen, löschen, verändern, laden, validieren, Fehler abfangen usw. - alle Aspekte die wichtig sind, wurden als Test hinterlegt.
Nun kommen die Änderungen: Es werden einige kritische Bereiche verändert, aber nach jeder Veränderung kann man automatisch alle Tests abspielen - schlägt der Test fehl, weiß man, wo Handlungsbedarf besteht. Die eben gemachte Änderung war wohl anscheinend nicht so gut.
Nach einer ganzen Weile: Die Tests werden wieder bestanden - das Herz des Entwicklers schlägt höher. Es können zwar immer noch Fehler auftreten (vielleicht muss ein neuer Test für einen neuen Aspekt noch hinzugefügt werden), aber die Grundzüge der Applikation stimmen noch.

Klingt doch eigentlich gut, aber wie sieht das in der Praxis aus:

Ein sehr (zugegeben) doofes Beispiel:

    public class DataManager
    {
        public bool ConnectToData()
        {
            return true;
        }

        public List<int> GetData()
        {
            return new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
        }
    }

Unser DataManager kann sich zu einer beliebigen Datenquelle verbinden - in unserem Fall sagen wir einfach mal, dass die Verbindung geklappt hat.
Die GetData Methode gibt Daten zurück - in unserem Beispiel ein paar statische Daten.

Da sich die Datenabfrage-Logik ja ändern könnte und da auch die Datenquelle vielleicht sich noch ändert, implementieren wir lieber einen Test dafür:

Create Unit Test…

image 
Methoden auswählen, welche man testen möchte (beide in unserem Fall)…

image 
Name eingeben…

image 

Ein TestProjekt ist entstanden:

image

Generierter Test (dort steht eigentlich bereits das wichtigste drin) :

Visual Studio nutzt MSTest - das Test-Framework von Microsoft. Es ist ähnlich zu nUnit und co.

using DoNot.Fear.UnitTests.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;

namespace DoNot.Fear.UnitTests.Test
{

    /// <summary>
    ///This is a test class for DataManagerTest and is intended
    ///to contain all DataManagerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DataManagerTest
    {

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        /// <summary>
        ///A test for GetData
        ///</summary>
        [TestMethod()]
        public void GetDataTest()
        {
            DataManager target = new DataManager(); // TODO: Initialize to an appropriate value
            List<int> expected = null; // TODO: Initialize to an appropriate value
            List<int> actual;
            actual = target.GetData();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for ConnectToData
        ///</summary>
        [TestMethod()]
        public void ConnectToDataTest()
        {
            DataManager target = new DataManager(); // TODO: Initialize to an appropriate value
            bool expected = false; // TODO: Initialize to an appropriate value
            bool actual;
            actual = target.ConnectToData();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
    }
}

Die Kommentare und auch den TestContext kann man löschen - ich hab ihn bisher nicht gebraucht ;)
Achtung: Ich bin kein Experte in den Unit Tests - sondern ist nur eine Art Erfahrungsbericht :)

Machen wir doch erstmal einen einfachen Test ob die Verbindung klappt:

        [TestMethod()]
        public void DataManager_ConnectToData_IsTrue()
        {
            DataManager man = new DataManager();
            Assert.IsTrue(man.ConnectToData());
        }

Sehr schlicht, aber genau das was ich wissen muss. Der Name des Tests sollte ungefähr das beschreiben was er macht - damit man sich später noch zurechtfindet. In diesem Fall prüfe ich einfach, ob die Verbindung zustande kommt.
Die Assert-Klasse hat mehrere Methoden:

image

Jetzt können wir diesen Test durchlaufen und sehen:

image

Jetzt prüfen wir noch die andere Methode:

        [TestMethod()]
        public void DataManager_GetData_IsNotNull()
        {
            DataManager man = new DataManager();
            Assert.IsNotNull(man.GetData());
        }

        [TestMethod()]
        public void DataManager_GetData_CheckForZero()
        {
            DataManager man = new DataManager();
            List<int> result = man.GetData();
            foreach (int number in result)
            {
                Assert.AreNotEqual(0, number);
            }
        }

Die erste Methode prüft, ob überhaupt Werte zurückkommen. Mit dem zweiten Test wollte ich nur mal eine primitive Business-Logik Test machen (”kein Element darf 0 sein”).

Jetzt kann man alle Abspielen:

image

Ergebnis:

image

Schön, oder? :)

Ein Gedankenspiel:

Angenommen in unseren Daten schleicht sich tatsächlich eine 0 ein (Datenabfrage könnte zum Beispiel falsch sein oder es wurden falsche Daten eingetragen), dann schauen wir mal was passiert:

image

Ergebnis:

image

Fail!

image

Idealerweise sollten Tests möglich häufig (sie können sogar automatisch nach jedem Build laufen!) machen - um die Fehlerquelle einzugrenzen.
Angenommen wir haben bei uns einen Fehler in der Abfragelogik oder die Methode (die bei uns nicht existiert, aber existieren könnte) die Daten schreibt, war fehlerhaft oder die Validation fehlgeschlagen ist… (es kann ja viele Quelle geben).

Wir beheben also diesen Fehler (den wir vielleicht sonst nur sehr schlecht gefunden hätten), bis wir wieder das sehen:

image

Resultat beim Entwickler (& beim zufriedenen Kunden) :

image

Der Testcode:

[TestMethod()]
        public void DataManager_ConnectToData_IsTrue()
        {
            DataManager man = new DataManager();
            Assert.IsTrue(man.ConnectToData());
        }

        [TestMethod()]
        public void DataManager_GetData_IsNotNull()
        {
            DataManager man = new DataManager();
            Assert.IsNotNull(man.GetData());
        }

        [TestMethod()]
        public void DataManager_GetData_CheckForZero()
        {
            DataManager man = new DataManager();
            List<int> result = man.GetData();
            foreach (int number in result)
            {
                Assert.AreNotEqual(0, number);
            }
        }


Ergebnis:

Die Vorteile von UnitTests werden sicherlich erst nach und nach bei einem Projekt sichtbar, aber wenn man dies stetig fortführt, reduziert sich die Fehleranfälligkeit erheblich.
Das was ich hier gezeigt habe, ist sicherlich nicht das Ende der Fahnenstange - es gibt neben Unit Tests auch noch andere Tests. Das ist auf der MSDN Testing Seite recht gut beschrieben.

Test Driven Development (TDD) :

TDD beschreibt ein Entwicklungsstil, wo auf Tests besonders viel Wert gelegt wird. Hier werden die Tests immer vor der eigentlichen Implementation geschrieben. Man trifft seine Annahmen und da die Methode (oder die zu testende Komponente) ja noch keine Logik enthält, wird der Test erst fehlschlagen.
Nun geht es darum, den Test erfolgreich zu bestehen. Sobald dies geschafft ist, kann man die Implementation hinterher nochmal überarbeiten. (Refactoring). Nun kann man immer wieder prüfen, ob der Test noch funktioniert oder nicht - wenn er nicht mehr stimmt, dann haben wir wohl was falsch gemacht.
Am Ende haben wir (in der Theorie) jede Methode / Komponente mit Tests ausgestattet.

Unit Tests in ASP.NET MVC, Silverlight & co.:

Eine Klassenbibliothek lässt sich relativ leicht testen. In ASP.NET (WebForms) ist dies allerdings nicht ganz so leicht. In ASP.NET MVC wurde darauf ein besonderer Augenmerk gelegt.
Auch in Silverlight 2 wurde das Thema angegangen.

Weitere Links:

Wer nun etwas neugierig geworden ist, der kann sich auch diese Links anschauen:

Download:

Sample Code

fmx - XNA und Serious Games

22.05.2008 19:16:00 | Lori Grosland

In zahlreichen Sessions auf der fmx erläuterten Microsoft-Sprecher aus Deutschland und den USA wichtige Technologien, wie beispielsweise den Einsatz von XNA Studio zur Spieleentwicklung unter Windows und auf der Xbox.  Vor Ort habe ich mit Dirk Primbs, Microsoft Developer Evangelist, über fmx und XNA gesprochen.  Auch dabei auf dem Microsoft-Stand war Kreativpartner Pixelpark Agentur.  Sie habe ein Showcase zum Thema „Xbox Business Applications“, ein Szenario, bei dem die Xbox-Konsole für Simulationen und E-Learning-Applikationen („Edutainment“) präsentiert.  Ich habe mit Dirk Krause von Pixelpark darüber geredet.

Die Fusion entmystifiziert - Teil 2

22.05.2008 17:55:48 | Klaus Bock

Um die vorhandenen Assemblies im GAC abzufragen gibt es viele Möglichkeiten. Eine, basierend auf dem Abfragen der Registrierung, habe ich in diesem Beitrag auf .NET Snippets.de gefunden. Die mit Sicherheit am häufigsten verwendete Methode dürfte jedoch die Abfrage mit gacutil.exe aus dem SDK sein. Falls jetzt noch die Information benötigt wird, ob ein natives Image einer Assembly vorhanden ist, wird in der Regel der Native Image Compiler ngen.exe verwendet, da gacutil.exe diese Möglichkeit nicht bietet. Unter Verwendung der Fusion-API ist dieses Problem jedoch relativ einfach zu lösen. Hier zum Vergleich die Ausgabe von gacutil.exe und einer Anwendung welche die Fusion-API verwendet. Es wird die Assembly System abgefragt.

gacutil query

Das Tool gacutil.exe gibt richtig die beiden, im GAC installierten, Versionen 2.0.0.0 und 1.0.5000.0 aus. Ob jedoch eines dieser Assemblies als natives Image vorliegt ist so nicht zu erfahren.

 

 

GAC AdminDas Tool GacAdminCmd.exe gibt wie gacutil.exe die beiden Versionen im GAC aus und zusätzlich die gefundene Version 2.0.0.0 aus dem ZAP (Native Images Cache). Die Assembly im ZAP wurde ohne Zuhilfenahme der ngen.exe ermittelt. Um zu erfahren wie, ist eine nähere Betrachtung der statischen Methode CreateAssemblyEnum der Fusion-API notwendig. Der vierte Parameter erwartet ein DWORD, welches ein Flag aus der ASM_CACHE_FLAGS-Enumeration darstellt. Wenn der Wert ASM_CACHE_ZAP, aus der Aufzählung, an den Parameter dwFlags der CreateAssemblyEnum-Methode übergeben wird, sucht die Methode im Native Images Cache nach der Assembly. Wie bereits eingangs erwähnt: relativ einfach.

Die Methode, welche die Assemblies ermittelt und auf den Bildschirm bringt, ist sehr einfach gehalten wie man hier sehen kann.

private static void listAssemblies(string assemblyName, bool listZap)
{
    int i = 0;
    string asm = null;

    Console.WriteLine();

    // Suche nach den Assemblies im GAC
    // wenn assemblyName ein NULL-Verweis ist, werden alle Assemblies
    // im GAC aufgelistet
    AssemblyCacheEnum acEnum = new AssemblyCacheEnum(
									assemblyName,
									AssemblyCacheLocation.Gac);
    
	while ((asm = acEnum.NextAssembly) != null)
    {
        Console.WriteLine("  " + asm);
        i++;
    }
    Console.WriteLine();
    Console.WriteLine(string.Format(
		CultureInfo.CurrentCulture,
        Resources.AsmCountInGacMsg,
		i));

    // Suche nach den Assemblies im ZAP
    if (listZap)
    {
        Console.WriteLine();
        Console.WriteLine();
        i = 0;

        // wenn assemblyName ein NULL-Verweis ist, werden alle Assemblies
        // im ZAP aufgelistet
        acEnum = new AssemblyCacheEnum(
			assemblyName,
			AssemblyCacheLocation.Zap);
        
		while ((asm = acEnum.NextAssembly) != null)
        {
            Console.WriteLine("  " + asm);
            i++;
        }

        Console.WriteLine();
        Console.WriteLine(string.Format(
			CultureInfo.CurrentCulture,
            Resources.AsmCountInZapMsg,
			i));
    }
}

Zunächst wird ein Instanz der AssemblyCacheEnum-Klasse erzeugt und der Name der Assembly sowie der Ort an dem gesucht werden soll im Konstruktor  übergeben. In einer Schleife werden dann die zurückgelieferten Namen auf dem Bildschirm ausgegeben sowie die Anzahl der gefundenen Assemblies mittels der Laufvariablen i ermittelt und ebenfalls ausgegeben.

Da die Implementierung der Fusion-API sehr umfangreich ist, beschränke ich mit hier auf die relevanten Code-Passagen.

Zunächst die bereits erwähnte statische Methode CreateAssemblyEnum

[DllImport("fusion.dll")]
internal static extern int CreateAssemblyEnum(
        out IAssemblyEnum ppEnum,
        IntPtr pUnkReserved,
        IAssemblyName pName,
        AssemblyCacheLocation flags,
        IntPtr pvReserved);

sowie die ebenfalls benötigte Methode CreateAssemblyNameObject. Sie wird benötigt um einen Zeiger auf ein IAssemblyName-Objekt zu erhalten. Hier muss darauf geachtet werden, dass der Parameter szAssemblyName, also der Name der gesuchten Assembly, in eine Unicode-Zeichenfolge gemarshallt wird.

[DllImport("fusion.dll")]
internal static extern int CreateAssemblyNameObject(
        out IAssemblyName ppAssemblyNameObj,
        [MarshalAs(UnmanagedType.LPWStr)]
        string szAssemblyName,
        CreateAssemblyNameObjectFlags flags,
        IntPtr pvReserved);

Zu den Schnittstellen IAssemblyName und IAssemblyEnum ist nicht weiter viel zu sagen. Der Vollständigkeit halber hier die relevanten Passagen.

IAssemblyName:

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("CD193BC0-B4BC-11d2-9833-00C04FC31D2E")]
internal interface IAssemblyName
{
    [PreserveSig()]
    int GetDisplayName(
    StringBuilder pDisplayName,
    ref int pccDisplayName,
    int displayFlags);
}

IAssemblyEnum:

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("21b8916c-f28e-11d2-a473-00c04f8ef448")]
internal interface IAssemblyEnum
{
    [PreserveSig()]
    int GetNextAssembly(
        IntPtr pvReserved,
        out IAssemblyName ppName,
        int dwFlags);
}

Da die aus dem ersten Listing, in der Methode listAssemblies verwendete, Klasse AssemblyCacheEnum sehr umfangreich ist zeige ich hier nur zwei Klassen-Member, den Konstruktor und zwei benötigte private Methode.

public sealed class AssemblyCacheEnum : IDisposable
{
    #region Class Members

    private IAssemblyEnum assemblyEnum = null;

    private IAssemblyName fusionName = null;

    #endregion

    public AssemblyCacheEnum(
			string assemblyName,
			AssemblyCacheLocation location)
    {
        // HRESULT erzeugen
        int hr = 0;

        if (assemblyName != null)
        {
            hr = NativeMethods.CreateAssemblyNameObject(
                out fusionName,
                assemblyName,
                CreateAssemblyNameObjectFlags.ParseDisplayName,
                IntPtr.Zero);
        }

        if (hr >= 0)
        {
            hr = NativeMethods.CreateAssemblyEnum(
                out assemblyEnum,
                IntPtr.Zero,
                fusionName,
                location,
                IntPtr.Zero);
        }

        if (hr < 0)
        {
            Marshal.ThrowExceptionForHR(hr);
        }
    }

    [SecurityPermission(
	 SecurityAction.LinkDemand,
	 UnmanagedCode = true)]
    private string getNextAssembly()
    {
        int hr = 0;

        // eine Instanz der IAssemblyName-Schnittstelle erzeugen.
        fusionName = null;

        // prüfen ob das Ende der Aufzählung bereits erreicht wurde
        if (done)
        {
            return null;
        }

        // jetzt das nächste IAssemblyName-Objekt
		// von assemblyEnum holen
        hr = assemblyEnum.GetNextAssembly(
							(IntPtr)0,
							out fusionName,
							0);

        if (hr < 0)
        {
            Marshal.ThrowExceptionForHR(hr);
        }

        // prüfen ob fusionName einen Wert hält
        if (fusionName != null)
        {
            // TODO: Fehlerbehandlung einbauen
            return getFullName(fusionName);
        }
        else
        {
            // keine Assembly mehr gefunden.
            done = true;
            return null;
        }
    }

    [SecurityPermission(
	 SecurityAction.LinkDemand,
	 UnmanagedCode = true)]
    private static string getFullName(IAssemblyName fusionAsmName)
    {
        int iLen = 1024;
        StringBuilder sDisplayName = new StringBuilder(iLen);

        int hr = fusionAsmName.GetDisplayName(
								sDisplayName,
								ref iLen,
								(int)AssemblyNameDisplayFlags.All);

        if (hr < 0)
        {
            Marshal.ThrowExceptionForHR(hr);
        }

        return sDisplayName.ToString();
    }
}

Manch einem mag die Implementierung der Fusion-API sehr aufwendig erscheinen. Wenn sie für nur eine Anwendung gesehen wird, gebe ich ihm recht. Doch einmal als Bibliothek erstellt, ist sie für jedes zukünftige Projekt verfügbar oder kann auch weiter gegeben werden. Unter diesem Aspekt halte ich den Aufwand für gerechtfertigt.

Technorati-Tags: | | |

Reflector Version 5.1.2.0 verfügbar

22.05.2008 13:21:00 | Klaus Bock

Seit Anfang Mai ist die aktualisierte Version 5.1.2.0 des .NET Reflector von Lutz Roeder verfügbar. Die Reflector Add-Ins, auf CodePlex gehostet, haben auch einige Neuerungen erfahren.

Wer öfter mal Com-Bibliotheken verwendet, sollte sich unbedingt das ComLoader Add-In genauer ansehen. Damit ist es möglich eine Com-Bibliothek auszuwählen und aus dieser eine verwaltete Com-Interop Assembly erstellen zu lassen. Bei der Auswahl der Com-Bibliothek können gleich verschiedene Optionen, wie etwa der zu verwendende Namensraum, eine SNK-Datei für den Public Key oder die Assembly Version, mit gegeben werden. Wie mit den importierten Schnittstellen umgegangen werden soll kann hier ebenso eingestellt werden, wie der Umgang mit Array's.

 

Technorati-Tags: | |

Online Vortrag am 27. Mai 2008 zum Thema ReSharper

21.05.2008 13:05:19 | Albert Weinert

Ich werde am Dienstag den 27. Mai 2008 einen Online Vortrag zum Thema ReSharper 4.0 machen. Dies geschieht im Rahmen der .net user group Köln Online Usertreffen. Es wird also das erste reine Online "treffen". Mal schauen was dabei rumkommt.

Der Vortrag wird über Office Live Meeting 2007 gehalten. Den kostenlosen Client kann man herunterladen. Eine Test nach der Installation ist unter folgender Seite möglich. http://esd.placeware.com/lm2007test/

ReSharper 4.0

Geplant sind folgende Themenbereiche die ReSharper beherrscht.

  • Quelltext Navigation
  • Refactoring
  • Quelltext Erzeugung
  • Quelltext Analyse
  • Unit Testing
  • LIve Templates

ReSharper ist ein sehr mächtiges Tool, welches jedoch Erklärung bedarf um den Einstieg zu erleichtern. Dies versuche ich mit dem Vortrag zu erreichen. Sicherlich wird auch der eine oder anderen ReSharper Anwender auch noch was neues Kennenlernen, wie ich auch ständig auf's neue Überrascht bin was ReSharper noch kann.

Ab 18:30 Uhr könnt Ihr euch hier anmelden. Es besteht die Möglichkeit des Sprachchats.

Eingeladen sind natürlich alle interessierte, nicht nur Mitglieder der .net user group Köln.

Ausgabe eines GridViews verändern - DataBound und RowDataBound Events

19.05.2008 23:05:00 | Peter Bucher

Vielfach kam in den Communities die Frage auf, wie es sich denn die Anzeige des GridViews verändern lässt.
Als Antwort kommt "RowDataBound Event".

Genau auf diesen Event will ich hier eingehen und anhand eines Beispiels zeigen, wie dieser Event benutzt werden kann.

Zitat aus "Hinweise":

Bevor das GridView-Steuerelement gerendert werden kann, muss jede Zeile im Steuerelement an einen Datensatz in der Datenquelle gebunden werden. Das RowDataBound-Ereignis wird ausgelöst, wenn eine Datenzeile (dargestellt durch ein GridViewRow-Objekt) an Daten im GridView-Steuerelement gebunden wird. Dadurch können Sie eine Ereignisbehandlungsmethode bereitstellen, die bei jedem Auftreten dieses Ereignisses eine benutzerdefinierte Routine ausführt, beispielsweise das Ändern der Werte der an die Zeilen gebundenen Daten.

 

und es steht weiter...

Ein GridViewRowEventArgs-Objekt wird an die Ereignisbehandlungsmethode übergeben, wodurch Sie auf die Eigenschaften der gebundenen Zeile zugreifen können. Wenn Sie auf eine bestimmte Zelle in der Zeile zugreifen möchten, verwenden Sie die Cells-Eigenschaft des GridViewRow-Objekts, das in der Row-Eigenschaft des GridViewRowEventArgs-Steuerelements enthalten ist. Sie können außerdem bestimmen, welcher Zeilentyp (Headerzeile, Datenzeile usw.) gebunden wird, indem Sie die RowType-Eigenschaft verwenden.

Das heisst, mit dem Event "RowDataBound" der GridView Klasse, ist es möglich, jede Zeile direkt nach der Datenbindung zu modifizieren.

Methoden die das Ereignis abonnieren, müssen einer festgelegten Signatur entsprechen.
Visual Studio macht das im Normalfall selber per Tastenkombination für uns.

 

Folgende, die benötigte Signatur:

void grdTest_RowDataBound(object sender, GridViewRowEventArgs e)

 

Eine Methode kann bspw. so aussehen:



/// <summary>
/// Formatiert die Tabelle ansehlich
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void grdTest_RowDataBoundAllgemein(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.DataRow) {
        string text = e.Row.Cells[2].Text;
        e.Row.Cells[2].Text = Tools.WordWrap(text, 25) + "...";
        e.Row.Cells[2].CssClass = "fixedWidth";
    }
}

GridViewDataBoundEvents

Diese macht nichts weiter, als für alle Zeilen die dem DataControlRowType.DataRow entsprechen, denn Text zu kürzen und der dritten Zelle von Links eine CSS Klasse hinzuzufügen, damit sie eine fixe Breite einnimmt.

 

Zum Download findet ihr eine Beispielanwendung, diese enthält ein GridView das mit Zufallsdaten gefüllt wird.
Mit vier Behandlungsmethoden für DataBound und RowDataBound enthält und die Tabelle in der Ausgabe modifiziert.
Mithilfe des Suchfilters können Textdaten aus dem Feld "Text" hervorgehoben werden, die dem Suchwort entsprechen.

Mit dem Priority-Farbe Link können die Farben für die Priority Spalte hervorgehoben werden
Mithilfe des Priority-Summe Links wird in der FooterRow (Fuss-Zeile) jeweils eine Summe aller Priorities dargestellt.
Im nächsten Abschnitt findet ihr den benötigten ASPX Code, den ich der Übersichtshalber ein bisschen beschnitten habe:

 

 

 



<form id="aspnetform" defaultbutton="btnSubmit" runat="server">
    <h1>GridViewDataBoundEvents</h1>
    <asp:Label ID="lblSearch" AssociatedControlID="txtSearch" Text="Suche in Text" runat="server" />
    <asp:TextBox ID="txtSearch" runat="server" />
    <asp:Button ID="btnSubmit" Text="Finden" runat="server" />
    <br />
    <br />
    <a id="search" href="?mode=search" runat="server">Suchfilter</a>
    <a id="color" href="?mode=color" runat="server">Priority-Farbe</a>
    <a id="sum" href="?mode=sum" runat="server">Priority-Summe</a>
    <br />
    <br />
    <asp:GridView ID="grdTest" GridLines="None" runat="server" />
</form>

Es steht ein Suchformular zur Verfügung, das aktiv wird, wenn der Suchfilter aktiviert wird.
Die kleine Navigation mit den normalen Links soll euch zeigen, wie verschiedene RowDataBound Ereignishandler je nach Auswahl abonniert werden können.

Im Page_Load der Beispielseite werden die Daten aus einer Zufallsquelle geladen, die Filter je nach Auswahl zugewiesen und dem aktiven Link eine CSS Klasse hinzugefügt.
Zudem werden die Daten beim ersten Laden der Seite gebunden und ein Klick Event des Suchen Buttons registriert.



protected void Page_Load(object sender, EventArgs e) {
    // Daten besorgen
    List<Task> data                  = new RandomData(10).RandomList;
    this.grdTest.DataSource      = data;

    // Filter Mode auswählen
    string mode = this.Request.QueryString["mode"];
    if (string.IsNullOrEmpty(mode)) {
        mode = String.Empty;
    }

    // Allgemeine Formatierungen anwenden
    this.grdTest.RowDataBound += this.grdTest_RowDataBoundAllgemein;

    switch (mode) {
        case "sum":
            // Summe anzeigen
            this.grdTest.DataBound += grdTest_DataBound;
            this.sum.Attributes.Add("class", "active");
            break;
        case"color":
            // Farben zu den Priority Zahlen anzeigen
            this.grdTest.RowDataBound += this.grdTest_RowDataBoundPriorityBackColor;
            this.color.Attributes.Add("class", "active");
            break;
        case "search":
            // Suchwörter bzw. dessen Zeilen hervorheben
            this.grdTest.RowDataBound += this.grdTest_RowDataBoundTextSearch;
            this.search.Attributes.Add("class", "active");
            break;
        default:
            break;
    }

    // Button.Click Eventhandler anmelden
    this.btnSubmit.Click += this.btnSubmit_Click;

    // Daten beim ersten Seitenaufruf binden
    if (!this.IsPostBack) {
        this.grdTest.DataBind();
    }
}

 

Diese Routine hebt Texte hervor, die ein Treffer in der Suche haben



/// <summary>
/// Erhellt die Zeilen, bei denen ein der gesuchte Begriff von "txtSearch" vorkommt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void grdTest_RowDataBoundTextSearch(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.DataRow) {
        string text = e.Row.Cells[2].Text;
        if ((!string.IsNullOrEmpty(this.txtSearch.Text))
            && text.IndexOf(this.txtSearch.Text) > -1) {
            e.Row.Cells[2].ForeColor = Color.Red;
        }
    }
}

 

Diese Methode vergibt Farben, je nach dem was für Werte das Feld "Priority" enthält.
Hier wird direkt über die DataBinder.Eval() Methode gearbeitet. Das ist genauer als über die jeweilige Zelle zu gehen.

Denn die Zelle, bzw. dessen Index kann sich ändern, ein Feldname nicht so häufig.



/// <summary>
/// Vergibt je nach Zahlenwertung eine Hintergrundfarbe für die aktuelle Zelle
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void grdTest_RowDataBoundPriorityBackColor(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.DataRow) {
        TableCell priortyCell = e.Row.Cells[3];

        switch(int.Parse(DataBinder.Eval(e.Row.DataItem, "Priority").ToString())) {
            case 0:
            case 1:
            case 2:
                priortyCell.BackColor = Color.Gray;
                break;
            case 3:
            case 4:
            case 5:
                priortyCell.BackColor = Color.Orange;
                break;
            case 6:
            case 7:
            case 8:
                priortyCell.BackColor = Color.OrangeRed;
                break;
            case 9:
            case 10:
                priortyCell.BackColor = Color.Red;
                break;
            default:
                break;
        }
    }
}

 

Und was passiert jetzt, wenn ich TemplateFields habe?

Wenn die Vorgaben nicht passend sind, ist ein TemplateField Mittel zum Zweck und dazu noch ein gutes!
In einem ItemTemplate eines TemplateFields können beliebige Controls platziert werden, bspw.:

Folgend der Code, des zweiten GridViews:



<asp:GridView ID="grdTest2" AutoGenerateColumns="false" GridLines="None" runat="server">
    <Columns>
        <asp:BoundField HeaderText="Id" DataField="Id" />
        <asp:BoundField HeaderText="Title" DataField="Title" />
        <asp:TemplateField HeaderText="Text">
            <ItemTemplate>
                <asp:Literal ID="litCountWords" runat="server" />
                Wörter und <asp:Literal ID="litCountWordsDisplayed" runat="server" />
                 werden angezeigt.
                 <asp:Panel ID="container" runat="server" style="border: 1px solid gray; padding: 4px; margin: 4px;">
                    <asp:Literal ID="litText" runat="server" />
                 </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Hierbei werden ein paar Controls platziert und eine eindeutige ID vergeben.
Da diese Templates MultipleTemplateInstances sind, werden die IDs automatisch einzigartig gehalten.
Nachteil dabei ist, das nur noch der indirekte Zugriff per <Control>.FindControl() möglich ist. Bei SingleInstence Templates ist der Zugriff direkt über die ID möglich.

Siehe: http://www.nikhilk.net/SingleInstanceTemplates.aspx

Durch eine relativ einfach Manipulation kann der Inhalt bereitgestellt werden:



/// <summary>
/// Wertet den Inhalt aus
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void grdTest2_RowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.DataRow) {
        e.Row.Cells[2].CssClass = "fixedWidth";

        Literal countWords = e.Row.FindControl("litCountWords") as Literal;
        Literal countWordsDisplayed = e.Row.FindControl("litCountWordsDisplayed") as Literal;

        Literal text = e.Row.FindControl("litText") as Literal;

        string content = DataBinder.Eval(e.Row.DataItem, "Text").ToString();
        text.Text = Tools.WordWrap(content, 25) + "...";

        countWords.Text = content.Split(' ').Length.ToString();
        countWordsDisplayed.Text = text.Text.Split(' ').Length.ToString();
    }
}

Die Beispielanwendung könnt ihr hier Downloaden:

Referenzen:

Wöchentliche Rundablage: Silverlight 2, ASP.NET MVC, C# 3.0, .NET 3.5 SP1…

19.05.2008 21:41:12 | Robert Mühsig

Silverlight 2:

ASP.NET MVC / ASP.NET:

Development:

.NET 3.5 SP1 / .NET / C# / Visual Studio:

Javascript:

Linktipp: Online JavaScript Obfuscator

19.05.2008 18:10:13 | Jan Welker

Eigentlich soll mein Blog keine Linksammlung werden, das folgende Tool hat mir aber so gut gefallen, dass ich es gern weiterempfehlen möchte.

Das JavaScript Utility ist nicht nur ein Obfuscator. Er kann außerdem:

  • JavaScript testen
  • JavaScript validieren
  • JavaScript Quellcode neu formatieren (wäre im Visual Studio auch sinnvoll gewesen)
  • JavaScript komprimieren
Was mir bei der Funktion JavaScript komprimieren gut gefallen hat, ist die Option „Add missing semicolon“. Die meisten JS  Obfuscatoren haben diese Option nicht. Das hat zur Folge, dass das JS hinterher nicht mehr läuft.

Hier nun der Link: http://jsutility.pjoneil.net/

Design-Guidlines

19.05.2008 14:11:38 | Rainer Schuster

Was bringen einem eigentlich Design-Guidlines, also Richtlinien für das Programmieren, Schreiben und Entwerfen von Sourcecode? Nun ganz einfach. Es trägt zur einfacheren Lesbarkeit der vorhandenen Quellen bei. Es sind Vorgaben, die dem Entwickler und Teammitgliedern helfen, den vorliegenden Code besser zu verstehen. Das war schon in Zeiten von Win32 und MFC so und das ist auch in Zeiten von C# so. Früher war Ungarische Notation "IN". Heute steht es auf der Liste der "DONT'S" und ist somit ein absolutes "NO GO". Wie komme ich dazu? ...

Nach einer kurzen und auch unterhaltsamen Diskussion über Codedesign vor ein paar Wochen hatte ich mich auf Google umgeschaut, was so von Microsoft kommt. Ich hatte mir schon einmal die Guidlines vor ca. 3 Jahren durchgelesen und wusste daher auch, dass es entsprechende Dokumente gibt. Auf Amazon findet sich z.B. dieses Buch hier in dem die Framework Design-Guides beschrieben sind. Diese kommen von Brad Abrams (hier sein blog). Er hat sie für das .NET Framework entwickelt. Von Microsoft gibt es diese Guidlines direkt in der MSDN. Wer immer auf dem neuesten Stand bleiben will, sollte von Zeit zu Zeit bei den Jungs von der Base Class Library (BCL) vorbei schauen.

Ob alles Gold ist, was glänzt bleibt im Raum stehen. Sicher ist jedoch, dass sich viele an diese Guidlines halten und auch der Open-Source-Code in der freien Welt sich stark danach richten. Auf der Microsoft-Plattform Codeplex, aber auch auf SourceForge.net oder auch Community Seiten wie www.codeproject.com sieht man Entwickler aus aller Welt, die diesen Stil verwenden. Nun ich muss sagen, seit dem ich es auch so praktiziere hat sich mein Verständnis für fremden Code der sich nach den gleichen Richtlinien gestaltet erheblich verbessert. Der Code wird meiner Meinung nach einfach interoperabler.

Meine klaren Empfehlungen: Richtlinien im Team entwickeln, die sich an den bestehenden im Markt anlehnen. Somit wird auch zugelieferter Code von außen veständlicher (falls Projekte extern vergeben werden).

Verständlicherer Code und bessere Verständlichkeit in der Teamkommunikation liefern Entwurfsmuster. Ob einfache Designpatterns wie Gang Of Four (schön zusammengefasst auf http://dofactory.com/) oder Enterprise Patterns, wie sie in den Enterprise Application Blocks oder Frameworks wie Spring.NET zu finden sind; jeder ernstzunehmende Entwickler sollte sich lieber früher als später damit beschäftigen. Zu Patterns wird es an anderer Stelle noch mehr geben.

Jobs, Jobs, Jobs!

19.05.2008 11:10:53 | Oliver Guhr

mitarbiter werben

Das Unternehmen für das Robert und ich arbeiten, die T-Systems Multimedia Solutions GmbH sucht zur Zeit 200 Mitarbeiter Deutschland weit. Um die offenen Stellen zu besetzen wurde allen Mitarbeitern bis zu 1000€ pro geworbenen Mitarbeiter geboten.
Wir Teilen uns die Kohle mit dir! Schicke dazu nach erfolgreicher Bewerbung eine Mail an Robert oder mich. Weitere Informationen zur Bewerbung findest du hier.

Offene Stellen im Bereich IT

Offene Stellen im Bereich Non-IT

T-Systems Multimedia Solutions - A Great Place To Work!

Vortrag "GUI-Design für Nicht-Designer" in Koblenz

18.05.2008 22:37:35 | Roland Weigelt

Am Mittwoch, 28. Mai 2008 bin ich bei der .NET Developer Group Koblenz zu Gast, wo ich ab 19:00 einen Vortrag mit dem Titel "GUI-Design für Nicht-Designer" halten werde.

Der Vortrag richtet sich u.a. an jene Entwickler, die von sich behaupten überhaupt keine Ahnung von GUI-Design zu haben. Die werden durch den Vortrag natürlich nicht automatisch zu perfekten GUI-Gestaltern, aber wenn man ein paar Grundregeln kennt, ist es gar nicht so schwer, zu einer durchaus brauchbaren grafischen Oberfläche zu gelangen.

In den Beispielen zeige ich GUIs mit Windows Forms, insgesamt geht es aber relativ wenig um konkrete Technologien, sondern eher darum zu lernen, Anwendungen aus der Sicht der Benutzer zu betrachten. Dabei kläre ich u.a. was zugekniffene Augen und Fluchtreflexe mit Usability zu tun haben.

MVC Storefront - Real World Application Building Excercise: ASP.NET MVC, TDD & more

18.05.2008 22:22:21 | Robert Mühsig

Schonmal etwas von Test-Driven-Developement gehört oder ASP.NET MVC?

Rob Conery (Entwickler von SubSonic und nun bei ASP.NET Team beschäftigt) versucht sich nun genau an diesen Dingen und dokumentiert dies - mittlerweile sind so bereits 10 Teile zusammengekommen:

Ich finde diese Videos sehr interessant gemacht - vor allem sieht man, warum welche Architekturentscheidung so oder so getroffen wurde - Rob erklärt ziemlich präzise jeden einzelnen Schritt und alles im TDD Umfeld.

Ich empfehle auch die Kommentare zu lesen, da dort bereits einige Architekturentscheidungen durch diskutiert wurden. Diese Diskussionen sind doch sehr lehrreich - insgesamt finde ich die momentane Architektur, welche Rob gewählt hat, sehr interessant.

Das Ganze gibts auch auf Codeplex zum Download.

Buchempfehlung: The Pragmatic Programmer

18.05.2008 21:00:56 | Robert Mühsig

Bücher sind für viele Programmierer ein Graus - sie veralten zu schnell und die beschriebenen Techniken sind schnell abgelöst.
Es gibt allerdings auch Bücher, die selbst nach Jahren noch einiges Wissen weitergeben. Eines davon ist das Buch “The Pragmatic Programmer“.

In dem Buch werden viele praktische Tipps weitergegeben - vieles ist bestimmt schon irgendwie bekannt (z.B. das eine “lose Kopplung” zwischen irgendwelchen Systemteilen günstig ist oder das eine Source Control unbedingt eingesetzt werden sollte), aber trotzdem gibt es sehr coole Aha-Effekte.
Manche Sachen treffen jetzt auch nicht unbedingt auf mich zu bzw. werde ich mich damit erst mal nicht beschäftigen, aber als prinzipielle Gedanke ist es gut. Vor allem Anfänger sollten dieses Buch mal durchlesen :)

Amazon.de Widgets

Software-Tipp: Microsoft WorldWide Telescope (für Hobby Astronomen)

18.05.2008 20:14:56 | Robert Mühsig

Microsoft Research hat eine nette Spielerei freigegeben: WorldWide Telescope. Es ist “ähnlich” wie Google Earth - nur das man hier durch das Weltall sich navigieren kann. Erst war ich erstmal leicht gelangweilt, aber wenn man sich näher die tollen Bilder anschaut, dann kann man eine ganze Weile hin und her zommen.
Hier ein paar Screenshots:

image 
(das Interface)

image

image

Mit einer dicken Internetleitung sieht es natürlich besser aus ;)

ADO.NET Entity Data Model und EntityDataSource in Visual Studio 2008

18.05.2008 19:23:00 | Ozgur Aytekin

In diesem Beitrag möchte ich mit einer Step-by-Step Anleitung euch zeigen, wie wir einfach und schnell eine einfache ASP.NET Web Application-Anwendung erstellen mit der wir die Daten in einer Datenbanktabelle anzeigen und bearbeiten können.

Dabei werde ich mit Visual Studio 2008 Service Pack 1 Beta veröffentliche ADO.NET Entity Model und EntityDataSource Komponente (Component) als Datenbank-Schnittstelle verwenden.

Schritt 1: Ein neues ASP.NET Web Application Projekt erstellen

Visual Studio 2008 starten und Menü Eintrag File - New Project auswählen.

Anschließend Visual C# - ASP.NET Web Application Template auswählen und EntityDataSourceSample0002 als Projektname definieren.

Step001 - Add New Project - ASP.NET Web Application

Schritt 2: Als nächstes Erstellen wir eine ADO.NET Entity Data Model-Klasse

Mit Hilfe des Project - Add Component Menü Eintrag den Auswahl-Dialog für Projekt-Elemente starten.

Im Dialog ADO.NET Entity Data Model-Element auswählen und AdventureWorks.edmx als Name definieren.

Step002 - Add New Item - ADO.NET Entity Data Model

Schritt 2a: Entity Data Model Wizard-Dialog

Im Wizard "Generate from database"-Element auswählen.

Step002a - Entity Data Model Wizard - Generate from database

Schritt 2b: Datenbank-Verbindung (Database connection)

In diesem Dialog definieren wir die Datenbank-Verbindung (Database connection). Zusätzlich wird auch der Name des Web.Config-Eintrages für die ConnectionString definiert.

In dem folgenden Beispiel wird ein SQL Server 2008 mit der AdventureWorks-Datenbank verwendet und der Eintrag im Web.Config-File heißt AdventureWorksEntitites.

Step002b - Choose Your Data Connection

Schritt 2c: Datenbank-Objekt (Database object) auswählen

Erst hier definieren wir, welche Datenbank-Tabelle(n) (Database table(s)) für unser Model relevant sind.

In dem folgenden Beispiel wird nur die CountryRegion-Tabelle ausgewählt. Zusätzlich wird der Name für den Model Namespace definiert. Im Beispiel wird AdventureWorksModel als Namespace verwendet.

Step002c - Choose Your Database Objects

Als Resultat erhalten wird unser AdventureWorks-Model mit der CountryRegion-Entity Klasse (Entity Class)

Step002d - AdventureWorksModel - CountryRegion Entity

Schritt 3: EntityDataSource-Komponente (Component)

In diesem Schritt werden wir die EntityDataSource-Komponente in unsere Seite einbinden und Konfigurieren.

Wir wechseln in das Design-Modus des Default.aspx-Elements. Einfach Solution Explorer auswählen und auf das Default.aspx-Element doppelklicken.

Im Toolbox unter dem Abschnitt Data sehen wir unseren EntityDataSource-Komponente (Component).

Step003 - EntityDataSource

Mit Drag & Drop die EntityDataSource-Komponente (Component) auf das Default.aspx-Element ziehen und los lassen.

Schritt 3a: EntityDataSource - DataSource-Eigenschaft konfigurieren (Configure Data Source)

Als nächstes werden wir die DataSource-Eigenschaft der EntityDataSource-Komponente konfigurieren. Für die Konfiguration kann der Eintrag Configure Data Source (wie im untenstehenden Bild ersichtlich) ausgewählt werden.

Step003a - EntityDataSource - Configure Data Source

Schritt 3b: ObjectContext-Konfigurieren (Configure ObjectContext)

Die ConnectionString und DefaultContainerName Informationen werden im folgenden Dialog definiert.

"Die Beta 1 des Visual Studio 2008 Service Packs hat leider einen Fehler (Bug). Ich werde euch zeigen, wie man diesen Fehler umgehen kann."

Namen Connection markieren und den Eintrag AdventureWorksEntities auswählen.

Step003b - EntityDataSource - ConnectionString

Wenn wir versuchen, den DefaultContainerName-Eigenschaft zu definieren, dann erhalten wir folgenden Fehlermeldung (Fehler (Bug) in Visual Studio 2008 ServicePack 1 Beta): The Entity Data Model metadata specified in the connection string could not be loaded due the following error(s): Unable to load specified metadata resource.

Step003c - EntityDataSource - Error - DefaultContainerName

Schritt 3c: Fehler (Bug) Korrektur

Die Fehlermeldung mit OK bestätigen und den Wizard mit Cancel abbrechen.

In der Web.Config-Datei wurde im Abschnitt ConnectionString ein falscher Eintrag verursacht diesen Fehler:

Step003ca - EntityDataSource - Error - DefaultContainerName - Correction

Die "*" müssen mit dem Projektnamen (Project name) bzw. Assemlby-Namen (Assembly name) ersetzt werden.

Step003cb - EntityDataSource - Error - DefaultContainerName - Correction

Die Datei speichern und neu KOMPILIEREN (Build).

Anschließend nochmals zurück auf das Design-Modus der Default.aspx-Seite wechseln und den EntityDataSource-Element konfigurieren (siehe Schritt 3a).

Schritt 3d: DefaultContainerName auswählen

Als DefaultContainerName den Eintrag AdventureWorksEntites auswählen.

Step003d - EntityDataSource - DefaultContainerName

Schritt 3e: Daten-Selektion konfigurieren (Configure Data Selection)

In diesem Schritt definieren wir, welche Funktionalitäten für unsere CountryRegion-Klasse zur Verfügung stellen soll.

Gemäß folgende Bild die Einstellungen vornehmen und den Dialog mit Finish abschließen.

Step003e - EntityDataSource - Configure Data Selection

Schritt 4: GridView-Element für die Datenanzeige und Bearbeitung

Für die Anzeige und Bearbeitung der Daten benötigen wir ein GridView-Element. Einfach ein neues GridView-Element mit Drag & Drop auf die Default.aspx-Seite ziehen.

Step004 - DataGridView

Schritt 4a: GridView DataSource-Eigenschaft (Property)

Als nächstes konfigurieren wir die Data Source-Eigenschaft (Property) des GridView-Controls. Als Data Source den EntityDataSource1-Eintrag auswählen.

Step004a - DataGridView - Choose Data Source

Unser GridView-Control wie folgt aus:

Bitte hier auch die Optionen Enable Paging, Enable Sorting, Enable Editing, Enable Deleting und Enable Selection auch ankreuzen.

Step004b - DataGridView - GridView Tasks

Jetzt können wir unser Beispiel-Projekt mit F5 starten.

Wenn bei euch auch die "Debugging Not Enabled"-Meldung erscheint, einfach mit OK weitermachen.

Step005 - Run - Modify the Web.config file to enable debugging

Nach eine "einbißchen lange" Wartezeit sehen wir in unserem Browser (in meinem Beispiel Internet Explorer) die Default.aspx-Seite mit GridView und die CountryRegion-Daten.

Step006 - Default.aspx in Internet Explorer

Das Beispielprojekt findet ihr unter: EntityDataSourceSample0002

Viel Spaß beim ausprobieren.

Für Feedbacks über die Kommentar-Funktionalität wäre ich dankbar, ob das Beispiel-Projekt bei euch auch funktioniert hat.

Sonntag 2.0

18.05.2008 17:13:39 | Oliver Scheer

Sonntag 2.0 – ein Mini-Barcamp zum Thema: Web 2.0 und Sicherheits-Aspekte

Schon mal auf einem Barcamp gewesen? Am Sonntag den 25.05.2008  findet unser erstes Mini- Barcamp in München statt zum Thema: Web 2.0 und Sicherheits-Aspekte.  Mehr Informationen und kostenfreie Anmeldung unter: http://sonntag.mixxt.de/

2842_gra_logo_sonntag20

XTOPIA 2008 kommt ...

18.05.2008 17:06:46 | Oliver Scheer

Am 17. und 18.11. findet die XTOPIA zum zweiten Mal statt.

Wieder in Berlin, dieses Mal jedoch im Berliner ICC. Am 16. November findet zusätzlich noch eine Pre-Conference statt. Die Microsoft Web-Konferenz für Web- und UI-Entwickler, IT-Entscheider und Designer geht damit ins zweite Jahr... wir freuen uns auf Sie! Bleiben Sie auf dem Laufenden über den RSS-Feed auf www.xtopia.de. In Kürze finden Sie dort ausführlichere Informationen und natürlich auch die Möglichkeit zur Registrierung.

Mehr Infos gibt es unter www.xtopia.de

Die Fusion entmystifiziert - Teil 1

18.05.2008 16:05:36 | Klaus Bock

Wir alle benutzen sie mehr oder weniger oft, doch kaum einer nimmt Notiz von ihr; die Fusion-API. Egal ob mit gacutil.exe eine Assembly dem GAC hinzugefügt wird oder ein MSI-Paket eine Assembly im GAC installiert, es ist immer die Fusion-API die das erledigt. Selbst der Assembly Cache Viewer des Explorer, die shfusion.dll, verwendet die Fusion-API.

Ich stand immer wieder vor dem Problem verschiedene Assemblies im GAC zu installieren auf Maschinen auf denen kein .NET SDK installiert ist, also auch keine gacutil.exe. Der Assembly Cache Viewer ist zu umständlich da, soweit ich es weiß, er nicht gescriptet werden kann. Jedesmal ein Setup-Projekt erstellen; das kann es doch nicht sein! Also begann ich eine kleine Konsolenanwendung um mir die Aufgabe ein wenig zu erleichtern. Dachte ich!

Mir fiel sehr schnell eine Eigenart der CLR auf: wenn eine Assembly geladen wurde um mittels Reflection die Attribute der Assembly auszulesen, kann diese Assembly weder verschoben noch gelöscht werden. Nach einigen weniger Erfolgreichen Recherchen, stieß ich auf den Sample Managed GAC API Wrappers Artikel von Junfeng Zhang. Nachdem ich den Ansatz gefunden hatte, sah ich mir die Fusion (Referenz zur nicht verwalteten API) einmal genauer an. Heureka! Das ist es.

Als Basis für meinen GacWrapper habe ich den oben erwähnten Artikel von Junfeng Zhang verwendet. Doch mein erstes Ziel, das Auslesen der Assembly-Attribute unter Angabe des Dateinamens, war mit dieser Beispiel-Implementierung nicht zu lösen. Mit der Methode GetAttribute der Schnittstelle IReferenceIdentity könnte dieses Problem jedoch gelöst werden. Die Methode gibt in der Original-Implementierung ein HRESULT zurück und liefert den benötigten Wert mittels eines out-Parameter. Da out-Parameter vermieden werden sollten, habe ich die Methode so geändert, dass der Wert direkt als string zurückgegeben wird. Hier die Schnittstelle im Code:

Jetzt wird noch eine Methode benötigt die der Schnittstelle mitteilt, welche Assembly behandelt werden soll. Die Fusion-API bietet hier die statische Methode GetAssemblyIdentityFromFile an, welche als Rückgabewert einen Zeiger auf ein IUnknown-Objekt liefert. Da die Implementierung der IReferenceIdentity als ComInterfaceTyp InterfaceIsUnKnown verfügbar ist, sollten hier keine Probleme auftauchen. Die statische Methode erwartet den Pfad zur Assembly und die Guid der verwendeten Schnittstelle. Da ich, wenn möglich, Zeiger im verwalteten Code vermeide habe ich die Implementierung der statischen Methode so geändert, dass ein Object zurückgegeben wird. Das Rückgabe-Objekt kann dann in ein Objekt vom Typ IReferenceIdentity geparst werden. Natürlich muss hier das zurückgegebene Objekt in den Typ IUnknown gemarshallt werden. Auch muss unbedingt beachtet werden, dass im DllImport-Attribute der Zeichensatz Unicode beim marshalling verwendet wird. Die Umsetzung in Code sollte dann etwa so aussehen:

Soweit zur Implementierung des nicht verwalteten Codes. Als nächstes habe ich eine Klasse gebildet in der auf die Assembly-Attribute lesend zugegriffen werden kann. Da die Möglichkeit zur Iteration durch die Attribute gegeben werden soll, verwende ich ein StringDictionary um die ermittelten Attribute in einer Klasse vor zuhalten. Hier ein Auszug daraus:

Bis jetzt ist die Möglichkeit geschaffen die Attribute einer Assembly, nur anhand des Dateinamens, auszulesen. Die Assembly wurde dabei nicht von der CLR geladen, kann also verschoben, gelöscht oder wie auch immer gehandhabt werden.

Die Fusion-API bietet deutlich mehr als diese eine Möglichkeit. Ich werde nach und nach, auch soweit ich Zeit dazu finde, diese Serie erweitern.

Technorati-Tags: | |

Visual Studio 2008 Service Pack 1 Beta Installation - Fatal error during installation

18.05.2008 15:53:00 | Ozgur Aytekin

Die Installation von Visual Studio 2008 Service Pack 1 Beta hat bei mir immer wieder fehlgeschlagen.

Jedes Mal wurde die Installation des Service Pack 1 Beta mit der Fehlermeldung "Fatal error during installation" abgebrochen.

Visual_Studio_2008_Service_Pack_1_SP1_Beta_Fatal_Error_During_Installation

Unter folgenden Forum Eintrag bei forums.microsoft.com konnte ich die Hilfe finden.

Fatal Error during Installation of Visual Studio 2008 service pack 1 beta

Nach der Installation der Full-Installer des .NET Framework 3.5 Service Pack 1 Beta konnte ich den Service Pack 1 Beta für Visual Studio 2008 erfolgreich installieren.

Die URL für die Full-Installer des .NET Framework 3.5 Service Pack 1 Beta: Microsoft .NET Framework 3.5 Service pack 1 Beta (Full-Installer)

Performance Tipp: Eine DB Connection global für einen Page Request definieren.

16.05.2008 23:31:00 | Jürgen Gutsch

Im Moment arbeite ich gerade an einer kleinen Communitiy Anwendung (ja klein, muss ja nicht immer groß sein) die standardmäßig eine Access Datenbank nutzt. Datenbankzugriffe sehen im Moment so aus, dass ich für jede Abfrage eine neue Datenbankverbindung öffne und anschließend wieder schließe. Eigentlich eine normale Prozedur:

using (OleDbConnection conn = new OleDbConnection(this.ConnectionString))
{
  string cmdText = "DELETE FROM [emails] WHERE [mailid]=?";
  using (OleDbCommand cmd = new OleDbCommand(cmdText, conn))
  {
    cmd.Parameters.Add("mailid", OleDbType.Guid).Value = ID;
    cmd.ExecuteNonQuery();
  }
}

Und ausreichend für einen einzelnen Zugriff. Meine Anwendung macht aber pro Page Request mindestens fünf Zugriffe; im Schnitt sind es sogar mehr.

In einem Thread auf MyCSharp, in dem es um zu schließende Connections beim Verlassen einer Website ging, wurde ich von Peter auf eine Diskussion auf Google Groups aufmerksam gemacht, in der es darum ging Datenbankverbindungen global zur Verfügung zu stellen. Stefan stellte dabei einen interessanter Ansatz vor:

Er definierte eine Klasse, die für das Öffnen und Schließen der Datenbankverbindung zuständig ist und die offne Verbindung hält. Diese Klasse wird in der Global.asax bei Application_BeginRequest instanziert, die Connection wird geöffnet und anschließend wird das erzeugte Objekt im aktuellen HttpContext gespeichert. Bei Application_EndRequest wird das Objekt aus dem HttpContext ausgelesen und die Verbindung geschlossen. Im Prinzip eine einfache und geniale Lösung. Die Connection kann jetzt überall in der Anwendung aus dem HttpContext geholt und genutzt werden.

Da ich wie erwähnt nach Optimierungsmöglichkeiten suchte, lag es nahe Stefans Vorschlag auszuprobieren, zumal mir langsam die Ideen für weitere Optimierungen beim Datenbankzugriff ausgegangen sind.

Die Klasse, die die Verbindung zur Datenbank hält, sieht bei mir folgendermaßen aus:

public class DB
{
  public string ConnectionString { get; set; } 
  private IDbConnection dbConnection;
  public IDbConnection DbConnection
  {
    get
    {
      if (dbConnection == null)
        dbConnection = new OleDbConnection(ConnectionString);
      if (dbConnection.State == ConnectionState.Closed 
            || dbConnection.State == ConnectionState.Broken)
        dbConnection.Open();
      return dbConnection;
    }
  }
  public DB(string ConnectionString)
  {
    this.ConnectionString = ConnectionString;
  } 
  public void Open()
  {
    dbConnection = new OleDbConnection(ConnectionString);
  } 
  public void Close()
  {
    if (dbConnection != null)
    {
      dbConnection.Close();
      dbConnection.Dispose();
    }
  }
}

Wichtig ist hier die Eigenschaft DbConnection. Diese instanziert die Datenbankverbindung erst wenn sie das erste mal benötigt wird. Falls keine Connection benötigt wird, enthält diese Klasse nichts anderes als einen Connection String. Das ist auch deswegen von Vorteil, da im IIS7 (IMHO nur im Integrated Pipeline Mode) und im Development Webserver des Visual Studio jeder Request (auch Bilder, CSS und JavaScripts) die Event Handler Application_BeginRequest und Application_EndRequest auslöst. Es wird also somit nicht bei jedem Request eine Datenbankverbindung geöffnet.

So sehen die Event Handler in der Global.asax aus:

void Application_BeginRequest(object sender, EventArgs e)
{
  DB db = new DB(ConfigurationManager.ConnectionStrings
        ["DefaultConnection"].ConnectionString);
  HttpContext.Current.Items["DB"] = db;

void Application_EndRequest(object sender, EventArgs e)
{
  DB db = HttpContext.Current.Items["DB"] as DB;
  if (db != null)
    db.Close();
}

In meine Basisklassen habe ich nun ebenfalls einen neue Eigenschaft eingefügt, welche mir die Datenbankverbindung aus dem HttpContext holt:

private DB db;
public IDbConnection DbConnection
{
  get
  {
    if (db == null)
      db = Context.Items["DB"] as DB;
    return db.DbConnection;
  }
}

Meine Datenbankabfragen kann ich somit nun um ein paar Zeilen erleichtern:

string cmdText = "DELETE FROM [emails] WHERE [mailid]=?"
using (OleDbCommand cmd = 
    new OleDbCommand(cmdText, this.DbConnection as OleDbConnection)) 

  cmd.Parameters.Add("mailid", OleDbType.Guid).Value = ID; 
  cmd.ExecuteNonQuery(); 
}

Nachdem ich das nun komplett in meine Anwendung integriert hatte, waren schon alleine beim Durchklicken eine deutliche Verbesserungen der Performance zu spüren.

Peter hatte in dem Thread zusätzlich den Vorschlag gemacht die Methode so weit zu verfeinern, dass nur Page Handler, bzw. Handler dessen Dateiendung "*.aspx" ist. die Klasse für die DB Verbindung instanzieren dürfen. Er geht sogar soweit, die Instanzierung auch für HttpHandler zu erlauben, die ein spezielles Marker Interface implementiert haben.

Das sieht dann so aus, dass erst ein Marker Interface definiert werden muss:

public interface IRequiresDbConnection{}

Die Implementierung des Interfaces:

public partial class myhandler : IHttpHandler, IRequiresDbConnection
{
[...]
}

Da die Handler bei Application_BeginRequest noch null sind, muss die Instanzierung unserer Klasse und die Abfrage auf den Handler, z. B: im Event Handler Application_PreRequestHandlerExecute erfolgen:

void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
  IHttpHandler handler = (sender as HttpApplication).Context.CurrentHandler;
  if (handler != null && (handler is Page || handler is IRequiresDbConnection))
  {
    DB db = new DB(ConfigurationManager.ConnectionStrings
        ["DefaultConnection"].ConnectionString);
    HttpContext.Current.Items["DB"] = db;
  }
}

Da ich die eigentliche Verbindung nur öffne, wenn sie das erste mal benötigt wird und im Prinzip jedes Webform und jeder Generic Handle allein wegen der Authentifizierung eine Datenbankverbindung benötigt, halte ich es in - meinem Fall - nicht für erforderlich Peters Vorschlag mit dem Marker Interface zu arbeiten.

Wie bereits erwähnt, ist in einer Anwendung mit vielen Datenbankzugriffen eine deutliche Performancesteigerung zu spüren, wenn pro Request nur eine Verbindung zur Datenbank geöffnet wird.

Danke euch beiden (Stefan und Peter) für den wertvollen Tipp :-)

Performance Tipp: Eine DB Connection global für einen Page Request definieren.

16.05.2008 23:31:00 | Jürgen Gutsch

Im Moment arbeite ich gerade an einer kleinen Communitiy Anwendung (ja klein, muss ja nicht immer groß sein) die standardmäßig eine Access Datenbank nutzt. Datenbankzugriffe sehen im Moment so aus, dass ich für jede Abfrage eine neue Datenbankverbindung öffne und anschließend wieder schließe. Eigentlich eine normale Prozedur:

using (OleDbConnection conn = new OleDbConnection(this.ConnectionString))
{
  string cmdText = "DELETE FROM [emails] WHERE [mailid]=?";
  using (OleDbCommand cmd = new OleDbCommand(cmdText, conn))
  {
    cmd.Parameters.Add("mailid", OleDbType.Guid).Value = ID;
    cmd.ExecuteNonQuery();
  }
}

Und ausreichend für einen einzelnen Zugriff. Meine Anwendung macht aber pro Page Request mindestens fünf Zugriffe; im Schnitt sind es sogar mehr.

In einem Thread auf MyCSharp, in dem es um zu schließende Connections beim Verlassen einer Website ging, wurde ich von Peter auf eine Diskussion auf Google Groups aufmerksam gemacht, in der es darum ging Datenbankverbindungen global zur Verfügung zu stellen. Stefan stellte dabei einen interessanter Ansatz vor:

Er definierte eine Klasse, die für das Öffnen und Schließen der Datenbankverbindung zuständig ist und die offne Verbindung hält. Diese Klasse wird in der Global.asax bei Application_BeginRequest instanziert, die Connection wird geöffnet und anschließend wird das erzeugte Objekt im aktuellen HttpContext gespeichert. Bei Application_EndRequest wird das Objekt aus dem HttpContext ausgelesen und die Verbindung geschlossen. Im Prinzip eine einfache und geniale Lösung. Die Connection kann jetzt überall in der Anwendung aus dem HttpContext geholt und genutzt werden.

Da ich wie erwähnt nach Optimierungsmöglichkeiten suchte, lag es nahe Stefans Vorschlag auszuprobieren, zumal mir langsam die Ideen für weitere Optimierungen beim Datenbankzugriff ausgegangen sind.

Die Klasse, die die Verbindung zur Datenbank hält, sieht bei mir folgendermaßen aus:

public class DB
{
  public string ConnectionString { get; set; } 
  private IDbConnection dbConnection;
  public IDbConnection DbConnection
  {
    get
    {
      if (dbConnection == null)
        dbConnection = new OleDbConnection(ConnectionString);
      if (dbConnection.State == ConnectionState.Closed 
            || dbConnection.State == ConnectionState.Broken)
        dbConnection.Open();
      return dbConnection;
    }
  }
  public DB(string ConnectionString)
  {
    this.ConnectionString = ConnectionString;
  } 
  public void Open()
  {
    dbConnection = new OleDbConnection(ConnectionString);
  } 
  public void Close()
  {
    if (dbConnection != null)
    {
      dbConnection.Close();
      dbConnection.Dispose();
    }
  }
}

Wichtig ist hier die Eigenschaft DbConnection. Diese instanziert die Datenbankverbindung erst wenn sie das erste mal benötigt wird. Falls keine Connection benötigt wird, enthält diese Klasse nichts anderes als einen Connection String. Das ist auch deswegen von Vorteil, da im IIS7 (IMHO nur im Integrated Pipeline Mode) und im Development Webserver des Visual Studio jeder Request (auch Bilder, CSS und JavaScripts) die Event Handler Application_BeginRequest und Application_EndRequest auslöst. Es wird also somit nicht bei jedem Request eine Datenbankverbindung geöffnet.

So sehen die Event Handler in der Global.asax aus:

void Application_BeginRequest(object sender, EventArgs e)
{
  DB db = new DB(ConfigurationManager.ConnectionStrings
        ["DefaultConnection"].ConnectionString);
  HttpContext.Current.Items["DB"] = db;

void Application_EndRequest(object sender, EventArgs e)
{
  DB db = HttpContext.Current.Items["DB"] as DB;
  if (db != null)
    db.Close();
}

In meine Basisklassen habe ich nun ebenfalls einen neue Eigenschaft eingefügt, welche mir die Datenbankverbindung aus dem HttpContext holt:

private DB db;
public IDbConnection DbConnection
{
  get
  {
    if (db == null)
      db = Context.Items["DB"] as DB;
    return db.DbConnection;
  }
}

Meine Datenbankabfragen kann ich somit nun um ein paar Zeilen erleichtern:

string cmdText = "DELETE FROM [emails] WHERE [mailid]=?"
using (OleDbCommand cmd = 
    new OleDbCommand(cmdText, this.DbConnection as OleDbConnection)) 

  cmd.Parameters.Add("mailid", OleDbType.Guid).Value = ID; 
  cmd.ExecuteNonQuery(); 
}

Nachdem ich das nun komplett in meine Anwendung integriert hatte, waren schon alleine beim Durchklicken eine deutliche Verbesserungen der Performance zu spüren.

Peter hatte in dem Thread zusätzlich den Vorschlag gemacht die Methode so weit zu verfeinern, dass nur Page Handler, bzw. Handler dessen Dateiendung "*.aspx" ist. die Klasse für die DB Verbindung instanzieren dürfen. Er geht sogar soweit, die Instanzierung auch für HttpHandler zu erlauben, die ein spezielles Marker Interface implementiert haben.

Das sieht dann so aus, dass erst ein Marker Interface definiert werden muss:

public interface IRequiresDbConnection{}

Die Implementierung des Interfaces:

public partial class myhandler : IHttpHandler, IRequiresDbConnection
{
[...]
}

Da die Handler bei Application_BeginRequest noch null sind, muss die Instanzierung unserer Klasse und die Abfrage auf den Handler, z. B: im Event Handler Application_PreRequestHandlerExecute erfolgen:

void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
  IHttpHandler handler = (sender as HttpApplication).Context.CurrentHandler;
  if (handler != null && (handler is Page || handler is IRequiresDbConnection))
  {
    DB db = new DB(ConfigurationManager.ConnectionStrings
        ["DefaultConnection"].ConnectionString);
    HttpContext.Current.Items["DB"] = db;
  }
}

Da ich die eigentliche Verbindung nur öffne, wenn sie das erste mal benötigt wird und im Prinzip jedes Webform und jeder Generic Handle allein wegen der Authentifizierung eine Datenbankverbindung benötigt, halte ich es in - meinem Fall - nicht für erforderlich Peters Vorschlag mit dem Marker Interface zu arbeiten.

Wie bereits erwähnt, ist in einer Anwendung mit vielen Datenbankzugriffen eine deutliche Performancesteigerung zu spüren, wenn pro Request nur eine Verbindung zur Datenbank geöffnet wird.

Danke euch beiden (Stefan und Peter) für den wertvollen Tipp :-)

Was rollt im Bereich Unittesting auf uns zu?

16.05.2008 11:55:59 | Rainer Schuster

Die Mannschaft rund um MbUnit ist auf dem besten Weg zu einer BETA. Aktuell ist im Moment Alpha 3. Was tut sich hier? Gallio ist ein gänzlich neues Testframework, das alle möglichen Arten von Unit Tests entgegen nimmt. Für mich persönlich erst einmal die wichtigsten:

  • MbUnit
  • NUnit
  • MSTest

Es gibt einen neuen Testrunner, der Icarus heißt. Ein schöner grafischer Testrunner, in dem wie gesagt alle Arten von Tests ablaufen. Experimentell in der neuen Version gibt es Unterstützung für MSTest, d.h. die Einheitentests können aus dem VisualStudio heraus mit dem Testframework von Microsoft getestet werden. MbUnit und MSTest ist im Moment mein Favorit, was die Frameworks angeht. Warum? Weil mit MSTest ohne Probleme interne, protected und private Klassen testen kann. MbUnit, weil es so schnell ist (MSTest ist hier eher lausig, was die Performance angeht, stellt man beide zum Vergleich nebeneinander) und weil es gut erweiterbar ist und schon viele nützliche Plugins besitzt. NUnit zieht hier auch immer wieder nach, aber meiner Meinung nach ist MbUnit führend. Die Entwicklung rund um Gallio ist jedenfalls groß! NUnit muss deshalb für mich mit in Betracht gezogen werden, weil es von einer Vielzahl von Projekten bereits benutzt wird. Viel Unterschied zwischen den xUnit basierten Frameworks gibt es nicht, MbUnit wir meiner Meinung nach am besten weiterentwickelt und bietet heute schon die meiste Funktionalität. Ich bin sehr gespannt, was MbUnit V3 und das Gallio Framework angeht.

MbUnit wir auch eine neuartige Möglichkeit des Unittesting unterstützen, an dem Peli de Halleux bei Microsoft in der Forschung  aktiv ist. Pex heißt hier das Zauberwort und soll eine neue Art und Weise des Unit Testing einführen. Der Webcast der unter dem angegebenen Link zu finden ist zeigt schön die Funktion. Leider gibt es noch kein offizielles Release. Wie ich aber von Peli erfahren habe wird es in naher Zukunft einen akademischen Release zur Evaluierung geben. Wer sich die Researchseite ansieht, wird auch schon die Dokumentation dazu entdecken. Aber was macht Pex eigentlich? Definiert wird eine Test-Funktion mit Parametern und Pex ermittelt automatisch möglich Inputparameter. Aus dem bekannten Red-Green-Refactoring wird ein Red-Yellow-Green-Refactoring. Pex ermittelt die Werte führt die Funktion aus und schaltet auf Gelb, wenn eine dieser Ausführungen fehlgeschlagen ist. In MSTest wird es so ablaufen, dass Pex dem Entwickler dann einen Vorschlag macht, wie der Fehler zu beheben ist. Neugierig gemacht? Wen es interessiert kann auf der Seite mehr finden.

Rosario Talk in der User Group Ulm

15.05.2008 12:39:26 | Christian Binder

Ich werde am 28.5 in der User Group Ulm über Rosario CTP 12 sprechen.
Wir werden den CTP 12 mal genauer unter die Lupe nehmen und die Neuerungen aufzeigen, die jetzt schon drin sind.
Vor allem in der Architekt Edition hat sich viel bewegt: Use Case Diagrams, Sequence Diagrams und  Logical Class Diagrams. Aber auch Neuerungen wie Workitem Links/Hierarchien, UI Testing, Build, Standalone Debugger, Unit Test Impact....  werden ein Thema sein.

Schon heute wissen was morgen passiert :-) dann geht's hier weiter.

Viel Spass

Chris

Kostenloses Kapitel aus kommendem Fachbuch über Unit-Testing

15.05.2008 10:50:43 | Rainer Schuster

Aus dem Manning Verlag gibt es von Unit-Testing Koryphäe Roy Osherove eine Buchankündigung (the art of UNIT TESTING), bei dem nun das erste Kapitel (The Basics of unit testing) redaktionell unbearbeitet und kostenlos zur Verfügung steht. Dabei geht Osherove schön auf die Materie des Unit Testing ein. Wie sich ein Test definiert, wie dieser zu gestalten ist. Macht eine Abgrenzung was machbar ist und was nicht so gut funktionert. Er geht dabei auch auf die Integrationstests ein, zeigt die Theorie von Test im allgemeinen an praktischen Beispielen auf und geht zum Schluss auf die testgetriebene Entwicklung ein (Testdriven Developement - TDD).

 

Fazit: Sehr empfehlenswert!

Schnelle Prototypen Tests mit Testdriven.NET

15.05.2008 10:13:30 | Rainer Schuster

Testdriven.NET ist ein kleines - sehr hilfreiches - Tool wenn es darum geht seine Implementation mal schnell auszutesten, oder im allgemeinen Tests zu erstellen. Es gibt eine kostenlose "Personal Edition" die zum evaluieren und schnellen Testen bestens geeignet ist.Testdriven.NET gelingt eine schöne Integration ins Visual Studio. Es bindet alle gängigen Testframeworks an (NUnint, MbUnit, MSTest) und bieten nebenbei noch produktivitätssteigernde Funktionen.

Eine dieser schönen Funktion ist das "Soforttesten" von Funktionen. Einfach per rechter Maustaste auf die zu testende Funktion --> "Run Test(s)". Damit können nicht nur Funktionen getestet werden, die mit einem Testattribut (TestFixture, Test) ausgezeichnet sind, sondern jede beliebige Funktion. Dies eignet sich hervorragend um eine Änderung/neue Funktion ausserhalb eines Kontext auf Richtigkeit zu testen. Probiert die Funktion einfach mal aus.

Zu Einheitentests im allgemeinen:

In meinem bisherigen Arbeitsleben habe ich einiges gelernt, darunter Regel Nr. 1: Sei Faul - das bezieht sich nicht auf den Umfang einer Aufgabe, sondern die Art und Weise wie etwas erledigt wird. Es soll heißen, benutze so wenig Aufwand wie möglich um deine Vorgaben zu erledigen. Wer in BWL/Wirtschaft oder einem ähnlichen Fach aufgepasst hat, wird hier das Minimal-Prinzip erkennen. Anders wird es nur funktionieren, wenn ich es mit all meinem Wissen, egal wie lange es dauert (dem Input), schaffe das beste Ergebnis, das nur möglich ist (Output) zu erreichen (Maximalprinzip).

Getreu dem Motto Minimalprinzip versuche ich Tests, die in jedem Produktlebenszyklus auftreten zu automatisieren. Das hat ganz triviale und logische Gründe zugleich:

  1. Die Fehleranfälligkeit sinkt, weil ich nicht immer wieder die gleiche monotone Aufgabe erledigen muss. Menschen neigen dazu sich oft wiederholenden Aufgaben (die evtl. zur Routine werden) nachlässig durchzuführen. Daraus ergeben sich zwangsläufig Fehler.
  2. Es erspart mir Zeit. Viele werden dagegen halten, das der Vorgang zum erstellen der Tests auch Zeit kostet, evtl. sogar mehr. Nun muss ich aber die Gesamtheit aller Punkte die ich hier aufzähle dagegen halten und die Tatsache, dass sich wiederholende Teste genau, wenn nicht sogar noch mehr als zeitintensiv gestallten.
  3. Aus dem vorherigen Punkt folgend werden Investitionskosten gesenkt da die einfach Formel Zeit = Geld auch in diesem Fall kein Ergebnis verfälschen kann.
  4. Dem Entwickler werden Unsicherheiten bei späteren Neuentwicklungen genommen. Jedes Produkt das nicht von der Planungsphase aus auf Vollständigkeit (100% aller Aufgaben erfüllt) ausgelegt ist, muss sich im Laufe seines Lebenszyklus einer Wartung, Erweiterung, Verfeinerung unterziehen um Anpassungen, und Abhängigkeiten zu implementieren. Die Test helfen dabei früh zu erkennen an welchen stellen die sogenannten Code-Breaking-Changes auftreten; also jene, die mein Produkt zur Kompilierzeit zerstören, ja sogar durch logische Tests die Konsistenz der Daten gewährleisten.

Windows XP Service Pack 3 (SP3)

15.05.2008 10:02:00 | Ozgur Aytekin

Windows XP Service Pack 3 (SP3) kann unter folgende URL heruntergeladen werden:

Die deutsche Version: Windows XP Service Pack 3-Netzwerkinstallationspaket für IT-Spezialisten und Entwickler

English version: Windows XP Service Pack 3 Network Installation Package for IT Professionals and Developers

Die ISO-Dateien sind wie folgt verfügbar:

Die deutsche Version: Windows XP Service Pack 3 - ISO-9660-CD-Abbilddatei

English version: Windows XP Service Pack 3 - ISO-9660 CD Image File

Technologie-Talk mit und für technische Entscheider

15.05.2008 09:10:47 | Jens Häupel

Sie arbeiten in einem Unternehmen, das nicht oder nur per Telefon von Microsoft betreut wird? Sie würden gerne in engeren Kontakt mit Microsoft treten, um besser gehört zu werden und Ihre strategische Ausrichtung mit der von Microsoft abzugleichen? Sie sind Projektleiter, Produktmanager, Solution Architect oder in ähnlicher Position?

 

Was bieten wir?

Wir wollen themenorientiert mit Ihnen über strategische Technologien reden. Wir wollen Ihnen Lösungen, Lösungsansätze und Wege vorstellen, mit denen Sie unkompliziert Ihr Geschäftsmodell erweitern können und natürlich Ihre Meinung dazu hören. Wir wollen ein Netzwerk bilden, in dem auch untereinander Synergien genutzt werden können. Das alles in kleinem Kreise von 10..15 Personen.

Wir zeigen Ihnen auch, wie Sie Microsoft Partner werden können und welche Vorteile daraus entstehen.

 

Wann?

Düsseldorf: 19. Juni 2008, 18 - 21 Uhr

München: 25. Juni 2008, 18 - 21 Uhr      [Termin-UPDATE]

Dresden: 26. Juni 2008, 18 - 21 Uhr

 

Wir beginnen mit dem Thema:

Integrationstechnologien für Microsoft Office (VSTO, Open XML, SharePoint, etc.)

 

Haben Sie Interesse? Dann schreiben Sie uns per Email oder kontaktieren Sie mich direkt über meinen Blog. Wir bestätigen Ihnen gerne die Anmeldung, sofern noch freie Plätze vorhanden sind.

 

Die Veranstaltung ist weniger für Entwickler gedacht, aber wenn Sie ein solcher sind, dann sprechen Sie bitte Ihren Projektleiter oder Produktmanager darauf an.

Herzlich willkommen in meinem Blog

14.05.2008 20:31:45 | Rainer Schuster

Hallo Community und Freunde der guten Unterhaltung. Ab sofort werde ich über meinen Programmiereralltag hier Berichten und mein Wissen rund um .NET und alles anderem was mit Programmierung zu tun hat bekannt geben. Kurze Informationen, die nicht direkt einen Artikel Wert sind oder Anmerkungen zu Technologien und Trends. Ich weiß, ihr denkt bestimmt nicht schon wieder einer, der etwas schreibt. Es gibt ja leider schon zu viele Quellen im Internet die Bloggen. Warum tue ich es dann dennoch? Um für mich selbst ein kleines Nachschlagewerk zu gestallten, von dem, was ich mal gemacht habe. Wenn mich dann jemand fragt wie etwas funktionert kann ich auf den Eintrag verweisen, oder selbst noch einmal schnell nachschlagen. Was könnt ihr von mir hier erwarten? Es wird sich auf jeden Fall um folgende Kategorien handeln, die dann im Laufe der Zeit wahrscheinlich mehr werden

  • Testgetriebene Entwicklung
  • Designpatterns
  • Softwarearchitektur (Will hier ja mal den MCPD machen)
  • Enterprise Patterns (z.B.Dependency Injection (IoC))
  • Aspektorientierte Programmierung (AOP) und Featureorientierte Programmierung
  • Erstellung von Dokumentationen mit Sandcastle und anderen Tools
  • und alles rund um meinen Alltag.
  • (vielleicht mehr infos rund um die Konfiguration und Verwendung des Teamfoundation Servers)

Aber nun wünsche ich euch viel Spaß noch weiterhin auf den Seiten von dotnet-forum.de und dotnet-snippets.de

Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery…

14.05.2008 13:48:50 | Robert Mühsig

Etwas spät zwar, aber hier eine neue Linkliste der vergangen Woche:

ASP.NET MVC:

TDD / .NET / Development:

Silverlight 2:

ASP.NET:

WPF:

Javascript:

Live Mesh:

Blogging:

Security ist ...

14.05.2008 09:29:10 | Jens Häupel

... etwas, was alle beherzigen sollten aber keiner gerne tut. Weil - es ist ja so viel bequemer!

Bei uns heißt es jetzt Security @ Sunday, und dann auch noch 2.0 - von wegen Web und so. Was soll das Ganze? Tja, wir veranstalten ein Bar Camp rund um das Thema Sicherheit in der Softwareentwicklung. Schon mal auf einem gewesen? Nein? Dann wird's aber Zeit.

Sonntag 2.0 – ein Mini-Barcamp zum Thema: Web 2.0 und Sicherheits-Aspekte

Am Sonntag den 25.05.2008  findet unser erstes Mini- Barcamp in München statt zum Thema: Web 2.0 und Sicherheits-Aspekte.  Mehr Informationen und kostenfreie Anmeldung unter: http://sonntag.mixxt.de/

Kommen kann übrigens jeder, der mit dem Thema zu tun hat. Und, die Veranstaltung ist natürlich kostenlos.

Die besten Entwickler Blogs als RSS Feed im dotnet-forum.de

14.05.2008 08:17:09 | Jan Welker

Für alle Besucher des dotnet-forum.de ist ab sofort ein neues Feature verfügbar: die Developer Blogs. Unter diesem Link http://dotnet-forum.de/DeveloperBlogs/ sind die 25 neuesten Beiträge der besten Entwickler Blogs verfügbar. Die Blogposts werden direkt per RSS Feed von den entsprechenden Entwickler-Blogs geholt.
Die zusammengestellten Inhalte können per RSS Feed abonniert werden.

Vorschläge für weitere Blogs nehme ich gern entgegen. Bedingung für die Aufnahme ist ein RSS oder Atom Feed dessen Inhalt sich mit der Entwicklung rund um .NET beschäftigt.

Du hast noch keinen Blog? Für Mitglieder des dotnet-forum.de können kostenlos leistungsfähige Blogs freigeschaltet werden. Bei Interesse reicht eine PN oder Email.

CommunityServer: A non zero-length string is required.

13.05.2008 21:32:01 | Jan Welker

Heute wollte ich den RSS Reader vom CommunityServer ausprobieren, leider bekam ich nur die übliche CommunityServer Fehlermeldung:  „Oops something went wrong!“.
Um die Ursache des Problems zu herauszubekommen, hab ich zuerst das Debugging in der Web.config aktiviert:

serverfehler

Der Fehler ist in der RSS.NET Dll aufgetreten, die vom CommunityServer verwendet wird. Genauer gesagt, im Konstruktor der Klasse RssChannel:

public RssChannel(string title, string description,
Uri link) { : if (description.Length == 0) { throw new ArgumentException("A
non zero-length string is required.", description); } : } 

Mit Lutz Röders Reflector habe ich in der CommunityServer.Reader.dll den passenden Aufruf gefunden:

RssChannel channel = new RssChannel(current.SiteSettings.SiteName
+ ", Folder: " + str, current.SiteSettings.SiteDescription, new Uri(current.CurrentUri.ToString().Replace("rss.ashx", "default.aspx"))); 

Es wurde in meinem Fall ein Leerstring an die RSS.NET DLL übergeben, weil ich in den Systemeinstellungen des CommunityServers keine Seitenbeschreibung eingegeben habe.

Abhilfe schafft also momentan nur das Eingeben einer Seitenbeschreibung.
Ich habe den Fehler an Telligent weitergegeben. Ich bin gespannt, ob der Fehler noch behoben wird, da seit kurzem die Version 2008 verfügbar ist.

Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions User Guide, Version 1.1

13.05.2008 21:00:00 | Ozgur Aytekin

Die Version 1.1 des "User Guide for the Visual Studio 2005 extensions for Windows SharePoint Services 3.0" wurde veröffentlicht.

Dieser Bedienungsanleitung beinhaltet folgende Themen:

  • Starting out in SharePoint Development
  • Walkthrough of the VSeWSS User Interface including the WSP View
  • The Team Site Project
  • The Blank Site Project
  • The List Definition Project
  • The Web Part Project
  • The Workflow Projects
  • Project Item Templates
  • Best Practices with VSeWSS
  • Changes from 1.0 to 1.1

Die URL für die Installationsdatei ist wie folgt: Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions User Guide, Version 1.1

Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta

13.05.2008 20:51:00 | Ozgur Aytekin

Microsoft hat die Public Beta 1 Version von Visual Studio 2008 und .NET Framework 3.5 Service Pack veröffentlicht.

Dieser Version soll nicht auf produktiven Maschinen installiert werden.

Wegen bekannten Installationsfehler, darf dieser Service Pack 1 Beta Version auf Vista Rechner mit Service Pack 1 installiert werden. Dieser Fehler wird in der Final-Version behoben sein, meldet ScottGu in seinem Blog.

Für weitere Informationen zum Thema "Wichtige Installations-Notizen" folgenden Blog-Eintrag lesen.

Important: SP1 Beta Installation Notes

Die wichtigsten Verbesserungen im Bereich Web Entwicklung sind:

  • ASP.NET Data Scaffolding Support (ASP.NET Dynamic Data
  • ASP.NET Routing Engine (System.Web.Routing)
  • ASP.NET AJAX Back/Forward Button History Support
  • ASP.NET AJAX Script Combining Support
  • Visual Studio 2008 Performance Improvements HTML Designer and HTML Source Editor
  • Visual Studio 2008 JavaScript Script Formatting and Code Preferences
  • Better Visual Studio Javascript Intellisense for Multiple Javascript/AJAX Frameworks
  • Visual Studio Refactoring Support for WCF Services in ASP.NET Projects
  • Visual Studio Support for Classic ASP Intellisense and Debugging
  • Visual Web Developer Express Edition support for Class Library and Web Application Projects

Im Bereich Client Entwicklung sind:

  • Application Startup and Working Set Performance Improvements
  • New .NET Framework Client Profile Setup Package
  • New .NET Framework Setup Bootstrapper for Client Applications
  • ClickOnce Client Application Deployment Improvements
  • Windows Forms Controls
  • WPF Performance Improvements
  • WPF Data Improvements
  • WPF Extensible Shader Effects
  • WPF Interoperability with Direct3D
  • VS 2008 for WPF Improvements

In dieser Version wird auch das ADO.NET Entity Framework and LINQ to Entities mitgeliefert.

Unter anderem im Bereich Daten sind folgende Verbesserungen vorhanden:

  • SQL 2008 Support
  • ADO.NET Entity Framework and LINQ to Entities
  • ADO.NET Data Services (formerly code-named "Astoria")

Auch für Team Foundation Server (TFS) kommen viele Verbesserungen mit. Für eine detailierte Information hat Brian Harry in sein Blog folgenden Artikel geschrieben: Team Foundation Server 2008 SP1 Preview

Die URLs für den Download findet ihr auf der folgende Seite: Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta

Für detaillierte Informationen kann ich euch folgende URLs empfehlen:

MSDN: Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta

ScottGu’s Blog: Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta

Brian Harry's WebLog:Team Foundation Server 2008 SP1 Preview

KB 946581 - Visual Studio 2008 - Hotfix

13.05.2008 19:41:00 | Ozgur Aytekin

Microsoft hat ein kumulatives Update für Microsoft Visual Studio 2008 und Microsoft Visual Web Developer 2008 zur Verfügung gestellt.

Dieser Hotfix ist nicht sehr neu, aber irgendwie wenig bekannt unter den Visual Studio 2008 Entwickler.

In diesem Hotfix sind unter anderem folgende Punkte verbessert:

  • Bugs in HTML Source View performance
  • Bug in Design view performance
  • Bugs in HTML editing
  • Bugs in JavaScript editing
  • Bugs in Web site building performance
  • Hotfix information

Weitere und detailierte Informationen findet ihr unter: A cumulative update for Visual Studio 2008 and Visual Web Developer Express 2008 is available

Die Datei findet ihr unter: Download

fmx & Silverlight

13.05.2008 17:29:00 | Lori Grosland

Vom 5. – 8. Mai fand in Stuttgart die 13. fmx Konferenz statt – Europas größte Konferenz zum Thema Animationen, Effekte, Games und Digital Media – veranstaltet von der Filmakademie Baden Württemberg. Microsoft war zum ersten Mal als einer der Hauptsponsoren mit einem großen Stand und einer Xbox-Lounge vertreten, an der sich die Besucher mit einer Tüte Popcorn bei Guitar Hero und anderen Xbox-Spielen vom Konferenzstress erholen konnten. Am Stand präsentierte Microsoft dem interessierten Publikum aus der Games-, Medien- und Designbranche neue Technologien wie  Microsoft Silverlight, Microsoft Popfly und Microsoft Live Labs Photosynth.

 

Ich war dabei und habe vor Ort mit Steffen Ritter, Microsoft Designer Marketing Manager über alles rund um die fmx und natürlich auch über sein Lieblings-Thema Silverlight gesprochen.  Auch zu sehen in diesem Video, ein paar coole Silverlight Demos, vorgestellt von Oliver Scheer, Microsoft Developer Evangelist.

 

Die Demos findet man auch hier:

http://silverlight.net/themes/silverlight/community/gallerydetail.aspx?cat=5
http://silverlight.idvsolutions.com/
http://memorabilia.hardrock.com/
http://www.bluerosegames.com/brg/games.aspx
http://home.comcast.net/~barney.ross/RubikCube/RubikCubeTestPage.html
http://silverlight.net/

Support für Daisy XML

13.05.2008 10:23:31 | Jens Häupel

Microsoft und DAISY Consortium stellen Software für barrierefreie Nutzung von Worddokumenten vor

Ungefähr 70 Prozent der weltweit verfügbaren Informationen liegen als Word-Dokument vor. Doch Menschen mit Sehbehinderung, Legasthenie oder einer körperlichen Behinderung haben nur eingeschränkten Zugang zu diesen Inhalten. Daher haben wir gemeinsam mit Partnern aus Industrie und Interessensgruppen im Rahmen eines Open Source-Projekts die Software „Save as DAISY XML“ entwickelt, die mit Microsoft Office Word erstellte Dokumente und Inhalte insbesondere für Menschen mit Behinderung leichter zugänglich und verwertbar macht. Ab sofort ist das Software Add-in „Save as DAISY XML“ für Microsoft Office Word 2007, 2003 und XP kostenlos verfügbar. Es ermöglicht, Office Open XML basierte Textdateien in das Digital Accessible Information System (DAISY) Format, das weltweit am häufigsten genutzte Standard Format für Menschen mit Sehbehinderung, umzuwandeln.

Das "Save as DAISY Add-in" ist in einem Open Source-Projekt gemeinsam mit Microsoft, Sonata Ltd. und dem DAISY Consortium entwickelt worden und kostenlos unter http://www.openxmlcommunity.org/daisy herunterzuladen.

Gleichzeitig zum Add-in ist auch die neueste Version der Konvertierungssoftware aus dem DAISY Pipeline-Projekt verfügbar. Diese verschiedenen Konvertierungswerkzeuge, die mit Unterstützung von Software zur synthetischen Erzeugung von Sprache die nahtlose Überführung von DAISY XML in das DAISY Digital Talking Book (DTB)-Format ermöglichen, können kostenlos heruntergeladen werden (http://www.daisy.org/projects/pipeline).

Microsoft Expression Studio 2 ist hier...

11.05.2008 22:12:00 | Ozgur Aytekin

Die englische Version des Microsoft Expression 2 Tools ist veröffentlicht.

Die Trial Versionen können unter folgende URL heruntergeladen werden: Try Expression Products

Wer die Microsoft Expression 1 Produkte zwischen 24.02.2008 und 01.06.2008 gekauft hat, ist für einen Gratis (Free) Upgrade des gleichen Produktes berechtigt. Die detailierte Informationen findet ihr unter folgende URL: Upgrade Eligibility

Microsoft SQL Server 2008 CTP Unterstützung für Visual Studio 2005 und Visual Studio 2008

11.05.2008 21:23:00 | Ozgur Aytekin

SQL Server 2008 CTP Unterstützung für Visual Studio 2005 kann unter folgende URL heruntergeladen werden: Visual Studio 2005 Support for SQL Server 2008 CTP

Für die Einschränkungen und bekannte Fehler (Known Issues) bitte die Informationen auf der Downlad-Seite lesen.

SQL Server 2008 CTP Unterstützung für Visual Studio 2008 kann unter folgende URL heruntergeladen werden: Visual Studio 2008 Support for SQL Server 2008 CTP

Leider Unterstützt dieser Version den LINQ to SQL Designer mit SQL Server 2008 noch nicht.

Auch bei dieser Download, für die Einschränkungen und bekannte Fehler (Known Issues) bitte die Informationen auf der Download-Seite lesen.

Für Allgemeine Informationen über die SQL Server 2008 CTP Unterstützung kann ich Euch folgende Seite empfehlen: Connecting to Microsoft SQL Server 2008 from Microsoft Visual Studio 2005 and 2008

KB 951937 – Funktionalitätsproblem mit ActiveX Data Objects (ADO)

11.05.2008 17:18:00 | Ozgur Aytekin

Für Entwickler, die für Windows Vista, Windows Server 2008 oder Windows XP Anwendungen entwickeln und die ActiveX Data Objects (ADO)-Schnittstelle mit SQL Server 2000 oder SQL Server 2005 einsetzen kann folgender KB Artikel mit der Nummer 951937 von Microsoft interessant sein: "On a computer that is running Windows Vista, Windows Server 2008, or Windows XP, an incorrect value is returned when an application queries the identity column value of a newly inserted row in various versions of SQL Server 2005 and of SQL Server 2000"

Weitere Informationen findet ihr unter folgende URL: KB 951937

Die let-Klausel (clause) in LINQ

11.05.2008 15:01:00 | Ozgur Aytekin

Für die Erstellung einer temporären Variable innerhalb einer Query Expression kann das Schlüsselwort let verwendet werden. Mithilfe einer Formel wird an diese Variable ein neuer Wert aus bestehenden Daten zugewiesen. Die Variable ist dann innerhalb der Query Expression weiterverwendet und bei Bedarf im Select-Block ausgegeben werden.

Die Lesbarkeit des Codes wird durch die Verwendung von Schlüsselwort let gesteigert und der Code bleibt übersichtlich.

In dem folgenden Beispiel werden mithilfe des let-Schlüsselwortes zwei Variablen (DistributorPrice und ProductColorIsBlack) erstellt.

Die Variable DistributorPrice beinhaltet den Wert des Händlerpreises. Dieser Preis wird mithilfe des Faktors 0.75 vom Listenpreis berechnet.
let DistributorPrice = (p.ListPrice*Convert.ToDecimal(0.75))

Die Variable ProductColorIsBlack beinhaltet den Wert, ob die Produktfarbe Schwarz ist.
let ProductColorIsBlack = (p.Color != null && p.Color == "Black")                   

Innerhalb des Select-Blocks werden die beiden Variablen ausgegeben.
select new
{
   ProductCategoryName = pc.Name,
   ProductSubCategoryName = psc.Name,
   ProductName = p.Name,
   p.ListPrice,
   DistributorPrice,
   ProductColorIsBlack
};

Der gesamte Beispiel Code ist wie folgt aufgelistet:



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->using System;
using System.Linq;

namespace LinqLetSample0001
{
internal class Program
{
private static void Main(string[] args)
{
var db
= new AdventureWorksDataContext();

var qry
= from pc in db.ProductCategories
join psc
in db.ProductSubcategories on pc.ProductCategoryID equals psc.ProductCategoryID
join p
in db.Products on psc.ProductSubcategoryID equals p.ProductSubcategoryID
let DistributorPrice
= (p.ListPrice * Convert.ToDecimal(0.75))
let ProductColorIsBlack
= (p.Color != null && p.Color == "Black")
select
new
{
ProductCategoryName
= pc.Name,
ProductSubCategoryName
= psc.Name,
ProductName
= p.Name,
p.ListPrice,
DistributorPrice,
ProductColorIsBlack
};

foreach (var item in qry)
{
Console.WriteLine(
"Product Category : " + item.ProductCategoryName);
Console.WriteLine(
"Product Sub Category : " + item.ProductCategoryName);
Console.WriteLine(
"Product : " + item.ProductName);
Console.WriteLine(
"Product Distributor Price: " + item.DistributorPrice);
Console.WriteLine(
"Product List Price : " + item.ListPrice);
Console.WriteLine(
"Product Color is Black : " + item.ProductColorIsBlack);
Console.WriteLine();
}

Console.ReadLine();
}
}
}


Das komplette Visual Studio 2008 Projekt kann unter folgende URL heruntergeladen werden: LinqLetSample0001.zip






 


Simples Text Captcha mit ASP.NET

11.05.2008 01:56:00 | Peter Bucher

Es gibt viele Captcha Controls im Web zu finden.
Trotzdem möchte ich hier eine einfache Variante vorstellen.
Diese Variante benutzt ein Label, um eine Rechnung darzustellen, bspw. "5 + 6 =".
Eine Textbox fürs Resultat, ein Button und ein Statuslabel wir im Beispiel verwendet.

Ich benutze einen ähnlichen Code auf http://www.peterbucher.ch/, bis jetzt habe ich noch nie Spam bekommen :)

Viel Spass damit...

ASPX Code:

<h1>SimpleCaptcha</h1>
<asp:Label ID="lblCaptcha" AssociatedControlID="txtCaptcha" runat="server" />
<asp:TextBox ID="txtCaptcha" runat="server" />
<asp:Button ID="btnSubmit" Text="Abschicken" runat="server" />
<asp:Label ID="lblStatus" runat="server" />

Codebehind:

using System;
using System.Drawing;


namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e) {
            // Textbox Inhalt zuweisen
            // Resultat in die Session Speichern
            if(!this.IsPostBack) {
                Random r = new Random();
                int num1   = r.Next(1, 15);
                int num2   = r.Next(1, 15);

                this.lblCaptcha.Text = string.Format("{0} + {1} =",
                                                     num1.ToString(),
                                                     num2.ToString());

                this.Session["captcha"] = num1 + num2;
            } else {
                // Status anzeigen
                if(this.ValidateCaptcha()) {
                    this.lblStatus.Text         = "Eingabe korrekt";
                    this.lblStatus.ForeColor = Color.Green;
                } else {
                    this.lblStatus.Text         = "Eingaben fehlerhaft";
                    this.lblStatus.ForeColor = Color.Red;
                }
            }
        }

        /// <summary>
        /// Validiert die Eingabe
        /// </summary>
        /// <returns>true / false - Eingabe richtig oder falsch</returns>
        protected bool ValidateCaptcha() {
            object session = this.Session["captcha"];
            object input     = this.txtCaptcha.Text;

            if(session != null && input != null) {
                int s, i;
                return (int.TryParse(session.ToString(), out s)
                        &&
                        int.TryParse(input.ToString(), out i)
                        && s.Equals(i));
            }

            return false;
        }
    }
}

Beispielprojekt zum Download:

Der Trend geht zum zweit-iPod

09.05.2008 18:54:15 | Oliver Guhr

…zumindest wenn es nach Amazon geht. Als ich heute mal wieder beim Internet Gemischtwarenladen vorbeischaute war ich erstaunt amüsiert was mir am neuen Produkten empfohlen wurde. Das solche automatischen Produktvorschläge fast nie sinnvolle Ergebnisse liefern ist ja bekannt, bei Amazon kann man sich sogar anschauen warum der Artikel vorgeschlagen wurde:

amazon

Weil ich einen iPod + Tasche erstanden habe könnte mir der 80 GB iPod auch gefallen - tut er auch, kaufen werde ich ihn aber nicht.

VSTO 3.0 Add-Ins für alle User installieren

09.05.2008 16:20:10 | Jens Häupel

Das Office 2007 Security Modell erlaubt es nicht, unter HKLM registrierte Managed Add-Ins zu verwenden. Was nicht heißt, dass mit einem Trick das Ganze nicht dennoch erreicht werden kann. Misha Shneerson, Senior Software Design Engineer im Microsoft BizApps Team, hat die notwendigen Aspekte in seinem Blog (Teil 1, Teil 2, Teil 3) beschrieben. Ich will mir hier die Zeit nehmen und das Ganze etwas erläutern.

Die Basis ist ein Registry-Replikations-Mechanismus von Office, durch welchen bestimmte Einträge von HKLM nach HKCU repliziert werden, wenn eine der Office Anwendungen gestartet wird.

Definiert werden diese Einträge unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\User Settings mittels eines Create bzw. Delete Keys.

Ein Beispiel:

Ein Add-In für Excel 2007 wird hier registriert (ich gehe davon aus, dass die Manifests digital signiert wurden und eine Trust Chain auf der Zielmaschine existiert (siehe hier):

   HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\MyAddIn

Die erforderlichen Einträge wären:

Name   Type    Value   
Description REG_SZ Ein Add-In für Excel ...
FriendlyName REG_SZ MyAddIn
LoadBehavior DWORD 3
Manifest REG_SZ C:\\Program Files\\MyCompany\\MyAddin.vsto|vstolocal

Um jeden an der Maschine angemeldeten Benutzer in den Genuß des Add-Ins kommen zu lassen, wird dieser Pfad im Prinzip auf die UserSettings von Office 2007 in HKLM "kopiert". Der gesamte Pfad würde dann so aussehen:

HKEY_LOCAL_MACHINE
   SOFTWARE
      Microsoft
         Office
            12.0
               User Settings
                 MyCompany.MyAddIn
                     Create
                        Software
                           Microsoft
                              Office
                                 Excel
                                    Addins
                                       MyAddIn

Unter MyAddIn stehen dann die in der o.g. Tabelle angegebenen Werte.

Nicht genug

Das reicht aber noch nicht. Repliziert wird der Pfad nur, wenn eine vorhandene Count Property (DWORD) auf dem im obigen Pfad fett formatierten Key (MyCompany.MyAddIn) gefunden wird und deren Wert vom Wert derselben im Ziel-Hive der Registry (HKCU) abweicht.

OfficeRegReplication

Der Wert am Zielort wird unter HKCU\Software\Microsoft\Office\12.0\User Settings\MyAddIn geführt. Das wird getan, um nicht bei jedem Start die Replikation durchzuführen, sondern nur bei Änderungen. Deshalb muß auch diese Count Property nach dem Deinstallieren erhalten bleiben. Am besten. man zählt bei jeder Änderung per Custom Action den Wert um eins hoch. Der Wertebereich eines DWords sollte für einige Zeit ausreichen.

Da die Installation mittels MSI stattfinden sollte, müssen einige Dinge beachtet werden:

  1. Der unter Manifest angegebene Pfad muß so aussehen: [TARGETDIR]MyAddin.vsto|vstolocal
    Der MSI setzt den ausgewählten Zielpfad automatisch ein.
  2. Der Create Key muß mit dem Flag DeleteAtUninstall versehen sein, damit er wieder entfernt wird.
  3. Beim Deinstallieren muß ein Delete Subkey geschrieben werden, der dafür sorgt, daß beim nächsten Start der Hostapplikation die Registrierung des Add-Ins aufgehoben wird. Der sieht vom Aufbau her genauso aus wie der Create Key. Allerdings - da dieser in der Registry verbleibt - muß beim erneuten Installieren ein evtl. vorhandener Delete Key gelöscht werden.
  4. Und natürlich muß beim Installieren wie auch beim Deinstallieren die Count Property erzeugt bzw. hochgezählt werden.

Im anfangs referenzierten Blog findet sich der Code für diese Aktionen. Das klingt kompliziert, aber man muß sich vor Augen halten, daß hier per User und per Machine Aktionen koodiniert werden müssen und der Sicherheitsmechanismus von VSTO der von ClickOnce ist - einer Technologie, die per User funktioniert.

Natürlich kann man das auch auf Basis der Inclusion List tun, Misha Shneerson erklärt das in Teil 3. Das sollte aber nur bei nichtverwalteten Netzwerken getan werden, da die zu erwartende Sicherheit geringer ist.

Visual Studio Extensibility Event am 26 Mai

09.05.2008 16:15:53 | Christian Binder

wer einen Überblick zu den Erweiterungsmöglichkeiten von Visual Studio sucht, sollte sich dieses Event nicht entgehen lassen. Bauen Sie z.B. Ihre Application auf Basis der Visual Studio Shell.
Inhaltlich werden folgende Themen von Ken Levy, Program Manager Visual Studio, behandelt:

  • Visual Studio Shell
  • Visual Studio SDK
  • Erweiterung von Visual Studio wie
    • Packages,
    • Add-Ins,
    • Makros und
    • Visualizer

    Anmeldung hier 

    Hinweis: Die Veranstalltung ist in Englischer Sprache und es gibt maximal 20 Plätze.

    Chris

    XNA Game Studio 3.0 CTP: Endlich VS 2008 & .NET 3.5

    08.05.2008 23:46:32 | Robert Mühsig

    image

    Für alle die, die sich für “Spieleentwicklung” interessieren gibt es nun ein neu Version (CTP) vom XNA Game Studio:

    Es integriert sich in Visual Studio 2008 - von der Express bis zu den Prof. und bietet .NET 3.5 Unterstützung.

    Hier die komplette Ankündigung von Microsoft und der Download Link.

    TDD, Unit-Tests & XNA \o/ :)

    Wer ist unter uns oder whos.amung.us

    08.05.2008 14:30:12 | Oliver Guhr

    Durch einfaches einbinden eines kleinen Buttons von whos.amung.us kann man sehen wer gerade den eigenen Blog durchstöbert und wo die Leute so herkommen. Zur auswahl gibts schicke Karten, z.b.

    Besucherkarte

    Besucherkarte

    Die Aktuellen Karten für code-inside.de kann man hier finden, der Button auf code-inside ist rechts oben unter “Counter”.

    Meine Vorträge demnächst zu Silverlight

    06.05.2008 19:00:32 | Mario Meir-Huber

    In nächster Zeit bin ich viel unterwegs und werde den einen oder anderen Vortrag zum Thema Silverlight halten. Der erste wird am 27. Mai in Linz, Oberösterreich sein. Dort geht es vor allem um die Neuerungen im Bereich Silverlight 2.0.

    Eine genauere Beschreibung ist auf der Usergroup Seite vorhanden: http://usergroups.at/blogs/netlinz/default.aspx

    Im Juni bin ich dann in Burghausen auf der Asp.Net Konferenz, wo ich 3 Vorträge zum Thema Silverlight halten werde. Diese sind:

    - Silverlight auf mobilen Geräten

    - Silverlight am Sharepoint Portal Server

    - ChartLibrary für Silverlight

     

    Infos gibt es hierfür unter: http://www.asp-konferenz.de

    Ribbon Controls mit best. Control IDs können nicht deaktiviert werden

    06.05.2008 16:29:10 | Jens Häupel

    In der Liste der Control Ids sind die Namen der eingebauten Controls zu finden. Offensichtlich haben sich einige der Controls - so wie das bei Menschen auch hin und wieder üblich ist - einen zweiten Namen zugelegt. Das führt zu Unstimmigkeiten, die dazu führen, dass einige der eingebauten Controls nicht deaktiviert werden können, wenn der erste Name (auch im Anpassen Dialog der Quick Access Toolbar angezeigt) verwendet wird. Für ein simples Anzeigen der Controls und Verwenden der eingebauten Funktionalität kann auch weiterhin dieser erste Name verwendet werden.

    In der nachfolgenden Tabelle finden Sie unter Control ID for Disabling den korrekten Namen des Controls zum Deaktivieren.

    ControlId Bugs

    Somit kann mit folgenden Snippet verhindert werden, dass z.B. die Gridlines ein- bzw. ausgeschaltet werden können:

    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load">
      <commands>
        <command idMso="ViewSheetGridlines" enabled="false"/>
      </commands>
    </customUI>

    oder

    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load">
      <commands>
        <command idMso="SplitCells" getEnabled="GetSplitCellsEnabled"/>
      </commands>
    </customUI>

    Live Übertragung des Treffen der .net user group Köln am 6. Mai 2008 (heute)

    06.05.2008 15:25:06 | Albert Weinert

    Hallo zusammen,

    die .net user group Köln plant heute Abend ein experiment. Wir wollen unser Usertreffen live im Internet streamen. So dass auch die Leute die nicht um Köln herum wohnen die Möglichkeit haben daran teilzunehmen.

    Die Sende-Adresse ab 19 Uhr ist

    http://www.mogulus.com/dnugkoeln

    Wir wissen noch nicht ob und wie es klappt (Bandbreite, Licht etc.), also  erscheint ruhig zahlreich und tragt bitte einen ordentlichen Nickname für den Chat ein.

    Die Themen heute sind

    Final Builder 6
    Robert Wachtel

    Final Builder ist ein Build-Werkzeug mit dem man seine Software-Builds automatisieren kann. Von einfacher Automatisierung bis zum CI-Server ist alles damit machbar. Sowohl auf dem Client als auch dem Server. Robert Wachtel gibt einen Überblick über die Möglichkeiten.

    ADO.NET „Astoria“ Data Services
    Albert Weinert


    Mit .NET 3.5 Service Pack 1 kommen die ADO.NET Data Services in das .NET Framework, aktuell gibt es sie als Preview zum runterladen und ausprobieren. Mit den Data Services wird eine REST basierte Schnittzustelle zu beliebigen Daten ermöglicht. Damit werden über das HTTP Protokoll Daten für JavaScript, Silverlight und Fat-Client Anwendungen ermöglicht. CRUD-Operationen sind natürlich auch möglich.

    http://www.dnug-koeln.de

     

    Wöchentliche Rundablage: ASP.NET MVC, Live Mesh, Silverlight, .NET…

    05.05.2008 22:22:53 | Robert Mühsig

    ASP.NET MVC:

    Live Mesh:

    .NET Framework:

    WPF / Silverlight:

    UI / Design:

    LINQ:

    Virtual Earth:

    Other:

    Software-Tipp: Microsoft SharedView - "Welchen Knopf muss ich denn drücken?"

    05.05.2008 20:47:27 | Robert Mühsig

    Die Frage “Welchen Knopf muss ich denn drücken?” oder ähnliche sind meist recht schwer zu beantworten. Ferndiagnosen sind meist recht schwer zu bewältigen.

    Seit einer Weile hat Microsoft ein nettes Tool - ganz ohne jeden großen Rummel - veröffentlicht: SharedView.

    image

    SharedView erlaubt es einfach den Desktop zu teilen oder nur eine einzelne Applikation mit bis zu 15 Leuten. Das ganze läuft auf Port 80 - daher ist keine Portfreischaltung notwendig.

    Einmal installiert (mit Adminrechten) muss man sich mit seiner Windows Live ID anmelden und kann eine Session aufbauen oder einer Session beitreten.

    Um mal der Freundin zu helfen ist es genial ;)

    jQuery… ein paar Links

    05.05.2008 20:14:08 | Robert Mühsig

    Da ASP.NET AJAX und ASP.NET MVC (noch?) nicht so richtig gut zusammenpassen muss ganz klar eine andere Javascript Bibliothek und AJAX Framework her - jQuery hat es mir angetan.

    Der Blogpost ist eher eine Zusammenfassung von den Links die ich in den letzten Rundablagen bereits nebenbei gebloggt hab.

    Was gibt es denn sonst noch für Javascript-Bibliotheken?

    Danny Douglass hat einen netten Vergleich zwischen jQuery, YUI, Prototype, Dojo, MooTools, Ext JS, und Script.aculo.us gemacht. Eine nette Auflistung der Merkmale findet man hier.

    jQuery Beispiele und Tutorials?

    Auf noupe.com gefunden:

    Drag`n`Drop gibts auch:

    Es gibt noch mehr tolle Beispiele (siehe links oben), eine aktuelle offline Dokumentation hab ich zwar noch nicht gefunden, aber für die Version 1.1.4 gibt es hier eine.

    Jeder braucht Plugins… jQuery hat einige:

    Auf noupe.com gefunden:

    VS 2008 / ASP.NET Integration:

    Wer noch mehr brauchbare Links kennt, einfach kurz melden :)

    TechTalk einmal anders

    05.05.2008 10:13:03 | Jens Häupel

    Meine Kollegen Lori Grosland und Dirk Primbs gehen im Juni auf TechTalk Tour zum Thema

     

    Technologieperlen unter der Haube

    In diesem TechTalk halten wir es analog zu einer beliebten Süssigkeit: Spass, Spannung und Schokolade...

    Das bedeutet:

    - Spass, wenn wir Ihnen Tools und Technologien wie Deep Zoom, die Live APIs oder auch das eine oder andere Research Projekt vorstellen.

    - Spannung, wenn wir der Frage nachgehen, wie die Technik darunter funktioniert und

    - Schokolade, wenn wir hands on zeigen, wie Sie diese Lösungen in eigenen Applikationen einsetzen.

     

    Anmeldung und Infos gibt’s unter http://www.microsoft.com/germany/msdn/techtalk/default.mspx

     

    Termine:

    02.06 - Karlsruhe

    03.06 - Köln

    05.06 - Berlin

    10.06 - München

    11.06 – Hamburg

    Übersicht der DateTime-Datentypen in SQL Server 2008

    04.05.2008 17:24:00 | Ozgur Aytekin

    Der folgende Artikel gibt einen Übersicht über die DateTime-Datentypen in SQL Server 2008. Auch die neuen Datentypen wie DATE, DATETIME2, DATETIMEOFFSET, und TIME sind in diesem Artikel beschrieben.

    DATE - NEU

    Der Datentyp DATE speichert Datumswert ohne Zeit Informationen.

    Der Bereich für diesen Datentyp liegt zwischen 0001-01-01 - 9999-12-31 (Jahr - Monat -Tag).

    Der Speicherbedarf liegt bei 3 bytes.



    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- DATE --------------------------------------
    2 -- Format : Jahr - Monat - Tag
    3 -- Year - Month - Day
    4
    5 -- Range : 0001-01-01 - 9999-12-31
    6 -- Storage Size : 3 bytes
    7 -- Default value: 1900-01-01
    8 ----------------------------------------------
    9
    10 -- Beispiel-Code -----------------------------
    11 DECLARE @Date_DataType DATE
    12 SET @Date_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @Date_DataType
    16 ----------------------------------------------
    17
    18 -- Resultat ----------------------------------
    19 -- SYSDATETIME() : 2008-05-04 16:54:59.0370304
    20 -- @Date_DataType: 2008-05-04
    21 ----------------------------------------------
    22


    DATETIME



    Der Datentyp DATETIME speichert Datum und Zeit Informationen.



    Der Bereich für diesen Datentyp liegt zwischen 1753-01-01 00:00:00 - 9999-12-31 23:59:59.997 (Jahr - Monat - Tag Stunden : Minuten : Sekunden .Sekundenbruchteile).



    Die Genauigkeit der Sekundenbruchteile kann bei diesem Datentyp nicht festgelegt werden.



    Der Speicherbedarf liegt bei 8 bytes.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- DATETIME --------------------------------------------------------------------------
    2 -- Format : Jahr - Monat - Tag Stunden : Minuten : Sekunden .Sekundenbruchteile
    3 -- Year - Month - Day Hours : Minutes : Seconds .Fractional Seconds
    4
    5 -- Range : 1753-01-01 00:00:00 - 9999-12-31 23:59:59.997
    6 -- Storage Size : 8 bytes
    7 -- Default value: 1900-01-01 00:00:00
    8 ---------------------------------------------------------------------------------------
    9
    10 -- Beispiel-Code ----------------------------------------------------------------------
    11 DECLARE @DateTime_DataType DATETIME
    12 SET @DateTime_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @DateTime_DataType
    16 ---------------------------------------------------------------------------------------
    17
    18 -- Resultat ---------------------------------------------------------------------------
    19 -- SYSDATETIME() : 2008-05-04 16:29:41.1544224
    20 -- @DateTime_DataType: 2008-05-04 16:51
    21 ---------------------------------------------------------------------------------------
    22


    DATETIME2 - NEU



    Als Erweiterung des Datentyps DATETIME, speichert DATETIME2 einen größeren Datumsbereich und eine größere Genauigkeit beim Sekundenbruchteil.



    Der Bereich für diesen Datentyp liegt zwischen 0001-01-01 00:00:00 - 9999-12-31 23:59:59.9999999 (Jahr - Monat - Tag Stunden : Minuten : Sekunden [.Sekundenbruchteile]).



    Die Genauigkeit der Sekundenbruchteile kann beim Deklarieren der Variable festgelegt werden, welches zwischen 0 und 7 sein kann.



    Der Speicherbedarf liegt bei 8 bytes.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- DATETIME2 ---------------------------------------------------------------------------
    2 -- Format : Jahr - Monat - Tag Stunden : Minuten : Sekunden [.Sekundenbruchteile]
    3 -- Year - Month - Day Hours : Minutes : Seconds [.Fractional Seconds]
    4
    5 -- Range : 0001-01-01 00:00:00 - 9999-12-31 23:59:59.9999999
    6 -- Storage Size : 8 bytes
    7 -- Default value: 1900-01-01 00:00:00
    8 ----------------------------------------------------------------------------------------
    9
    10 -- Beispiel-Code -----------------------------------------------------------------------
    11 DECLARE @DateTime2_DataType DATETIME2(7)
    12 SET @DateTime2_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @DateTime2_DataType
    16 ----------------------------------------------------------------------------------------
    17
    18 -- Resultat ----------------------------------------------------------------------------
    19 -- SYSDATETIME() : 2008-05-04 16:22:33.6997728
    20 -- @DateTime2_DataType: 2008-05-04 16:22:33.6997728
    21 ----------------------------------------------------------------------------------------
    22


    DATETIMEOFFSET - NEU



    Der Datentyp DATETIMEOFFSET speichert zusätzlich zu den Datumsangaben mit Zeit Informationen auch die Zeitzonen Information.



    Der Bereich für diesen Datentyp liegt zwischen 0001-01-01 00:00:00 - 9999-12-31 23:59:59.9999999 (Jahr - Monat - Tag Stunden : Minuten : Sekunden [.Sekundenbruchteile] [+|- Stunden : Minuten]).



    Die Genauigkeit der Sekundenbruchteile kann beim Deklarieren der Variable festgelegt werden, welches zwischen 0 und 7 sein kann.



    Der Speicherbedarf liegt bei 10 bytes.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- DATETIMEOFFSET -----------------------------------------------------------------------------------------------
    2 -- Format : Jahr - Monat - Tag Stunden : Minuten : Sekunden [.Sekundenbruchteile] [+|- Stunden : Minuten]
    3 -- Year - Month - Day Hours : Minutes : Seconds [.Fractional Seconds] [+|- Hours : Minutes]
    4
    5 -- Range : 0001-01-01 00:00:00 - 9999-12-31 23:59:59.9999999
    6 -- Storage Size : 10 bytes
    7 -- Default value: 1900-01-01 00:00:00 00:00
    8 -----------------------------------------------------------------------------------------------------------------
    9
    10 -- Beispiel-Code ------------------------------------------------------------------------------------------------
    11 DECLARE @DateTimeOffset_DataType DATETIMEOFFSET(7)
    12 SET @DateTimeOffset_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @DateTimeOffset_DataType
    16 -----------------------------------------------------------------------------------------------------------------
    17
    18 -- Resultat -----------------------------------------------------------------------------------------------------
    19 -- SYSDATETIME() : 2008-05-04 13:59:59.9918208
    20 -- @DateTimeOffset_DataType: 2008-05-04 13:59:59.9918208 +00:00
    21 -----------------------------------------------------------------------------------------------------------------
    22


    Für die manueller Zuweisung eines Wertes muss ein spezielles Format eingehalten werden. In diesem Format sind die Datumsangaben von den Zeitangaben mit dem Buchstaben „T“ voneinander getrennt. Die Angabe der Zeitzone erfolgt nach Sekundenbruchteile und beginnt mit einem „+“ oder „-„.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- Beispiel-Code ------------------------------------------------------------------------------------------------
    2 SET @DateTimeOffset_DataType = '2008-05-04T13:59:59.9918208+00:00'
    3
    4 PRINT @DateTimeOffset_DataType
    5 -----------------------------------------------------------------------------------------------------------------
    6
    7 -- Resultat -----------------------------------------------------------------------------------------------------
    8 -- @DateTimeOffset_DataType: 2008-05-04 13:59:59.9918208 +00:00
    9 -----------------------------------------------------------------------------------------------------------------
    10


    Der Format des DATETIMEOFFSET Datentyps entspricht dem ISO 8601.



    ISO 8601 ist ein internationaler Standard der ISO, der numerische Datumsformate und Zeitangaben beschreibt und Empfehlungen für den Gebrauch im internationalen Kontext ausspricht. Der Titel der Norm ist Data elements and interchange formats -- Information interchange -- Representation of dates and times, was im deutschen „Datenelemente und Austauschformate; Informationsaustausch; Darstellung von Datum und Uhrzeit“ bedeutet.



    Quelle: Wikipedia



     



    SMALLDATETIME



    Der Datentyp SMALLDATETIME speichert Datumsangaben mit Zeit Information im 24-Stunden-Format ohne Sekundenbruchteile.



    Der Bereich für diesen Datentyp liegt zwischen 1900-01-01 00:00:00 - 2079-06-06 23:59:59 (Jahr - Monat - Tag Stunden - Minuten – Sekunden).





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- SMALLDATETIME -------------------------------------------------
    2 -- Format : Jahr - Monat - Tag Stunden : Minuten : Sekunden
    3 -- Year - Month - Day Hours : Minutes : Seconds
    4
    5 -- Range : 1900-01-01 00:00:00 - 2079-06-06 23:59:59
    6 -- Storage Size : 4 bytes
    7 -- Default value: 1900-01-01 00:00:00
    8 -----------------------------------------------------------------
    9
    10 -- Beispiel-Code ------------------------------------------------
    11 DECLARE @SmallDateTime_DataType SMALLDATETIME
    12 SET @SmallDateTime_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @SmallDateTime_DataType
    16 -----------------------------------------------------------------
    17
    18 -- Resultat -----------------------------------------------------
    19 -- SYSDATETIME() : 2008-05-04 13:30:56.9855008
    20 -- @SmallDateTime_DataType: 2008-05-04 13:31
    21 -----------------------------------------------------------------
    22


    Die Minuten werden aufgerundet, wenn die Sekunden größer sind als 29.



     



    TIME - NEU



    Der Datentyp TIME speichert die Zeit ohne Datumsangaben im 24-Stunden-Format.



    Der Bereich für diesen Datentyp liegt zwischen 00:00:00.0000000 und 23:59:59.9999999 (Stunden : Minuten : Sekunden [.Sekundenbruchteile]).



    Die Genauigkeit der Sekundenbruchteile kann beim Deklarieren der Variable festgelegt werden, welches zwischen 0 und 7 sein kann.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 -- TIME -----------------------------------------------------------
    2 -- Format : Stunden : Minuten : Sekunden . Sekundenbruchteile
    3 -- Hours : Minutes : Seconds . Fractional Seconds
    4
    5 -- Range : 00:00:00.0000000 - 23:59:59.9999999
    6 -- Storage Size : 3 - 5 bytes
    7 -- Default value: 00:00:00
    8 -------------------------------------------------------------------
    9
    10 -- Beispiel-Code --------------------------------------------------
    11 DECLARE @Time_DataType TIME(7)
    12 SET @Time_DataType = SYSDATETIME()
    13
    14 PRINT SYSDATETIME()
    15 PRINT @Time_DataType
    16 -------------------------------------------------------------------
    17
    18 -- Resultat -------------------------------------------------------
    19 -- SYSDATETIME() : 2008-05-04 13:00:15.0369088
    20 -- @Time_DataType: 13:00:15.0369088
    21 -------------------------------------------------------------------
    22


    Die Beispieldatei findet Ihr unter: DateTime_DataTypes_Sample_0001.sql

    Microsoft SQL Server Product Samples

    04.05.2008 08:29:00 | Ozgur Aytekin

    Unter folgende URL findet Ihr die Beispiel Datenbanken für den Microsoft SQL Server 2008:

    Datenbanken -(Databases)

     

    Die folgende Seite bietet diverse Beispiele zu den Themen:

    - Microsoft Product Samples

    - Sample Databases

    - End to End (multi-technology, complete, integrated)

    - Microsoft SQL Server Analysis Services

    - Microsoft SQL Server Database Engine

    - Microsoft SQL Server Integration Services

    - Microsoft SQL Server Reporting Services

    - Platform Tools & Utilities

    - Forums & Answers

    Microsoft SQL Server Community & Samples

    UNION und UNION ALL

    03.05.2008 23:45:00 | Ozgur Aytekin

    UNION Statement unterdrückt wie bei einem SELECT DISTINCT die doppelten Einträge im Resultat. Von den mehrfach vorkommenden Datensätzen wird nur ein Datensatz im Resultat zurückgegeben.

    Für die Verwendung von UNION und UNION ALL Statements werden mindestens zwei Datenquellen benötigt. Die beiden Datenquellen müssen gleicher Anzahl Spalten (Columns) besitzen. Jeder einzelnen Spalte in der Tabelle 1 muss in der Tabelle 2 mit gleichem Datentyp (data type) vorkommen.

    Für die Verwendung von UNION und UNION ALL Statements werden mindestens zwei Datenquellen benötigt. Die ausgewählten Spalten (Columns) der beiden Datenquellen müssen in gleicher Anzahl vorkommen. Auch die Datentypen (data types) dieser Spalten müssen vom selben Typ sein.

    Im Resultat werden als Spaltennamen die Spaltennamen der ersten Datenquelle verwendet.

    UNION ALL Statement liefert alle Datensätze aus beiden Datenquellen als Resultat zurück. Hier werden die doppelten Einträge nicht unterdrückt und sie werden als ein des Resultates zurückgegeben. Für die Verwendung von UNION ALL Statement gelten die gleichen Bedingungen für die Datenquellen wie beim UNION-Statement.

    Für das Beispiel werden zwei Tabellen mit dem Namen CountryCity und CountryCapital erstellt.



    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1
    2 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CountryCity]') AND type in (N'U'))
    3 DROP TABLE [dbo].[CountryCity]
    4 GO
    5
    6 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CountryCapital]') AND type in (N'U'))
    7 DROP TABLE [dbo].[CountryCapital]
    8 GO
    9
    10 CREATE TABLE [dbo].[CountryCity]([ID] [int] NOT NULL,
    11 [Country] [nvarchar] (50) NOT NULL,
    12 [City] [nvarchar] (50) NOT NULL)
    13
    14 CREATE TABLE [dbo].[CountryCapital]([ID] [int] NOT NULL,
    15 [Country] [nvarchar] (50) NOT NULL,
    16 [City] [nvarchar] (50) NOT NULL)
    17
    18




    In der Tabelle CountryCity befinden die Länder und Städte.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (1, 'SWITZERLAND', 'ZURICH')
    2 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (2, 'SWITZERLAND', 'BERN')
    3 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (3, 'SWITZERLAND', 'GENEVA')
    4 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (4, 'GERMANY', 'BERLIN')
    5 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (5, 'GERMANY', 'HAMBURG')
    6 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (6, 'GERMANY', 'MUNICH')
    7 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (7, 'AUSTRIA', 'VIENNA')
    8 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (8, 'AUSTRIA', 'GRAZ')
    9 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (9, 'AUSTRIA', 'LINZ')
    10 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (10, 'TURKIYE', 'ISTANBUL')
    11 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (11, 'TURKIYE', 'ANKARA')
    12 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (12, 'TURKIYE', 'IZMIR')


    Die Tabelle CountryCapital beinhaltet die Länder und die Hauptstadt des Landes.







    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    -->1 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (1, 'SWITZERLAND', 'BERN')
    2 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (2, 'GERMANY', 'BERLIN')
    3 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (3, 'AUSTRIA', 'VIENNA')
    4 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (4, 'TURKIYE', 'ANKARA')




    Die Verwendung von UNION Statement liefert aus den beiden Tabellen jeder Stadt nur einmal im als Resultat zurück. In diesem Resultat sind die Datensätze auch nach dem Ersten und dann nach dem zweiten Feld sortiert, welches nach einem ORDER BY Country, City entspricht. Für eine andere Sortierung muss der ORDER BY-Statement explizit angegeben werden.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    -->1 SELECT Country, City
    2 FROM [dbo].[CountryCity]
    3 UNION
    4 SELECT Country, City
    5 FROM [dbo].[CountryCapital]


    Als Resultat wird folgendes ausgegeben:



    UNION



    Mit UNION ALL werden alle Datensätze der beiden Tabellen als Resultat zurückgeliefert. Die Datensätze sind in diesem Resultat nicht sortiert.





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    -->1 SELECT Country, City
    2 FROM [dbo].[CountryCity]
    3 UNION ALL
    4 SELECT Country, City
    5 FROM [dbo].[CountryCapital]


    Als Resultat wird folgendes ausgegeben:



    UNION_ALL 



    Der gesamte Beispiel Code ist wie folgt aufgelistet:





    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --> 1 BEGIN TRANSACTION
    2
    3 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CountryCity]') AND type in (N'U'))
    4 DROP TABLE [dbo].[CountryCity]
    5 GO
    6
    7 IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CountryCapital]') AND type in (N'U'))
    8 DROP TABLE [dbo].[CountryCapital]
    9 GO
    10
    11 CREATE TABLE [dbo].[CountryCity]([ID] [int] NOT NULL,
    12 [Country] [nvarchar] (50) NOT NULL,
    13 [City] [nvarchar] (50) NOT NULL)
    14
    15 CREATE TABLE [dbo].[CountryCapital]([ID] [int] NOT NULL,
    16 [Country] [nvarchar] (50) NOT NULL,
    17 [City] [nvarchar] (50) NOT NULL)
    18
    19
    20 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (1, 'SWITZERLAND', 'ZURICH')
    21 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (2, 'SWITZERLAND', 'BERN')
    22 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (3, 'SWITZERLAND', 'GENEVA')
    23 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (4, 'GERMANY', 'BERLIN')
    24 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (5, 'GERMANY', 'HAMBURG')
    25 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (6, 'GERMANY', 'MUNICH')
    26 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (7, 'AUSTRIA', 'VIENNA')
    27 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (8, 'AUSTRIA', 'GRAZ')
    28 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (9, 'AUSTRIA', 'LINZ')
    29 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (10, 'TURKIYE', 'ISTANBUL')
    30 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (11, 'TURKIYE', 'ANKARA')
    31 INSERT INTO [dbo].[CountryCity] ([ID], [Country], [City]) VALUES (12, 'TURKIYE', 'IZMIR')
    32
    33 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (1, 'SWITZERLAND', 'BERN')
    34 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (2, 'GERMANY', 'BERLIN')
    35 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (3, 'AUSTRIA', 'VIENNA')
    36 INSERT INTO [dbo].[CountryCapital] ([ID], [Country], [City]) VALUES (4, 'TURKIYE', 'ANKARA')
    37
    38 SELECT Country, City
    39 FROM [dbo].[CountryCity]
    40 UNION
    41 SELECT Country, City
    42 FROM [dbo].[CountryCapital]
    43
    44
    45 SELECT Country, City
    46 FROM [dbo].[CountryCity]
    47 UNION ALL
    48 SELECT Country, City
    49 FROM [dbo].[CountryCapital]
    50
    51 ROLLBACK TRANSACTION


    Die Beispieldatei findet Ihr unter: UNION_and_UNION_ALL_Sample_0001.sql

    Silverlight Foto Album Steuerelement

    03.05.2008 18:31:00 | Mario Meir-Huber

    Ich war am Wochenende wieder mal fleißig und habe ein Control gebastelt, welches ein Fotoalbum anzeigt. Als Datenspeicher wird hierfür XML verwendet. Zwischen einzelnen Fotos kann man auch ganz einfach navigieren. Ferner kann man durch Klick auf ein Album zu einem Unteralbum navigieren.

    Das Control ist in der MS Public Licence auf Codeplex erhältlich:

    http://www.codeplex.com/photoalbum

    Ein Beispiel ist auf meinem Server vorhanden:

    http://www.meirhuber.de/picturealbum/

    Regeln | Impressum