﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Daniel&#039;s Blog</title>
	<atom:link href="http://www.dlindemann.de/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.dlindemann.de/blog</link>
	<description>Doing some things in .NET</description>
	<lastBuildDate>Fri, 09 Jul 2010 12:16:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>MySites Konfiguration &#8220;debuggen&#8221;</title>
		<link>http://www.dlindemann.de/blog/?p=341</link>
		<comments>http://www.dlindemann.de/blog/?p=341#comments</comments>
		<pubDate>Fri, 09 Jul 2010 12:01:17 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.dlindemann.de/blog/?p=341</guid>
		<description><![CDATA[Die MySites in SharePoint 2010 sind sehr auf den Austausch von persönlichen Informationen ausgerichtet. Neu hinzu kommt eine Pinnwand à la Facebook und die Möglichkeit Statusinformationen bereitzustellen, wie auf XING. Das Aufsetzen von MySites kann jedoch etwas knifflig sein. Ein bekanntes Problem ist z.B. dass der Serviceaccount, der den User Profile Synchronization Services ausführt zwingend [...]]]></description>
			<content:encoded><![CDATA[<p>
Die MySites in SharePoint 2010 sind sehr auf den Austausch von persönlichen Informationen ausgerichtet. Neu hinzu kommt eine Pinnwand à la Facebook und die Möglichkeit Statusinformationen bereitzustellen, wie auf XING.<br />
Das Aufsetzen von MySites kann jedoch etwas knifflig sein. Ein bekanntes Problem ist z.B. dass der Serviceaccount, der den User Profile Synchronization Services ausführt zwingend zur lokalen Administratorengruppe hinzugefügt werden muss (weitere Informationen dazu gibts auf <a href="http://sharepointcommunity.de/blogs/fabianm/archive/2010/05/05/fehler-beim-start-des-sharepoint-2010-user-profile-synchronization-services.aspx" target="_blank">Fabians Blog</a>).<br />
Deshalb möchte ich hier kurz zusammenfassen auf was man achten muss um MySites zu erstellen und zeigen wie man Fehlerquellen beim synchronisieren auf die Schliche kommt.
</p>
<h4>Die Konfiguration</h4>
<ul>
<li>
<b>Farm/Service Account muss zur Gruppe Administratoren gehören</b><br />
Der Benutzer der den User Profile Synchronisation Service ausführt musst zur <u>lokalen</u> Administratorgruppe gehören.
</li>
<li>
<b>Zugriffsrechte auf die Sharepoint Datenbank</b><br />
Der Benutzer der den User Profile Synchronisation Service ausführt muss Daten in die Datenbank schreiben können.
</li>
<li>
<b>Prüfen, dass die Windows Services Forefront Indentity Snychronisation und Forefront Identity Manager laufen</b><br />
Nachdem man den User Profile Synchronisation Service gestartet hat (der Start kann bis zu 10min dauern), sollte man sich vergewisser, dass die Windows Services Forefront Indentity Snychronisation Service und Forefront Identity Manager Service gestartet wurden. Dieser werden von dem User Profile Synchronisation Service ausgeführt.
</li>
<li>
<b>IIS Reset</b><br />
Nach dem Starten des Services sollte man einen IIS Reset durchführen, da man sonst eine System.IO.FileLoadException an den Kopf geworfen bekommt :/<br />
<a href="javascript:void(0);" onclick="wp_showhide('mySitesExceptionText');">Komplette Exception anzeigen</a></p>
<div id="mySitesExceptionText" style="display: none">
<pre class="brush: plain">
System.IO.FileLoadException: The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)    at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager.InitializeIlmClient(String ILMMachineName, Int32 FIMWebClientTimeOut)     at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager..ctor(UserProfileApplicationProxy userProfileApplicationProxy, Guid partitionID)     at Microsoft.SharePoint.Portal.UserProfiles.AdminUI.ProfileAdminPage.IsProfileSynchronizationRunning()     at Microsoft.SharePoint.Portal.WebControls.UserProfileServiceImportStatisticsWebPart.RenderSectionContents(HtmlTextWriter writer)     at Microsoft.SharePoint.Portal.WebControls.UserProfileServiceImportStatisticsWebPart.RenderWebPart(HtmlTextWriter writer)     at Microsoft.SharePoint.WebPartPages.WebPart.Render(HtmlTextWriter writer)     at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)     at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)     at System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer)     at System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output)     at System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer)     at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)     at System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer)     at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)     at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)     at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.RenderChildren(HtmlTextWriter writer)     at System.Web.UI.Page.Render(HtmlTextWriter writer)     at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.Render(HtmlTextWriter writer)     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
</pre>
</div>
</li>
<li>
<b>Benötigte Rechte und Daten des Active Directories zu synchronisieren</b><br />
Der Benutzer der Daten aus dem Active Directory zieht, braucht das Recht <u>Replicate Directory Changes</u>. Meistens ist das der SharePoint Farm Account, es kann aber auch ein anderer Account angegeben werden.
</li>
</ul>
<p>Weitere Informationen zu diesen Themen findet man auch im Microsoft Technet: <a href="http://technet.microsoft.com/en-us/library/ee721049(office.14).aspx" target="_blank">http://technet.microsoft.com/en-us/library/ee721049(office.14).aspx</a>
</p>
<h4>Probleme mit dem Tool Forefront Synchronisation Service Manager lösen</h4>
<p>
Der Forefront Synchronisation Service Manager ist ein nettes Tool mit dem man die Konfiguration des User Profile Synchronisation Services überprüfen kann.<br />
Man findet das Programm unter <i>C:\Program Files\Microsoft Office Servers\14.0\Synchronization Service\UIShell\miisclient.exe</i>.<br />
Mit diesem Tool hat man die Möglichkeit sich eine Liste der Operationen auf ein Active Directory oder auf eine andere Datenquellen anzuschauen, kann sich Operationen (wie z.B. einen FullImport) starten und sich eine genaue Fehlermeldung anzeigen lassen.<br />
<div id="attachment_339" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/forefrontidentitymanagerclient.png" rel="lightbox[341]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/forefrontidentitymanagerclient.png" alt="" title="Forefront Identity Manager Client" width="400" class="size-full wp-image-339" /></a><p class="wp-caption-text">Forefront Identity Manager Client</p></div></p>
<p>Um das Programm starten zu können muss der Benutzer in folgenden Gruppen sein:</p>
<ul>
<li>FIMSyncBrowse</li>
<li>FIMSyncJoiners</li>
<li>FIMSyncOperators</li>
<li>FIMSyncPasswordSet</li>
</ul>
<p>Danach startet man das Programm im Context des Service Accounts.</p>
<p>Nun sieht man eine Liste der ausgeführten Aktionen.<br />
<div id="attachment_343" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/miisOverview.png" rel="lightbox[341]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/miisOverview.png" alt="" title="Synchronisation Service Manager Übersicht" width="400" class="size-full wp-image-343" /></a><p class="wp-caption-text">Synchronisation Service Manager Übersicht</p></div></p>
<p>Um z.B. einen FullImport laufen zu lassen, kann man über Actions -> Run (bzw. STRG+F5) eine Aktion starten.</p>
<div id="attachment_340" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/runfullimport.png" rel="lightbox[341]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/runfullimport.png" alt="" title="Synchronisation Service Manager Action" width="400" class="size-full wp-image-340" /></a><p class="wp-caption-text">Synchronisation Service Manager Action</p></div>
<p>Möchte man wissen, warum eine Synchronisation nicht geklappt hat, kann man sich einfach das Log anschauen.<br />
<div id="attachment_338" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/connectionlog.png" rel="lightbox[341]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/07/connectionlog.png" alt="" title="Synchronisation Service Manager Connection Log" width="400" class="size-full wp-image-338" /></a><p class="wp-caption-text">Synchronisation Service Manager Connection Log</p></div></p>
<p>Der Synchronisation Service Manager hat noch einiges mehr zu bieten. Für ein kleines Debugging sollten die beschriebenen Funktionen jedoch ausreichen.</p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=341</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Entwickeln mit Hilfe des Developer Dashboards</title>
		<link>http://www.dlindemann.de/blog/?p=329</link>
		<comments>http://www.dlindemann.de/blog/?p=329#comments</comments>
		<pubDate>Fri, 14 May 2010 11:47:48 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.dlindemann.de/blog/?p=329</guid>
		<description><![CDATA[Eines der wichtigsten Features für Entwickler im neuen SharePoint 2010 ist das Developer Dashboard. Wie man das Developer Dashboard aktiviert habe ich schon hier beschrieben. Doch wie benutzt man das Feature um seinen Code zu analysieren? Zeit stoppen In der linken Spalte des Developer Dashboards findet man die Ablaufverfolgung des Requests. Hier findet man eine [...]]]></description>
			<content:encoded><![CDATA[<p>
Eines der wichtigsten Features für Entwickler im neuen SharePoint 2010 ist das<br />
Developer Dashboard.<br />
Wie man das Developer Dashboard aktiviert habe ich schon <a href="http://www.dlindemann.de/blog/?p=132">hier</a> beschrieben.<br />
Doch wie benutzt man das Feature um seinen Code zu analysieren?
</p>
<p><h4>Zeit stoppen</h4>
<p>In der linken Spalte des Developer Dashboards findet man die Ablaufverfolgung des Requests.<br />
Hier findet man eine Liste von ausgeführten Aktionen mit Angaben zur Dauer der Verarbeitung.<br />
Um eigene Aktionen aufzunehmen benutzt man das Objekt <b>SPMonitoredScope</b>, das sich im Namespace <b>Microsoft.SharePoint.Utilities</b> befindet.<br />
Jeglicher Code, der ausgeführt wird solange eine Instanz von SPMonitoredScope vorhanden ist wird protokolliert.<br />
Deshalb sollte man SPMonitoredScope über usings steuern.</p>
<pre class="brush: csharp">
protected void myButton_Click(object sender, EventArgs e)
{
    using (SPMonitoredScope scopeButtonPushed = new SPMonitoredScope("Button action"))
    {
        // dummy sleep action
        Thread.Sleep(5000);
        l.Text = "Meine Daten: ";

        string myData = GenerateLabelData();
        l.Text += myData;
    }
}
</pre>
<p>Dieser Beispielcode nimmt auf, dass die Aktion "Button action" 5 Sekunden gedauert hat und zeigt die Daten in der Ablaufverfolgung an.</p>
<p>Es besteht auch die Möglichkeit Aktionen zu verschachteln.<br />
Somit kann man eine detaillierte Informationen zu seinem Code bekommen.</p>
<pre class="brush: csharp">
protected void myButton_Click(object sender, EventArgs e)
{
    using (SPMonitoredScope scopeButtonPushed = new SPMonitoredScope("Button action"))
    {
        // dummy sleep action
        Thread.Sleep(5000);
        l.Text = "Meine Daten: ";

        string myData = GenerateLabelData();
        l.Text += myData;
    }
}

private string GenerateLabelData()
{
    // z.B. lesen von daten aus einer datenbank
    using (SPMonitoredScope scopeGetData = new SPMonitoredScope("Get user information"))
    {
        // ... und noch ein dummy sleep
        Thread.Sleep(3000);
        return "Daniel Lindemann";
    }
}
</pre>
<p>In diesem Beispiel wird die Aktion "Get user information" innerhalb der Aktion "Button action" ausgeführt.<br />
Dies erzeugt folgende Ausgabe im Developer Dashboard:<br />
<div id="attachment_330" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/05/usingdd.png" rel="lightbox[329]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/05/usingdd.png" alt="Informationen im Developer Dashboard" title="Informationen im Developer Dashboard" width="400" class="size-full wp-image-330" /></a><p class="wp-caption-text">Informationen im Developer Dashboard</p></div>
</p>
<p><h4>Wichtige Ereignisse protokollieren</h4>
<p>Auf der rechten Seite des Developer Dashboards findet man die Spalte <b>Assertionen und kritische Ereignisse</b> bzw. <b>Asserts and Critical Events</b> in der englischen Version.<br />
Wie der Name schon verrät können hier kritische Ereignisse überprüft werden.<br />
Man sollte diese Funktion benutzten um darauf hinzuweisen, dass etwas nicht wie gewünscht ausgeführt wurde. Dazu benutzt man die statische Methode <b>AddDataToScope</b> der Klasse <b>SPCriticalTraceCounter</b> die sich ebenfalls im Namespace <b>Microsoft.SharePoint.Utilities</b> befindet.<br />
Als Beispiel ändere ich die Methode GenerateLabelData() sodass ein Eintrag zu den Ereignissen hinzugefügt wird:</p>
<pre class="brush: csharp">
private string GenerateLabelData()
{
    // z.B. lesen von daten aus einer datenbank
    using (SPMonitoredScope scopeGetData = new SPMonitoredScope("Get user information"))
    {
        // ... und noch ein dummy sleep
        Thread.Sleep(3000);
        SPCriticalTraceCounter.AddDataToScope(2501, "Database problem", 1, "Database query took long time");
        return "Daniel Lindemann";
    }
}
</pre>
<p>Als 3. Parameter erhält die Methode ein Flag, das beschreibt um welche Art von Meldung es sich handelt.<br />
Folgende Meldungen sind möglich:</p>
<ul>
<li>1 = Critical</li>
<li>4 = Exception</li>
<li>6 = Assert</li>
<li>8 = Warning</li>
<li>10 = Unexpected</li>
<li>15 = Monitorable</li>
</ul>
<p>Diese Methode um den Ablauf des Codes zu verfolgen hat jedoch einen Nachteil. Es wird immer der komplette StackTrace mitgespeichert und somit kann die Antwort des Servers um einige kB anwachsen.<br />
Darum sollte die Methode nicht für jedes Problem das auftreten kann aufgerufen werden.</p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=329</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ShareCamp 2010 / Session</title>
		<link>http://www.dlindemann.de/blog/?p=319</link>
		<comments>http://www.dlindemann.de/blog/?p=319#comments</comments>
		<pubDate>Wed, 14 Apr 2010 19:39:29 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.dlindemann.de/blog/?p=319</guid>
		<description><![CDATA[Am Wochenende war das erste Barcamp der SharePoint Community. Das mit fast 200 Besuchern ausgebuchte Event war ein voller Erfolg bei dem man sich mit anderen SharePoint Enthusiasten austauschen konnte. Mit über 40 Sessions hatte die Unkonferenz eine Menge zu bieten. Die Vorträge gingen von Konfigurationsthemen, über Workflows bis zu Entwicklungsthemen. Alles sehr ausgewogen. Eine [...]]]></description>
			<content:encoded><![CDATA[<p>
Am Wochenende war das erste Barcamp der SharePoint Community.<br />
Das mit fast 200 Besuchern ausgebuchte Event war ein voller Erfolg bei dem man sich mit anderen SharePoint Enthusiasten austauschen konnte.<br />
Mit über 40 Sessions hatte die Unkonferenz eine Menge zu bieten. Die Vorträge gingen von Konfigurationsthemen, über Workflows bis zu Entwicklungsthemen. Alles sehr ausgewogen.<br />
Eine Kleinigkeit habe ich dennoch zu bemängeln: Ich hätte mir mehr Entwicklersessions gewünscht <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  .</p>
<p>Sollte es nächstes Jahr auch ein ShareCamp geben bin ich wieder mit Freude dabei.</p>
<p><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/02/born2share.gif" rel="lightbox[319]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/02/born2share.gif" alt="born2share" title="born2share" width="254" height="50" class="aligncenter size-full wp-image-268" /></a></p>
<p>Eindrücke vom ersten ShareCamp gibts auf <a href="http://www.sharecamp.de">http://www.sharecamp.de</a>
</p>
<p>
Ich möchte mich auch nochmal bei allen Besuchern meiner Session zum Thema <b>Ribbon Customizing im SharePoint 2010</b> bedanken.<br />
Wie versprochen sind hier die Slides und Beispiele.</p>
Note: There is a file embedded within this post, please visit this post to download the file.
<p>
<em>EDIT: Hatte Probleme mit meinem Webserver. Jetzt funktioniert der Download aber <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </em></p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/Community' rel='tag' target='_blank'>Community</a>, <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=319</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bing Maps im Sharepoint</title>
		<link>http://www.dlindemann.de/blog/?p=276</link>
		<comments>http://www.dlindemann.de/blog/?p=276#comments</comments>
		<pubDate>Mon, 15 Mar 2010 16:12:28 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://www.dlindemann.de/blog/?p=276</guid>
		<description><![CDATA[Im aktuellen .NET Magazin ist ein schöner Bericht von Tobias Richling über das Entwickeln von Webanwendungen die geographische Daten per Bing Maps visualisieren. Dabei benutzt er ein Bing Maps ASP.NET Control, das auf Codeplex veröffentlicht wurde. Nachdem ich den Artikel durchgelesen habe, dachte ich mir: "Hey, Sharepoint mit Bing Maps ausstatten ... wieso nicht?" Das [...]]]></description>
			<content:encoded><![CDATA[<p>
Im aktuellen .NET Magazin ist ein schöner Bericht von Tobias Richling über das Entwickeln von Webanwendungen die geographische Daten per Bing Maps visualisieren.<br />
Dabei benutzt er ein <a href="http://bingmapsasp.codeplex.com/">Bing Maps ASP.NET Control</a>, das auf Codeplex veröffentlicht wurde.<br />
<br />
Nachdem ich den Artikel durchgelesen habe, dachte ich mir: "Hey, Sharepoint mit Bing Maps ausstatten ... wieso nicht?"<br />
Das Ergebnis lies nicht lange auf sich warten. Deshalb möchte ich hier zeigen wie man Bing Maps per Webpart in den Sharepoint 2010 einbinden kann.</p>
<div id="attachment_282" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/03/bingMapsOverview1.png" rel="lightbox[276]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/03/bingMapsOverview1.png" alt="" title="Bing Maps im Sharepoint 2010" width="400" class="size-full wp-image-282" /></a><p class="wp-caption-text">Bing Maps im Sharepoint 2010</p></div>
<p><h4>Bing Maps ASP.NET Control anpassen</h4>
<p>Das Bing Maps ASP.NET Control ist ein Wrapper, der um den Bing Maps Service gelegt wurde. Das Steuerelement gehörte zum Live SDK wurde aber wieder entfernt.<br />
Der Vorteil dieses Steuerelements ist, dass man durch das Setzen von wenigen Eigenschaften eine Bing Map angezeigt bekommt ohne eine Zeile Javascript. Dennoch ist es möglich die angezeigte Karte mittels <a href="http://www.microsoft.com/maps/developers/">Bing Maps AJAX SDK</a> zu ändern, was einem Entwickler bei Sharepoint 2010 Projekten sehr entgegen kommt <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>Auf Codeplex steht nur der Quellcode des Steuerelements zu Verfügung. Da die Assembly, um sie in Sharepoint benutzen zu können, mit einem Schlüssel signiert sein muss , ist das sogar ein Vorteil.<br />
<br />
Wenn man sich den <a href="http://bingmapsasp.codeplex.com/SourceControl/list/changesets">Quellcode</a> geladen hat, kann man die Solution in Visual Studio öffnen und die Assembly signieren. Das Projekt das einen Schlüssel braucht hat den Namen <b>Microsoft.Live.ServerControls.VE</b>.<br /> Ist dieser Schritt erledigt kann man das Projekt neu erstellen. Das benötigte Steuerelement findet man dann im Projektordner unter Source\bin.
</p>
<p><h4>Erstellen eines Bing Map Webparts</h4>
<p>Um das Bing Maps Webpart zu erstellen, benutzt man am besten die Vorlage für ein normales Webpart (die Vorlage des Visual Webpart finde ich ein wenig oversized).<br />
Nachdem man die Referenz zur Bing Maps Control hinzugefügt hat, muss man im Solution Packet Editor noch die Assembly als SafeControl eintragen, damit sie mit auf den Server deployt wird.<br />
Das Solution Paket sollte danach so aussehen:</p>
<pre class="brush: xml">
&lt;Solution xmlns=&quot;http://schemas.microsoft.com/sharepoint/&quot; SolutionId=&quot;3dd182a9-21c3-4260-9177-de19e39420fe&quot; SharePointProductVersion=&quot;14.0&quot;&gt;
  &lt;Assemblies&gt;
    &lt;Assembly Location=&quot;Microsoft.Live.ServerControls.VE.dll&quot; DeploymentTarget=&quot;GlobalAssemblyCache&quot;&gt;
      &lt;SafeControls&gt;
        &lt;SafeControl Assembly=&quot;Microsoft.Live.ServerControls.VE, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null&quot; Namespace=&quot;Microsoft.Live.ServerControls.VE&quot; TypeName=&quot;*&quot; /&gt;
        &lt;SafeControl Assembly=&quot;Microsoft.Live.ServerControls.VE, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null&quot; Namespace=&quot;Microsoft.Live.ServerControls.VE.Extenders&quot; TypeName=&quot;*&quot; /&gt;
      &lt;/SafeControls&gt;
    &lt;/Assembly&gt;
    &lt;Assembly Location=&quot;BingMapsWebpart_SP2010.dll&quot; DeploymentTarget=&quot;GlobalAssemblyCache&quot;&gt;
      &lt;SafeControls&gt;
        &lt;SafeControl Assembly=&quot;BingMapsWebpart_SP2010, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cf157c772a0dd57&quot; Namespace=&quot;BingMapsWebpart_SP2010.BingMaps&quot; TypeName=&quot;*&quot; /&gt;
      &lt;/SafeControls&gt;
    &lt;/Assembly&gt;
  &lt;/Assemblies&gt;
  &lt;FeatureManifests&gt;
    &lt;FeatureManifest Location=&quot;BingMapsWebpart_SP2010_BingMapsFeature\Feature.xml&quot; /&gt;
  &lt;/FeatureManifests&gt;
&lt;/Solution&gt;
</pre>
<p>Je nachdem wie man das Webpart benutzen möchte muss man noch die Deployment Eigenschaften anpassen.<br />
Für mein Beispiel benutze ich folgende Einstellungen:</p>
<ul>
<li>Deployment der Assemblies im GAC</li>
<li>Webpart Feature Bereich Site</li>
</ul>
<p>Zurück zum eigentlichen Thema.<br />
Im Quellcode des Webparts muss man erst einmal feststellen ob ein ScriptManager auf der Seite vorhanden ist, da es sich beim Bing Maps ASP.NET Control um ein Ajax Control handelt. Ist kein ScriptManager auf der Seite vorhanden muss man einen hinzufügen! Am besten überschreibt man dafür die Methode OnInit( ).</p>
<pre class="brush: csharp">
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    // enables script manager
    ScriptManager sm = ScriptManager.GetCurrent(this.Page);
    if (sm == null)
    {
        // register scriptmanager
        ScriptManager newScriptManager = new ScriptManager() { ID = "bingMapsScriptManager", ScriptMode = ScriptMode.Auto };
        this.Page.Form.Controls.Add(newScriptManager);
    }
}
</pre>
<p>Fehlt nur noch eine Bing Map. Um diese anzeigen zu lassen erstellt man in der Methode CreateChildControls( ) das Objekt <b>Map</b>. Das Map-Objekt ist das Hauptobjekt das benötigt wird und befindet sich im Namespace Microsoft.Live.ServerControls.VE. Es spiegelt wie der Name schon vermuten lässt eine Bing Map wieder.<br />
Man könnte sich die Map jetzt schon anzeigen lassen. Aber ich möchten den Benutzer gerne auf eine Standardansicht leiten. So kann man mittels der Eigenschaft <b>Dashboard</b> das Bing Maps Menü ein- bzw. ausblenden und die Eigenschaft <b>Center</b> gibt an welchen Punkt das Map-Objekt zu Beginn zentrieren soll.<br />
Dazu gibt es noch viele weitere Eigenschaften auf die ich hier nicht weiter eingehen möchte, da es sehr viele sind.</p>
<p>Der Code um Berlin in der Karte anzeigen zu lassen sieht folgendermaßen aus:</p>
<pre class="brush: csharp">
protected override void CreateChildControls()
{
    base.CreateChildControls();

    Map bingMap = new Map() { ID = "bingMap", Height = new Unit(600), Width = new Unit(100.00, UnitType.Percentage) };
    bingMap.ZoomLevel = 10;
    bingMap.Dashboard = true;
    bingMap.Center = new LatLong(52.5070, 13.3615);    // Berlin
    bingMap.Locale = SupportedLocales.de_de;    // UI in deutsch
    bingMap.ScaleBarDistanceUnit = DistanceUnit.Kilometers;    // Maßeinheit in KM

    this.Controls.Add(bingMap);
}
</pre>
<p>Jetzt kann man das Webpart testen. Einfach das Debuggen starten und das Bing Map Webpart auf einer Seite hinzufügen.
</p>
<p><h4>Daten in Bing Map anzeigen</h4>
<p>Natürlich kann man sich mit Bing Maps nicht nur eine Karte anzeigen lassen. Wie auch bei vielen anderen Web Map Diensten kann man Punkte auf der Karte hervorheben. Dazu gehören z.B. Punkte auf Objekte, Routen, hervorgehobene Bereiche.<br />
Ermöglicht wird das Ganze im Bing Maps ASP.NET Control durch Shapes. Wenn ich mir also eine Reißzwecken am Brandenburger Tor hinzufügen möchte muss ich ein Shape in Gestalt einer Reißzwecke hinzufügen.</p>
<pre class="brush: csharp">
Shape brandenburgerTor = new Shape(ShapeType.Pushpin, new LatLongWithAltitude(52.51625, 13.37767));
brandenburgerTor.Title = "Brandenburger Tor";
brandenburgerTor.Description = "Das Wahrzeichen Berlins";
brandenburgerTor.MoreInfoURL = "http://de.wikipedia.org/wiki/Brandenburger_Tor";
bingMap.AddShape(brandenburgerTor);
</pre>
<p>Die wichtigesten Informationen muss man im Konstruktor übergeben. <b>ShapeType.Pushpin</b> gibt an, dass der Shape als Reißzwecke gerendert wird. Danach folgen die Koordinaten für das Brandenburger Tor als LatLongWithAltitude-Objekt.<br />
Die Eigenschaften <b>Title</b>, <b>Description</b> und <b>MoreInfoURL</b> geben an was angezeigt werden soll, wenn man mit der Maus über den Reißzwecken fährt.<br />
<div id="attachment_311" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/03/bingMapsOverview2.png" rel="lightbox[276]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/03/bingMapsOverview2.png" alt="" title="Ortsmarke in Bing Maps" width="400" class="size-full wp-image-311" /></a><p class="wp-caption-text">Ortsmarke in Bing Maps</p></div>
</p>
<p><h4>Fazit</h4>
<p>Durch Bing Maps und das Bing Maps ASP.NET Control ist es auf einfache Art und Weise möglich geographische Daten im Sharepoint zu visualieren. Man könnte sich beispielsweise eine Liste mit Konferenzen halten und speichert sich in einem zusätzlichen Feld wo sie statt finden. Für mich ist es zudem eine Abwechslung zu den einfach gehaltenen Listen.<br />Ob Bing Maps in ASP.NET / Sharepoint Anwendungen eine Zukunft hat wird sich noch zeigen. Mir hat das Entwickeln dieser Beispielapplikation auf jeden fall Spaß gemacht.</p>
Note: There is a file embedded within this post, please visit this post to download the file.

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/ASP.NET' rel='tag' target='_blank'>ASP.NET</a>, <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=276</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Erstes Sharepoint BarCamp</title>
		<link>http://www.dlindemann.de/blog/?p=267</link>
		<comments>http://www.dlindemann.de/blog/?p=267#comments</comments>
		<pubDate>Tue, 09 Feb 2010 10:23:08 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.dlindemann.de/blog/?p=267</guid>
		<description><![CDATA[Am 10. und 11.4.2010 veranstaltet die Firma DataOne zusammen mit Microsoft das erste Sharepoint BarCamp in der Microsoft Zentrale in Unterschleißheim. Ein BarCamp ist eine Art Konferenz bei der es jedoch statt Besuchern nur aktive Teilnehmer gibt. Die einzelnen Sessions werden dabei meist zu beginn des BarCamps aufgenommen und geplant. Jeder Teilnehmer ist dazu aufgefordert [...]]]></description>
			<content:encoded><![CDATA[<p>
Am 10. und 11.4.2010 veranstaltet die Firma DataOne zusammen mit Microsoft das erste Sharepoint BarCamp in der Microsoft Zentrale in Unterschleißheim.<br />
Ein BarCamp ist eine Art Konferenz bei der es jedoch statt Besuchern nur aktive Teilnehmer gibt. Die einzelnen Sessions werden dabei meist zu beginn des BarCamps aufgenommen und geplant. Jeder Teilnehmer ist dazu aufgefordert eigene Ideen/Sessions vorzuschlagen. Diese müssen nicht zwingend geplant sein. Ich habe selbst schon guten Sessions beigewohnt, die innerhalb von 5min entstanden sind!
</p>
<p><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/02/born2share.gif" rel="lightbox[267]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/02/born2share.gif" alt="born2share" title="born2share" width="254" height="50" class="aligncenter size-full wp-image-268" /></a></p>
<p>
Weitere Informationen gibt es auf der Seite <a href="http://www.sharecamp.de">[ShareCamp] born2share</a>.<br />
Wenn das mit meiner Übernachtungsmöglichkeit klappt (wovon ich ausgehen), werde ich auf jeden fall dort sein!<br />
Bleibt nur noch abzuwarten ob ich auf dem ShareCamp meine erste Session halten werden und über welches Thema *grübel* <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /></p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/Community' rel='tag' target='_blank'>Community</a>, <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=267</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Surfstick / Web&#8217;n&#039;Walk Stick als SMS Modem benutzen</title>
		<link>http://www.dlindemann.de/blog/?p=124</link>
		<comments>http://www.dlindemann.de/blog/?p=124#comments</comments>
		<pubDate>Tue, 19 Jan 2010 21:55:00 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[AT Commands]]></category>
		<category><![CDATA[SMS]]></category>

		<guid isPermaLink="false">http://81.20.129.96/blog/?p=124</guid>
		<description><![CDATA[Bei der Entwicklung von Softwarelösungen gibt es immer wieder die Anforderung SMS vom System verschicken zu lassen. Meistens während dem Ablauf eines Eskalationsmodells oder zum Benachrichtigen bei außergewöhnlichen Vorkommnissen oder Fehlern im System (z.B. einem unerwarteten Stillstand einer Produktionsanlage). Um eine SMS Lösung zu realisieren muss man nicht immer auf teuere GSM Modems / SMS [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/blau_surfstick.png" rel="lightbox[124]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/blau_surfstick.png" alt="blau.de Surfstick" title="blau.de Surfstick" width="68" height="141" class="size-full wp-image-182" align="left" /></a><br />
Bei der Entwicklung von Softwarelösungen gibt es immer wieder die Anforderung SMS vom System verschicken zu lassen. Meistens während dem Ablauf eines Eskalationsmodells oder zum Benachrichtigen bei außergewöhnlichen Vorkommnissen oder Fehlern im System (z.B. einem unerwarteten Stillstand einer Produktionsanlage).</p>
<p>Um eine SMS Lösung zu realisieren muss man nicht immer auf teuere GSM Modems / SMS Gateways zurückgreifen. Es reicht schon wenn man einen Surfstick oder Web'n'Walk Stick zu verfügung hat. Diese kann man auch sehr günstig beziehen.</p>
<p>Ich möchte hier erklären, was man beachten muss um einen Surfstick aus einer eigenen Applikation heraus zu steuern, sodass man ihn als GSM Modem zum Verschicken von SMS benutzen kann.
</p>
<p><h4>Voraussetzungen</h4>
<p>Damit man per Surfstick SMS verschicken kann müssen zwei Voraussetzungen erfüllt sein</p>
<ul>
<li><b>SIM Karte mit der man SMS versenden kann</b><br />eine Kombikarte von T-Mobile ist evtl. nicht dazu geeignet um SMS zu schicken. Meistens sind diese Karten nur zum Surfen geeignet.</li>
<li><b>Treiber für Surfstick müssen installiert sein</b><br />Meistens muss dazu ein Programm zum benutzen des Sticks installiert werden (Modem Software). Diese Software darf nicht gestartet sein, wenn man per selbstgeschriebenem Programm SMS versenden möchte, da sie COM Ports blockiert.</li>
</ul>
<p><h4>Herausfinden welchen COM Port der Stick benutzt</h4>
<p>Nachdem man die Treiber für den Stick installiert hat, findet man in dem Geräte-Manager mind. 1 neues serielles Gerät (bei meinem blau.de Surfstick werden 2 Geräte installiert, das GSM Modem und ein Service/Diagnose Anschluss).<br />
<br /><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/GsmModemPorts.png" rel="lightbox[124]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/GsmModemPorts.png" alt="Gsm Modem Ports" title="Gsm Modem Ports" width="75%" height="75%" /></a></p>
<p>Um herauszufinden welcher COM Port benutzt werden muss, öffnet man den COM Port per Telnet Programm und schickt eine Testnachricht hin. Am einfachsten benutzt man dazu <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" target="_blank">PuTTY</a>.<br />
Als Connection Type <u>Serial</u> benutzen und COM Port angeben.<br />
Wenn die Sitzung geöffnet ist schickt man die Nachricht <b>AT</b>. Danach sollte man die Antwort <b>OK</b> erhalten und weiß somit auf welchem Port das GSM Modem läuft <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a href="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/GsmModemPutty.png" rel="lightbox[124]"><img src="http://www.dlindemann.de/blog/wp-content/uploads/2010/01/GsmModemPutty.png" alt="Gsm Modem Putty" title="Gsm Modem Putty" width="75%" height="75%" /></a></p>
<p>Sollte keine Eingabe möglich sein oder kein <b>OK</b> zurückgegeben werden muss man einen anderen COM Port öffnen.
</p>
<p><h4>AT Commands</h4>
<p>Handys und GSM Modems arbeiten mit AT Commands um auf die Mobilfunkfunktionen zuzugreifen. AT steht dabei für Attention.<br />
Ein Command ist sehr simple aufgebaut: <b>AT+Command Parameter</b>.<br />Als Antwort bekommt man immer ein <b>OK</b> zurück geliefert bzw ein <b>ERROR</b> wenn etwas schief ging.</p>
<p>Ein einfaches Beispiel:<br />
<b>AT+CPIN=&quot;1234&quot;</b>&nbsp;&nbsp;&nbsp;Mit diesem Befehl gibt man seine PIN ein.</p>
<p>Zum senden von SMS benötigt man die folgenden Befehle:</p>
<ul>
<li><b>AT</b><br />Prüfen ob Modem bereit ist</li>
<li><b>AT+CPIN=?</b><br />Prüfen ob PIN, PUK, PIN2 oder PUK2 benötigt wird</li>
<li><b>AT+CPIN=&quot;1234&quot;</b><br />Eingabe von PIN, PUK, PIN2 oder PUK2</li>
<li><b>AT+CMGF=1</b><br />Setzt das SMS Format in den Text Modus</li>
<li><b>AT+CMGS=&quot;+yyyyy&quot; [Enter]<br />
&nbsp;&gt;&nbsp;Das ist eine Nachricht [STRG-Z]</b><br />Sendet eine SMS Nachricht ohne sie im Speicher zu hinterlegen</li>
</ul>
<p>Diese Befehle kann man auch super in einer Telnet Session ausprobieren <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br />
Wer mehr Informationen zu AT Commands haben möchte, dem kann ich diese Ressourcen ans Herz legen:</p>
<ul>
<li><a href="http://www.gsm-modem.de/gsm-modem-faq.html">http://www.gsm-modem.de/gsm-modem-faq.html</a></li>
<li><a href="http://www.developershome.com/sms/howToSendSMSFromPC.asp">http://www.developershome.com/sms/howToSendSMSFromPC.asp</a></li>
<li><a href="http://www.developershome.com/sms/atCommandsIntro.asp">http://www.developershome.com/sms/atCommandsIntro.asp</a></li>
<li><a href="http://www.control.com.sg/at_commands_sms.aspx">http://www.control.com.sg/at_commands_sms.aspx</a></li>
<li><a href="http://www.anotherurl.com/library/at_test.htm">http://www.anotherurl.com/library/at_test.htm</a></li>
</ul>
<p><h4>SMS mit .NET versenden</h4>
<p>Jetzt sind alle nötigen Informationen gesammelt und man kann mittels .NET einen <b>SerielPort</b> öffnen. Die Einstellungen sind prizipiell egal und können auf dem Stardard stehen bleiben. Einzigst der COM Port, der benutzt werden soll muss eingestellt werden.</p>
<pre class="brush: csharp">
// using System.IO.Ports;    nicht vergessen in die Klasse aufzunehmen
SerialPort comport = new SerialPort("COM5");
</pre>
<p>Als nächsten schickt man dann den Befehl <b>AT</b> um zu sehen ob das GSM Modem bereit ist.<br />
Da man warten muss bis das Modem eine Antwort zurück gibt, lässt man den Thread in dem der Code läuft ein paar ms warten.</p>
<pre class="brush: csharp">
comPort.Write("AT" + SpecialCharacter.Return);
Thread.Sleep(50);
string answer = ReadComPort();
</pre>
<p>Die Methode <b>ReadComPort( )</b> vereinfacht das lesen und löscht die Puffer des SerialPort, damit man nicht immer alles per Code wiederholen muss.</p>
<pre class="brush: csharp">
private string ReadComPort()
{
    try
    {
        return comPort.ReadExisting();
    }
    catch
    {
        return "ERROR";
    }
    finally
    {
        comPort.DiscardInBuffer();
        comPort.DiscardOutBuffer();
    }
}
</pre>
<p>Ein weiteres kleines Helferlein ist die Struktur <b>SpacialCharacter</b> mit der ich benötigte Schriftzeichen an den SerialPort schicken kann.</p>
<pre class="brush: csharp">
public struct SpecialCharacter
{
    public static string CtrlZ = ((char)26).ToString();
    public static string Return = Environment.NewLine;
}
</pre>
<p>Nun muss man die PIN Nummer eingeben. Dazu schickt man den Befehl <b>AT+CPIN=&quot;1234&quot;</b> ab. Ich gehe jetzt davon aus, dass der PIN 1234 lautet <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<pre class="brush: csharp">
comPort.Write("AT+CPIN=\"1234\"" + SpecialCharacter.Return);
Thread.Sleep(50);
string answer = ReadComPort();
</pre>
<p>Gibt das GSM Modem in diesem Schritt wieder <b>OK</b> zurück, kommen wir zum dritten Schritt.<br />
Das setzen des Text Modus mittels <b>AT+CMGF=1</b>.</p>
<pre class="brush: csharp">
comPort.Write("AT+CMGF=1" + SpecialCharacter.Return);
Thread.Sleep(50);
string answer = ReadComPort();
</pre>
<p>Quittiert das Modem den Befehl wiedermal mit <b>OK</b> kommt der finale Schritt. Das senden einer SMS!!!</p>
<p>Der Befehl zum Senden einer SMS ohne die SMS im Speicher zu hinterlegen lautet <b>AT+CMGS=&quot;+yyyyy&quot;</b> bei der man die Nummer des Empfängers angibt. Nach dem Absenden des Befehls erwartet das Modem eine weiter Eingabe, die Nachricht, die mit <b>STRG+z</b> bestätigt werden muss.</p>
<pre class="brush: csharp">
comPort.Write("AT+CMGS=\"" + PhoneNumber + "\"" + SpecialCharacter.Return);
Thread.Sleep(10);
comPort.Write(Message + SpecialCharacter.CtrlZ);
Thread.Sleep(50);
string answer = ReadComPort();
</pre>
<p>Ist die Antwort <b>OK</b> hat man eine SMS verschickt und kann sich auf den Empfang freuen <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />
</p>
<p><h4>Schön verpacken</h4>
<p>Damit der gesamte Ablauf etwas handlicher wird, sollte man den kompletten Vorgang um eine SMS zu verschicken in eine Klasse.<br />
Bei mir kam folgendes heraus:</p>
<p><a href="javascript:void(0);" onclick="wp_showhide('p124completeCode');">Kompletten Quelltext anzeigen</a></p>
<div id="p124completeCode" style="display: none">
<pre class="brush: csharp">
using System;
using System.IO.Ports;
using System.Text;
using System.Threading;

namespace EasySms
{
    public class GsmModem : IDisposable
    {
        private string comPortName;
        private int baudRate;
        private Parity parity;
        private int dataBits;
        private StopBits stopBits;

        private SerialPort comPort;

        public GsmModem()
        {
            this.comPortName = string.IsNullOrEmpty(SerialPort.GetPortNames()[0]) ? "COM1" : SerialPort.GetPortNames()[0];
            this.baudRate = 115200;
            this.parity = Parity.None;
            this.dataBits = 8;
            this.stopBits = StopBits.One;

            this.SetUpComport();
            this.comPort.Open();
        }

        public GsmModem(string ComPortName)
        {
            this.comPortName = ComPortName;
            this.baudRate = 115200;
            this.parity = Parity.None;
            this.dataBits = 8;
            this.stopBits = StopBits.One;

            this.SetUpComport();
            this.comPort.Open();
        }

        public GsmModem(string ComPortName, int BaudRate, Parity ComParity, int DataBits, StopBits ComStopBits)
        {
            this.comPortName = ComPortName;
            this.baudRate = BaudRate;
            this.parity = ComParity;
            this.dataBits = DataBits;
            this.stopBits = ComStopBits;

            this.SetUpComport();
            this.comPort.Open();
        }

        public bool ModemReady
        {
            get
            {
                comPort.Write("AT" + SpecialCharacter.Return);
                Thread.Sleep(50);
                string answer = ReadComPort();

                if (answer.ToLower().Contains("ok"))
                    return true;
                else
                    return false;
            }
        }

        public bool SimReady
        {
            get
            {
                comPort.Write("AT+CPIN=?" + SpecialCharacter.Return);
                Thread.Sleep(50);
                string answer = ReadComPort();

                if (answer.ToLower().Contains("ready"))
                    return true;
                else
                    return false;
            }
        }

        public SimState ModemSimState
        {
            get
            {
                comPort.Write("AT+CPIN=?" + SpecialCharacter.Return);
                Thread.Sleep(50);
                string answer = ReadComPort();

                string pre = "+cpin: ";

                if (answer.ToLower().Contains(pre + "ready"))
                    return SimState.READY;
                else if (answer.ToLower().Contains(pre + "sim pin"))
                    return SimState.SIM_PIN;
                else if (answer.ToLower().Contains(pre + "sim puk"))
                    return SimState.SIM_PUK;
                else if (answer.ToLower().Contains(pre + "sim pin2"))
                    return SimState.SIM_PIN2;
                else if (answer.ToLower().Contains(pre + "sim puk2"))
                    return SimState.SIM_PUK2;
                else if (answer.ToLower().Contains(pre + "ph-sim pin"))
                    return SimState.PH_SIM_PIN;
                else if (answer.ToLower().Contains(pre + "blocked"))
                    return SimState.BLOCKED;
                else
                    return SimState.ERROR;
            }
        }

        public Encoding ModemEncoding
        {
            get { return this.comPort.Encoding; }
        }

        private string ReadComPort()
        {
            try
            {
                return comPort.ReadExisting();
            }
            catch
            {
                return "ERROR";
            }
            finally
            {
                comPort.DiscardInBuffer();
                comPort.DiscardOutBuffer();
            }
        }

        private void SetUpComport()
        {
            this.comPort = new SerialPort(this.comPortName, this.baudRate, this.parity, this.dataBits, this.stopBits);
            this.comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);
            this.comPort.Encoding = Encoding.Default;
            this.comPort.NewLine = SpecialCharacter.Return;
            this.comPort.ReadTimeout = 2500;
            this.comPort.WriteTimeout = 2500;
        }

        private void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            throw new GsmModemException("Error on " + this.comPortName, e.EventType);
        }

        public string ExecuteATCommand(string Command)
        {
            comPort.Write(Command);
            Thread.Sleep(50);
            return ReadComPort();
        }

        public ModemAnswer SetTextMode(SmsTextMode TextMode)
        {
            comPort.Write("AT+CMGF=" + ((int)TextMode).ToString() + SpecialCharacter.Return);
            Thread.Sleep(50);
            string answer = ReadComPort();

            if (answer.ToLower().Contains("ok"))
                return ModemAnswer.OK;
            else
                return ModemAnswer.ERROR;
        }

        public ModemAnswer SetPin(string Pin)
        {
            comPort.Write("AT+CPIN=\"" + Pin + "\"" + SpecialCharacter.Return);
            Thread.Sleep(50);
            string answer = ReadComPort();

            if (answer.ToLower().Contains("ok"))
                return ModemAnswer.OK;
            else
                return ModemAnswer.ERROR;
        }

        public ModemAnswer SendSms(string PhoneNumber, string Message)
        {
            comPort.Write("AT+CMGS=\"" + PhoneNumber + "\"" + SpecialCharacter.Return);
            Thread.Sleep(10);
            comPort.Write(Message + SpecialCharacter.CtrlZ);
            Thread.Sleep(50);
            string answer = ReadComPort();

            if (answer.ToLower().Contains("ok"))
                return ModemAnswer.OK;
            else
                return ModemAnswer.ERROR;
        }

        public ModemAnswer SendSms(string PhoneNumber, string Message, out string CompleteModemAnswer)
        {
            comPort.Write("AT+CMGS=\"" + PhoneNumber + "\"" + SpecialCharacter.Return);
            Thread.Sleep(10);
            comPort.Write(Message + SpecialCharacter.CtrlZ);
            Thread.Sleep(50);
            string answer = ReadComPort();
            CompleteModemAnswer = answer;

            if (answer.ToLower().Contains("ok"))
                return ModemAnswer.OK;
            else
                return ModemAnswer.ERROR;
        }

        #region IDisposable Member

        public void Dispose()
        {
            if (this.comPort != null &#038;& this.comPort.IsOpen)
            {
                this.comPort.Close();
            }

            this.comPort.Dispose();
        }

        #endregion
    }
}
</pre>
<pre class="brush: csharp">
namespace EasySms
{
    public enum ModemAnswer
    {
        OK,
        ERROR
    }

    public enum SmsTextMode
    {
        PDU = 0,
        TEXT = 1
    }

    public enum SimState
    {
        READY,
        SIM_PIN,
        SIM_PUK,
        SIM_PIN2,
        SIM_PUK2,
        PH_SIM_PIN,
        BLOCKED,
        ERROR
    }
}
</pre>
</div>
<p>Durch diese kleine Klasse vereinfacht sich das SMS senden auf folgende paar Zeilen:</p>
<pre class="brush: csharp">
using (GsmModem modem = new GsmModem("COM11"))
{
    if (modem.ModemReady)
    {
        if (modem.ModemSimState == SimState.READY)
        {
            string modemAnswer;
            ModemAnswer answer;
            modem.SetTextMode(SmsTextMode.TEXT);
            answer = modem.SendSms("+49160xxxxxxx", "Test von meiner Assembly", out modemAnswer);
            if (answer == ModemAnswer.OK)
            {
                Console.WriteLine("yeah!!!");
                Console.WriteLine(modemAnswer);
            }
            else
            {
                Console.WriteLine("och nööö!!!!");
                Console.WriteLine(modemAnswer);
            }
        }
    }
}
</pre>
</p>
<p>
Das komplette Projekt kann man sich <a href="http://www.dlindemann.de/blog/wp-content/uploads/EasySms.zip">hier herunterladen</a>.<br />
Ich denke es ist eine gute Basis und kann leicht erweitet werden.</p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/.NET' rel='tag' target='_blank'>.NET</a>, <a class='technorati-link' href='http://technorati.com/tag/AT+Commands' rel='tag' target='_blank'>AT Commands</a>, <a class='technorati-link' href='http://technorati.com/tag/SMS' rel='tag' target='_blank'>SMS</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=124</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sharepoint 2010 Developer Dashboard aktivieren</title>
		<link>http://www.dlindemann.de/blog/?p=132</link>
		<comments>http://www.dlindemann.de/blog/?p=132#comments</comments>
		<pubDate>Thu, 14 Jan 2010 19:35:06 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://81.20.129.96/blog/?p=132</guid>
		<description><![CDATA[Das Developer Dashboard in Sharepoint 2010 bietet die Möglichkeit den Seitenaufbau nachzuverfolgen. Die Informationen die das Dashboard anzeigt beziehen sich auf die Seite, die Datenbankaufrufe, die Webservice Aufrufe, usw. Bevor man das Dashboard aktiviert, sollte man wissen, dass es folgende Optionen gibt: On - Schaltet das Developer Dashboard an Off - Schaltet das Developer Dashboard [...]]]></description>
			<content:encoded><![CDATA[<p>
Das Developer Dashboard in Sharepoint 2010 bietet die Möglichkeit den Seitenaufbau nachzuverfolgen.<br />
Die Informationen die das Dashboard anzeigt beziehen sich auf die Seite, die Datenbankaufrufe, die Webservice Aufrufe, usw.</p>
<p><img src="http://81.20.129.96/blog/wp-content/uploads/sp2010DeveloperDashboard.png" alt="Sharepoint2010DeveloperDashboard" style="width: 75%" /><br />
<br />
Bevor man das Dashboard aktiviert, sollte man wissen, dass es folgende Optionen gibt:</p>
<ul>
<li><b>On</b> - Schaltet das Developer Dashboard <u>an</u></li>
<li><b>Off</b> - Schaltet das Developer Dashboard <u>aus</u></li>
<li><b>OnDemand</b> - Ermöglicht das öffnen des Developer Dashboards über einen Button im Menü<br />
<img src="http://81.20.129.96/blog/wp-content/uploads/sp2010DeveloperDashboardOnDemandButton.png" alt="Sharepoint2010DeveloperDashboardOnDemandButton" /></li>
</ul>
<p>Folgende Möglichkeiten gibt es um das Developer Dashboard in Sharepoint zu aktivieren:</p>
<ul>
<li><b>STSADM.EXE</b></li>
<li><b>PowerShell</b></li>
<li><b>Sharepoint Object Model</b></li>
</ul>
<p><h6>STSADM.EXE</h6>
<p>Eingabeaufforderung (cmd) öffnen und in den Ordner <b>C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN</b> wecheln.<br />
Danach folgenden stsadm.exe mit folgenden Parametern ausführen:</p>
<pre class="brush: text" style="width: 75%">
stsadm.exe -o setproperty -propertyname developer-dashboard -propertyvalue On
</pre>
</p>
<p><h6>PowerShell</h6>
<p>Nachdem man eine PowerShell geöffnet hat, muss man zuerst die Sharepoint 2010 PowerShell Bibliothek laden:</p>
<pre class="brush: ps" style="width: 75%">
Add-PSSnapin Microsoft.SharePoint.Powershell
</pre>
<p>Jetzt kann man einfach folgendes Skript benutzen um das Developer Dashboard zu aktivieren:</p>
<pre class="brush: ps"  style="width: 98%">
$ddb= [Microsoft.Sharepoint.Administration.SPWebService]::ContentService.DeveloperDashboardSettings
$ddb.DisplayLevel = "On"
$ddb.TraceEnabled = $true
$ddb.Update()
</pre>
</p>
<p><h6>Sharepoint Object Model</h6>
<p>Um das Developer Dashboard mittels Sharepoint Object Model (kurz: Sharepoint OM) muss man mit Visual Studio ein neues Projekt erstellen und danach die Sharepoint OM Assembly als Referenz hinzufügen.<br />
Die Assembly findet man im GAC unter dem Namen <b>Microsoft.Sharepoint</b>.<br />
Der Code, der das Developer Dashboard aktiviert sieht folgendermaßen aus:</p>
<pre class="brush: csharp">
SPWebService.ContentService.DeveloperDashboardSettings.DisplayLevel = SPDeveloperDashboardLevel.On;
SPWebService.ContentService.DeveloperDashboardSettings.TraceEnabled = true;
SPWebService.ContentService.DeveloperDashboardSettings.Update();
</pre>
<p>Bevor das Programm richtig läuft muss die <u>Zielplattform auf x64</u> umgestellt sein, da man sonst eine NullReferenceException hervorruft (weitere Infos dazu gibts auf <a href="http://www.hezser.de/blog/archive/2010/01/03/spfarm-local-is-null.aspx" target="_blank">René Hézser's Blog</a>).
</p>
<p>
Have fun with Sharepoint 2010!</p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/.NET' rel='tag' target='_blank'>.NET</a>, <a class='technorati-link' href='http://technorati.com/tag/PowerShell' rel='tag' target='_blank'>PowerShell</a>, <a class='technorati-link' href='http://technorati.com/tag/SharePoint' rel='tag' target='_blank'>SharePoint</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=132</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aufrufen von Webservices ohne Webreferenz</title>
		<link>http://www.dlindemann.de/blog/?p=12</link>
		<comments>http://www.dlindemann.de/blog/?p=12#comments</comments>
		<pubDate>Sun, 08 Nov 2009 14:35:40 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Webservices]]></category>
		<category><![CDATA[Reflection]]></category>

		<guid isPermaLink="false">http://81.20.129.96/blog/?p=12</guid>
		<description><![CDATA[Schon öfter hatte ich das Problem, dass ich mehrere unterschiedliche Webservices in meiner Assembly benutzen musste. Kam dann ein Service hinzu musste das ganze Projekt neu deployt werden. Eine Möglichkeit dieses Problem zu umgehen ist das dynamische Laden der Webservice Description und erstellen einer Webservice Instanz per Reflection. Um eine Instanz des Webservice erstellen zu [...]]]></description>
			<content:encoded><![CDATA[<p>
Schon öfter hatte ich das Problem, dass ich mehrere unterschiedliche Webservices in meiner Assembly benutzen musste. Kam dann ein Service hinzu musste das ganze Projekt neu deployt werden.<br />
Eine Möglichkeit dieses Problem zu umgehen ist das dynamische Laden der Webservice Description und erstellen einer Webservice Instanz per Reflection.<br />
Um eine Instanz des Webservice erstellen zu können, muss man den Service per <a href="http://msdn.microsoft.com/de-de/library/system.codedom%28VS.80%29.aspx">.NET CodeDom</a> in eine Assembly laden.
</p>
<p><h6>Laden der Webservice Description</h6>
<p>Die Webservice Description läd man am besten mittels WebClient und der statischen Methode Read( ) des ServiceDescription-Objekts.<br />
Dazu muss ein Verweis auf <i>System.Web.Services</i> hinzugefügt werden.<br />
Zu finden ist die Webservice Description auf der Webservice Seite unter dem Link <b>Dienstbeschreibung</b>. Oder man hängt einfach den Parameter <b>WSDL</b> hinter dem Service Link an <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .<br />
<img src="./wp-content/uploads/webserviceWithoutReferenceWsdl.png" alt="WSDL" border="0" /></p>
<pre class="brush:csharp">
ServiceDescription description = null;
using (WebClient client = new WebClient())
{
	using (Stream s = client.OpenRead("http://localhost:1044/BundesligaService.asmx?WSDL"))
	{
		description = ServiceDescription.Read(s);
	}
}
</pre>
<p>
Mittels eines ServiceDescriptionImporter muss man den Service zu der Assembly hinzufügen, die man später erstellen möchte.<br />
Also erstellt man sich einfach ein ServiceDescriptionImporter-Objekt und fügt das vorher erstellte ServiceDescription-Objekt zur Auflistung der zu importierenden Service Descriptions hinzu.</p>
<pre class="brush:csharp">
// Import Webservice
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "SOAP12";
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
importer.AddServiceDescription(description, null, null);
</pre>
</p>
<p><h6>Erstellen der Webservice Assembly</h6>
<p>Damit man eine Webservice Assembly dynamisch erstellen kann, braucht man verschiedene Objekte aus dem <i>System.CodeDom</i>-Namespace. Da wären zuerst einmal die zwei Klassen <i>CodeNamespace</i> und <i>CodeCompileUnit</i>.<br />
<i>CodeNamespace</i> stellt wie der Name schon erahnen lässt einen Namespace dar.<br />
Das <i>CodeCompileUnit</i>-Objekt stellt einen Container für dynamisch erstellten Code bereit.</p>
<p>Jetzt muss man die Service Description in die erstellte CodeCompileUnit importieren. Die Methode Import( ) der ServiceDescriptionImporter-Klasse übernimmt das erstellen des Proxycodes und gibt einen Wert der Enumeration <i>ServiceDescriptionImportWarnings</i> zurück (falls keine Probleme auftraten, ist der Rückgabewert 0).<br/><br />
Nun fehlt noch der Codegenerator. Den erstellt man durch den Aufruf der statischen Methode CreateProvider( ) der CodeDomProvider-Klasse und natürlich generiere ich einen C#-Codegenerator <img src='http://www.dlindemann.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .<br />Danach hat man noch die Möglichkeit Assemblies zu referenzieren die in der neuen Assembly benutzt werden sollen.</p>
<p>Ist alles erledigt, kann die Assembly erstellt werden. CompileAssemblyFromDom( ) der CodeDomProvider-Instanz kompiliert die Assembly und gibt eine Instanz der Klasse <i>CompilerResults</i> zurück.<br />Wenn die Errors-Auflistung keine Elemente enthält, verlief das kompilieren der Assembly ohne Probleme. Jetzt kann man mittels der Eigenschaft CompiledAssembly der CompilerResult-Instanz auf die Assembly zugreifen und eine Instance des Webservice erstellen.</p>
<pre class="brush:csharp">
// Create new Assembly with DOM
CodeNamespace codeNamespace = new CodeNamespace();
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(codeNamespace);

// Import webservice reference to assembly
object webserviceInstance = null;
ServiceDescriptionImportWarnings warnings = importer.Import(codeNamespace, ccu);
if (warnings == 0)
{
	// Create c# code
	CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

	// Add some references
	string[] assemblyReferences = new string[] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll" };
	CompilerParameters cp = new CompilerParameters(assemblyReferences);
	cp.GenerateInMemory = true; // Save assembly in memory

	// Compile assembly
	CompilerResults results = provider.CompileAssemblyFromDom(cp, ccu);
	if (results.Errors.Count > 0)
		throw new Exception("Can't compile code");
	else
		webserviceInstance = results.CompiledAssembly.CreateInstance("BundesligaService");
}
</pre>
</p>
<p><h6>Eine Webservice Methode ausführen</h6>
<p>Um den Webservice zu benutzen lässt man sich einfach per Reflection ein <i>MethodInfo</i>-Objekt von der Webserviceinstanz zurück geben und führt die Methode aus.</p>
<pre class="brush:csharp">
MethodInfo mi = webserviceInstance.GetType().GetMethod("GetClubs");
object returnValue = (object)mi.Invoke(webserviceInstance, Args);
</pre>
<p>Um dem ganzen ein bisschen mehr .NET 2.0 Charme zu verpassen, kann man eine Methode erstellen die einen generischen Typ zurück gibt.<br />
Somit kann man sicher gehen, dass das Ergebnis in den richtigen Typ konvertiert wird.</p>
<pre class="brush:csharp">
public &lt;T&gt; InvokeMethod&lt;T&gt;(object[] Args)
{
	MethodInfo mi = webserviceInstance.GetType().GetMethod("GetClubs");
	(T)mi.Invoke(webserviceInstance, Args);
}
</pre>
</p>
<p></p>
<p>
<a href="javascript:void(0);" onclick="wp_showhide('p12completeCode');">Kompletten Quelltext der DynamicWebservice-Klasse anzeigen</a></p>
<div id="p12completeCode" style="display: none">
<pre class="brush:csharp">
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Net;
using System.Reflection;
using System.Web.Services.Description;

namespace TestApplication.BL
{

    public enum WebserviceProtocol
    {
        Soap,
        Soap12,
        HttpPost,
        HttpGet,
        HttpSoap
    }

    public class DynamicWebservice : IDisposable
    {
        private string serviceName;
        private string methodName;
        private WebserviceProtocol protocol;

        private object webserviceInstance;

        public DynamicWebservice(string ServiceName)
        {
            this.serviceName = ServiceName;
        }

        public DynamicWebservice(string ServiceName, string MethodName)
            : this(ServiceName)
        {
            this.methodName = MethodName;
        }

        public DynamicWebservice(string ServiceName, string MethodName, WebserviceProtocol Protocol)
            : this(ServiceName, MethodName)
        {
            this.protocol = Protocol;
        }

        public void CreateWebserviceAssembly(string serviceUrl)
        {
            // Read WSDL file
            string uri = string.Empty;
            if (serviceUrl.EndsWith(@"/"))
                uri = serviceUrl + "?wsdl";
            else if (serviceUrl.EndsWith("asmx"))
                uri = serviceUrl + "?wsdl";
            else
                uri = serviceUrl + @"/?wsdl";

            ServiceDescription description = null;
            using (WebClient client = new WebClient())
            {
                using (Stream s = client.OpenRead(uri))
                {
                    description = ServiceDescription.Read(s);
                }
            }

            // Import Webservice
            ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
            importer.ProtocolName = this.protocol.ToString();
            importer.Style = ServiceDescriptionImportStyle.Client;
            importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
            importer.AddServiceDescription(description, null, null);

            // Create new Assembly with DOM
            CodeNamespace codeNamespace = new CodeNamespace();
            CodeCompileUnit ccu = new CodeCompileUnit();
            ccu.Namespaces.Add(codeNamespace);

            // Import webservice reference to assembly
            ServiceDescriptionImportWarnings warnings = importer.Import(codeNamespace, ccu);
            if (warnings == 0)
            {
                // Create c# code
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

                // Add some references
                string[] assemblyReferences = new string[] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll" };
                CompilerParameters cp = new CompilerParameters(assemblyReferences);
                cp.GenerateInMemory = true; // Save assembly in memory

                // Compile assembly
                CompilerResults results = provider.CompileAssemblyFromDom(cp, ccu);
                if (results.Errors.Count &gt; 0)
                    throw new Exception("Can't compile code");
                else
                    this.webserviceInstance = results.CompiledAssembly.CreateInstance(this.serviceName);

            }
        }

        public void InvokeMethod(object[] Args)
        {
            if (string.IsNullOrEmpty(this.methodName))
                throw new ArgumentException("No method name declared by the constructor!");

            // Invoke Method
            MethodInfo mi = webserviceInstance.GetType().GetMethod(this.methodName);
            mi.Invoke(webserviceInstance, Args);
        }

        public void InvokeMethod(string MethodName, object[] Args)
        {
            MethodInfo mi = webserviceInstance.GetType().GetMethod(MethodName);
            mi.Invoke(webserviceInstance, Args);
        }

        public object InvokeMethodWithReturnValue(string MethodName, object[] Args)
        {
            MethodInfo mi = webserviceInstance.GetType().GetMethod(MethodName);
            return mi.Invoke(webserviceInstance, Args);
        }

        public T InvokeMethodWithReturnValue&lt;T&gt;(string MethodName, object[] Args)
        {
            MethodInfo mi = webserviceInstance.GetType().GetMethod(MethodName);
            return (T)mi.Invoke(webserviceInstance, Args);
        }

        public void Dispose()
        {
            // delete the instance
            this.webserviceInstance = null;

            this.serviceName = null;
            this.methodName = null;
        }

    }

}</pre>
</div>
<p>
Download: <a href="./wp-content/uploads/WebserviceWithoutReference.zip">Beispiel Projekt</a><br /></p>

<!-- start wp-tags-to-technorati 1.02 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/.NET' rel='tag' target='_blank'>.NET</a>, <a class='technorati-link' href='http://technorati.com/tag/Reflection' rel='tag' target='_blank'>Reflection</a>, <a class='technorati-link' href='http://technorati.com/tag/Webservices' rel='tag' target='_blank'>Webservices</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.dlindemann.de/blog/?feed=rss2&amp;p=12</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
