28.05.2013
MVC: Html.Action / RenderAction und Html.Partial / RenderPartial
ASP.NET

Bei mir kam eben Verwirrung auf, als ich eine View als Partial View einbinden wollte und die passende Methode im Controller nicht aufgerufen wurde. Deshalb habe ich mich kurz belesen und notiere folgendes:

Html.Partial und RenderPartial verwendet man für statische Inhalte, oder wenn die Daten bereits geladen sind. Im Controller wird keine Action-Methode aufgerufen. Html.Action und RenderAction finden dann Verwendung, wenn man im Controller noch diverse Aktionen ausführen möchte.

Die Render... Anweisungen rendern, wie es der Name schon sagt, das Html direkt in den Output-Stream, während die anderen Anweisungen eine Methode mit Rückgabewert sind, den man noch weiter beeinflussen kann.
0 Kommentare
Kommentar schreiben

20.02.2013
MD5 Hash
Allgemein .NET

Die einfachste Methode, um einen MD5-Hash zu erstellen, findet man in der System.Web Dll. Die Methode heißt HashPasswordForStoringInConfigFile. Leider ist sie ab .NET 4.5 veraltet, aber bis dahin leistet sie optimalen Dienst.

1:System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("Mein String", "md5")


Für diese Methode darf die Referenz auf System.Web im Projekt nicht fehlen!
2 Kommentare
Kommentar schreiben

15.02.2013
Separate Codepfade für das Debugging
ASP.NET

Beim Entwickeln von Anwendungen möchte man oft zusätzliche Informationen ausgeben, oder gar ganz andere Codepfade ausführen lassen, um das Verhalten des Codes zu analysieren. Viele kommentieren hierzu etliche Codezeilen ein und aus und am Ende sieht der Code entweder unsauber aus, oder nützliche Zusatzzeilen werden komplett gelöscht und dürfen beim nächsten Bugfixing oder bei der nächsten Erweiterung wieder neu programmiert werden.

Einfacher ist die Lösung über preprocessor directives! So kann man zum Beispiel ganz einfach Code für Debug und Release hinzufügen, der auch nur dann kompiliert wird, wenn man das Projekt in der entsprechenden Einstellung erstellt. Das hat auch den Vorteil, dass diverse Debug-Anweisungen später im Release keine unerwünschten Fehler auslösen können.

Hier ein Beispiel:
1:#if (DEBUG)
2: return View(GetAllData());
3:#else
4: return RedirectToAction("NextStep");
5:#endif

Beobachtet diese Zeilen in Visual Studio mal, wenn ihr das Projekt zwischen Debug und Relase hin und her schaltet. Der inaktivte Part wird jeweils ausgegraut.
1 Kommentar
Kommentar schreiben

05.01.2011
ASP.NET Development Server langsam mit Firefox
Allgemein .NET

Ich habe mich schon lange darüber aufgeregt, dass mein Lieblingsbrowser beim Entwickeln von Webseiten mit Visual Studio extrem langsam reagiert. Heute habe ich das Thema mal gegoogelt und bin auch prompt auf eine Lösung gestoßen. Die Langsamkeit liegt an der IPv6-Untersützung des Firefox in der entsprechenden Umgebung. Das Problem lässt sich abstellen, indem man die IPv6-Unterstützung des Firefox ausschaltet (insofern man diese nicht benötigt).

Einfach die Konfiguration des Firefox mit about:config aufrufen. Anschließend den Eintrag network.dns.disableIPv6 lokalisieren und auf true setzen.

Schon rennt der Firefox mit dem Cassini-Webserver.

Hier noch der Link zu dem Orginalartikel, der mir geholfen hat: http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx
0 Kommentare
Kommentar schreiben

04.10.2010
DateTime: Letzter Tag eines Monats
VB.NET

Wenn man den letzten Tag eines Monats haben möchte, muss man etwas herum rechnen. Es gibt etliche Varianten, die jede Menge Vodoo durchführen, dabei ist die rechnerische Lösung recht einfach.
Die DateTime Klasse bietet uns gute Möglichkeiten, mit Datumswerten zu rechnen. Um den letzten Tag eines Monats zu erhalten, muss man zum gegebenen Datum einen Monat hinzu addieren und die Anzahl der gegebenen Tage subtrahieren. Damit erhält man den nullten Tag des Folgemonats, oder auch den letzten Tag des gewünschten Monats. Man kann auch einfach folgende Funktion nutzen:

1:    Public Shared Function GetLastDayOfMonth(ByVal d As DateTime) As DateTime
2: Dim dNextMonth As DateTime = DateAdd(DateInterval.Month, 1, d)
3: Return DateAdd(DateInterval.Day, -d.Day, dNextMonth)
4: End Function
0 Kommentare
Kommentar schreiben

29.09.2010
Ajax Control Toolkit 40412 funktioniert nicht
ASP.NET

Ich habe gerade das Ajax Control Toolkit in der Version 40412 in mein Visual Studio eingebunden und fleißig Controls verwendet. Beim Ausführen meiner Seite waren keine dieser Controls zu sehen, anstelle dessen eine Javascript Fehlermeldung 'Sys.Extended.UI.TextBoxWrapper' ist Null oder kein Objekt. Mehrfach habe ich die dll Dateien neu eingebunden und alles probiert...

Abhilfe hat nur eine ältere Version 30512 schaffen können. Diese funktionierte nach der beschriebenen Anleitung wunderbar.

Ich hoffe das war nur etwas Ärger am sich endenden Arbeitstag. Ansonsten ist das Ajax Toolkit echt spitze.
0 Kommentare
Kommentar schreiben

01.10.2010
Exportieren von geography/geometry-Daten aus einer MSSQL 2008 Datenbank
SQL

Als ich mit dem DTS-Wizard von MSSQL 2008 heute meine geography-Daten in meine Wirkdatenbank kopieren wollte, bekam ich vom Wizard folgende Fehlermeldung:

1:Found 1 unknown column type conversion(s)
2:You are only allowed to save the package


Das Problem:

Der DTS-Wizard kennt das Mapping der neuen Datentypen SQL Server 2008 noch nicht. Diese können aber dem DTS-Wizard bekannt gemacht werden. Mit einem Doppelklick auf die als fehlerhaft markierte Spalte, bekommt man die Konvertierungs-Details angezeigt. In dieser Ansicht wird unter anderem das Mapping-File angezeigt, welches für die Definition der Konvertierung zuständig ist. In meinem Fall ist es die Datei C:\Programme\Microsoft SQL Server\100\DTS\MappingFiles\MSSQLToSSIS10.XML, da ich von SQL2008 nach SQL2008 exportieren möchte. Jetzt einfach die entsprechende Datei suchen und den Bereich für den Datentyp varbinary (max) kopieren. Dieser sollte folgendermaßen aussehen:

1:  <!-- varbinary (max) -->
2: <dtm:DataTypeMapping >
3: <dtm:SourceDataType>
4: <dtm:DataTypeName>varbinarymax</dtm:DataTypeName>
5: </dtm:SourceDataType>
6: <dtm:DestinationDataType>
7: <dtm:SimpleType>
8: <dtm:DataTypeName>DT_IMAGE</dtm:DataTypeName>
9: </dtm:SimpleType>
10: </dtm:DestinationDataType>
11: </dtm:DataTypeMapping>


Diesen Bereich jetzt einfach zwei mal einfügen und wir folgt editieren:

Für geometry:

1:  <!-- geometry -->
2: <dtm:DataTypeMapping >
3: <dtm:SourceDataType>
4: <dtm:DataTypeName>geometry</dtm:DataTypeName>
5: </dtm:SourceDataType>
6: <dtm:DestinationDataType>
7: <dtm:SimpleType>
8: <dtm:DataTypeName>DT_IMAGE</dtm:DataTypeName>
9: </dtm:SimpleType>
10: </dtm:DestinationDataType>
11: </dtm:DataTypeMapping>


Für geography:

1:  <!-- geography -->
2: <dtm:DataTypeMapping >
3: <dtm:SourceDataType>
4: <dtm:DataTypeName>geography</dtm:DataTypeName>
5: </dtm:SourceDataType>
6: <dtm:DestinationDataType>
7: <dtm:SimpleType>
8: <dtm:DataTypeName>DT_IMAGE</dtm:DataTypeName>
9: </dtm:SimpleType>
10: </dtm:DestinationDataType>
11: </dtm:DataTypeMapping>


Hier noch der Link zum englischen Orginalartikel auf der Seite von SQL-Server-Helper.com, der mit diese Lösung verraten hat.
0 Kommentare
Kommentar schreiben

09.10.2010
Beispiel: Exif Daten auslesen
ASP.NET

Wie man mit .NET die Exif Daten aus Bildern auslesen kann, findet man recht gut im Internet. Nur an Beispielen feht es. Hier möchte ich einen einfachen Schnipsel zeigen, wie man die wohl interessantesten Infos auslesen kann. Das ganze geht recht einfach über die GetPropertyItem Methode von Bitmap. Man muss nur die ID und den Datentyp der Property wissen, die Infos kann man hier (Property Item Descriptions) finden. Etwas kniffig ist z.B. die Belichtungszeit, die ergibt sich aus 2 Zahlen, die man getrennt aus dem Value extrahieren muss.

Hier das kleine Beispiel, welches Aufnahmedatum, Kamera, Brennweite, Blende, Belichtungszeit und ISO ausliest. Für die Richtigkeit übernehme ich mal keine Garantie, dafür braucht es noch ein paar Tests. Zur Zeit sieht es recht gut aus.
1:Encoding ascii = Encoding.ASCII;
2:string str = "";
3:
4:// DateTime
5:str = ascii.GetString(value.GetPropertyItem(36867).Value, 0, value.GetPropertyItem(36867).Len - 1);
6:lblDate.Text = DateTime.ParseExact(str, "yyyy:MM:dd HH:mm:ss", null).ToString("dd.MM.yyyy HH:mm");
7:
8:// Cam
9:str = ascii.GetString(value.GetPropertyItem(271).Value, 0, value.GetPropertyItem(271).Len - 1);
10:str += " " + ascii.GetString(value.GetPropertyItem(272).Value, 0, value.GetPropertyItem(272).Len - 1);
11:lblCam.Text = str;
12:
13:// Focal Length
14:str = Math.Truncate((decimal)(BitConverter.ToInt16(value.GetPropertyItem(37386).Value, 0) / 10)).ToString();
15:lblFocalLength.Text = str + " mm";
16:
17:// Aperture
18:str = BitConverter.ToInt32(value.GetPropertyItem(33437).Value, 0).ToString();
19:str = str.Insert(str.Length - 1, ",");
20:lblAperture.Text = str;
21:
22:// Exposure Time
23:int i1 = BitConverter.ToInt32(value.GetPropertyItem(33434).Value, 0);
24:int i2 = BitConverter.ToInt32(value.GetPropertyItem(33434).Value, 4);
25:if (i2 == 10)
26:{
27: str = Math.Round(i1 / 10.0, 1).ToString();
28:} else
29:{
30: str = i1.ToString() + "/" + i2.ToString();
31:}
32:lblExposureTime.Text = str + " Sek.";
33:
34:// ISO
35:lblIso.Text = BitConverter.ToInt16(value.GetPropertyItem(34855).Value, 0).ToString();

Noch ein kleiner Hinweis: lblDate usw. sind Labels auf meiner aspx-Seite. Dort werden die Werte dann angezeigt.
0 Kommentare
Kommentar schreiben

27.09.2010
Visual Studio 2008 - Intellisense extrem langsam
Allgemein .NET

Nach dem Hinzufügen von Webservices wird bei mir das Visual Studio 2008 Intellisense so langsam, dass ich bei jedem Aufruf ein bis zwei Sekunden auf die Anzeige warten darf. Dies lässt sich beheben, in dem man unter den Projekteigenschaften --> Kompilieren --> "XML-Dokumentationsdatei generieren" den Haken rausnimmt.

Ich wusste schon immer, das eine Dokumentation besonders lange dauert. ;-)
0 Kommentare
Kommentar schreiben

26.10.2010
Quelltext in html mit Tabs darstellen
ASP.NET

Tabs / Tabulatoren sind eine schöne Sache, wenn man Text formatieren möchte. Besonders bei Quelltexten möchte man die Lesbarkeit mit den unterschiedlich eingerückten Zeilen stark verbessern. Bei den Schriftarten Courier New usw. kann man die Einrückung auch gern mit Leerzeichen machen, aber Tabulatoren sind denkbar einfacher.

In html hat man nun oft das Problem, dass man im Code Tabulatoren einfügen kann, wie man will, dieser aber vom Browser nicht interpretiert werden. Möchte man nun z.B. Quelltext anzeigen, wie in diesen Blog hier, müsste man alle Tabs mit Leerzeichen ersetzen. Aber es geht auch einfacher! Das Tag <pre> sagt den Browser, dass es sich nachfolgend schon um formatierten Text handelt und zeigt dann auch die Tabs brav an.

Hier ein kleines Beispiel
1:<div>
2:<pre>
3: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
4: If Not IsPostBack Then
5: Try
6: Catch ex As Exception
7: End Try
8: End If
9: End Sub
10:</pre>
11:</div>
1 Kommentar
Kommentar schreiben

01.10.2010
Arbeiten mit Geodaten im SQL-Server 2008
SQL

Mit meiner neuen Seite http://www.sachsencacher.de haben Artzuk und ich uns natürlich intensiv mit Geodaten auseinandersetzen dürfen. Obwohl ich in den Release-Notes zum SQL-Server 2008 zwar über die Unterstützung solcher Datentypen gelesen habe, war ich mir nicht über die Mächtigkeit der Funktionen im Klaren. Als ich mich jetzt nochmal intensiver damit beschäftigt habe, bin ich auf ein geniales Tutorial aus fünf Teilen auf dem Blog von Olaf Helper gestoßen.

Deshalb möchte ich die Teile hier gern verlinken und Ihm ein großes Lob über diesen Weg aussprechen:

T-SQL Geografie-Unterricht Teil 1 - Punkte
T-SQL Geografie-Unterricht Teil 2 – Linie
T-SQL Geografie-Unterricht Teil 3 – Polygon
T-SQL Geografie-Unterricht Teil 4 – Berechnungen
T-SQL Geografie-Unterricht Teil 5 – Daten konvertieren

0 Kommentare
Kommentar schreiben

20.09.2010
Einträge aus einer generischen Liste (List(Of T)) mit Lambda-Ausdrücken entfernen
VB.NET

Wer kennt das nicht? Man hat eine Liste oder ein Array aus Objekten oder Variablen und muss nun bestimmte Einträge in dieser Liste löschen. Die mir bisher bekannte Vorgehensweise es mit Schleifen (For Each) zu machen war immer problematisch, da man die durchzulaufende Liste nicht verändern darf. Heute bin ich auf das Thema Lambda-Ausdrücke gestoßen, die es einem wirklich einfach machen, diese Werte mit einer Code-Zeile zu entfernen, in sofern man klare Kriterien definieren kann.

Hier mein Beispiel:

1:Protected Sub ListDemo()
2: 'Liste erstellen
3: Dim li As New List(Of String)
4: li.Add("Text1")
5: li.Add("Text2")
6: li.Add("Text3")
7: li.Add("Text4")
8: li.Add("Text1")
9: li.Add("Text4")
10:
11: 'Alle List-Items die den Wert "Text1" haben entfernen
12: li.RemoveAll(Function(prod) prod.Equals("Text1"))
13: End Sub


Hier noch meine Erklärung der Sytax:

li - generische Liste
RemoveAll - orginäre Methode der Klasse List(Of T)
Funtion - Definition der rekursiven, anonymen Funktion
prod - Übergabeparameter - In diesem Fall der aktuelle Listenwert
prod.Equals("Text1") - Boolscher Ausdruck, der ausgewertet wird

Etwas ausführlicher ist das Ganze auf bloggingabout.net englisch beschrieben.

0 Kommentare
Kommentar schreiben

24.08.2010
Zugriff auf Application bzw. Session aus Shared Functions
ASP.NET

Im Zusammenhang mit meinem letzten Post, bin ich auf das Problem gestoßen, dass ich ja auf Werte innerhalb des aktuellen Contextes zugreifen muss. Der Zugriff kann hier z.B. über die Application (Global) oder Session ("Lokal") erfolgen. Hier das Beispiel dazu:

1:Partial Public Class _Default
2: Inherits System.Web.UI.Page
3:
4: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
5: 'Beliebige Daten in die Session schreiben
6: Session("PageLoadTime") = Now.ToString
7: End Sub
8:
9: Public Shared Function GetPageLoadTime() As String
10: 'Mit dem HttpContext-Objekt kann man auf die aktuellen Umgebungsvariablen zugreifen
11: Dim hcContext As HttpContext = HttpContext.Current
12: Return hcContext.Session("PageLoadTime")
13: End Function
14:End Class
0 Kommentare
Kommentar schreiben

24.08.2010
Clientseitiges ausführen einer serverseitigen Methode
VB.NET

Das nachfolgende Beispiel beschreibt die Möglichkeit clientseitig Servercode auszuführen und mit der Antwort Clientseitig weiter zu arbeiten. Dies ermöglicht zum Beispiel das Abfragen von Statusmeldung und die Aktualisierung eines UpgradeProgress. Ein Beispiel für eine gute UpgradeProgressBar findet Ihr hier.

1:<%@ Page Language="vb" AutoEventWireup="false"  %>
2:
3:<head runat="server">
4: <script runat="server">
5: ''' <summary>
6: ''' Webmethode zum Laden der Serveruhrzeit
7: ''' </summary>
8: <System.Web.Services.WebMethod()> _
9: Public Shared Function CurrentTime() As String
10: Return Now.ToString()
11: End Function
12: </script>
13: <script type="text/javascript">
14: // Javascriptfunktion für den Aufruf der Webmethode
15: function showCurrentTime() {
16: PageMethods.CurrentTime(onComplete);
17: }
18: // Javascriptfunktion für die Verarbeitung bzw. Ausgabe des Ergebnisses
19: function onComplete(result) {
20: alert(result);
21: }
22: </script>
23:</head>
24:<body >
25: <form id="form1" runat="server">
26: <%--Scriptmanager für die aktivierung von AJAX--%>
27: <%--EnablePageMethods muss auf True gesetzt werden--%>
28: <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
29: <%--Buttoncontrol zum aufrufen der Javascriptfunktion--%>
30: <asp:Button runat="server" ID="test" OnclientClick="showCurrentTime();return false;" Text="Zeige Serveruhrzeit" />
31: </form>
32:</body>
33:</html>
1 Kommentar
Kommentar schreiben

19.08.2010
Ajax: Button reagiert nicht (bei dynamisch eingefügten Controls)
ASP.NET

Ich hatte mir ein UserControl geschrieben, das jeweils einen Kommentar widerspiegeln sollte. In diesen Control ist ein Button zum Löschen des jeweiligen Kommentars. Damit dafür nicht die die ganze Seite neu geladen werden muss, habe ich das asp:UpdatePanel benutzt.

Das Problem
Beim Klick auf den Löschen-Button, ist nichts passiert. Nach einigen Spielereien, wurde die komplette Seite neu geladen, aber das war nicht das Ziel des UpdatePanels!

Ursache und Lösung
Jedes Usercontrol muss eine eindeutige ID bekommen, dies hatte ich vergessen. Deshalb war der Trigger verwirrt, wenn ich das mal so ausdrücken darf. Nachdem ich die IDs eingefügt hatte, lief alles sofort wie gewünscht.
0 Kommentare
Kommentar schreiben

01.10.2010
Massendaten zwischen zwei SQL-Servern kopieren (BulkCopy)
SQL

Ich hatte das Problem, dass ich mit meinem SQL-Server daheim Daten auf dem SQL-Server der Wirkanwendung (gehostetes Webprojekt) aktualisieren musste. Meine erste Idee war natürlich (Replikation etc kamen nicht in Frage, da es der Zeilserver nicht unterstützt):

1:INSER INTO DestTable
2:SELECT col1, col2
3:FROM SourceTable


Diese Idee hatte ich ziemlich schnell verworfen. Die ausführung des Scripts dauerte sagenhafte 3:47 Stunden. Für diese Zeit wäre die Website down gewesen. Daraufhin habe ich viele Ideen gehabt und wieder verworfen. Das einzige was ist wusste ist, dass mir das Wort BULK weiterhilft. Dann bin ich auf das SqlBulkCopy-Objekt im Namespace System.Data.SqlClient gestoßen. Mit folgenden Skript dauerte dann das aktualisieren dann nur noch 6,5 Minuten für vier sehr große Tabellen. Diese Zeit ist dann wohl meinem DSL 3000 geschuldet.

1:   Private Sub UpdateLiveTable(ByVal sTablename As String)
2: 'Daten aus der Quelldatentabelle laden
3: Dim daSource As New SqlDataAdapter(String.Format("SELECT * FROM {0}", sTablename), _sqlConnSource)
4: Dim dtSource As New DataTable
5: daSource.Fill(dtSource)
6:
7: 'Löschen aller Daten der Zieltabelle (optional)
8: Dim scDelete As New SqlCommand(String.Format("DELETE FROM {0}", sTablename), _sqlConnDestination)
9: _sqlConnDestination.Open()
10: scDelete.ExecuteNonQuery()
11: _sqlConnDestination.Close()
12:
13: 'Daten in die Zieltabelle kopieren
14: Dim sbkDestination As New SqlClient.SqlBulkCopy(_sqlConnDestination)
15: sbkDestination.BulkCopyTimeout = 2400 'Timeout setzen, da der Import je nach Datenmenge dauern kann
16: sbkDestination.DestinationTableName = sTablename 'Name der Zieltabelle angeben
17: _sqlConnDestination.Open()
18: sbkDestination.WriteToServer(dtSource) 'Hier werden die Daten geschrieben
19: _sqlConnDestination.Close()
20: End Sub
0 Kommentare
Kommentar schreiben

04.05.2010
GridView Ungültiges Postback- oder Callbackargument
ASP.NET

Ungültiges Postback- oder Callbackargument. Die Ereignisvalidierung wird mithilfe von <pages enableEventValidation="true"/> in der Konfiguration oder mithilfe von <%@ Page EnableEventValidation="true" %> auf einer Seite aktiviert. Aus Sicherheitsgründen überprüft dieses Feature, dass Argumente für Postback- oder Callbackereignisse von dem Serversteuerelement ausgehen, von dem sie ursprünglich gerendert wurden. Wenn die Daten gültig sind und erwartet wurden, verwenden Sie die ClientScriptManager.RegisterForEventValidation-Methode, um die Postback- oder Callbackdaten für die Validierung zu registrieren.

Diese Fehlermeldung kam bei mir, als ich einen DeleteButton mit ShowDeleteButton (als ImageButton!) in jeder GridView Zeile haben wollte, der mit einen return confirm('Wirklich löschen?') ausgestattet war. Ohne das JavaScript lief noch alles perfekt.
1:<asp:GridView runat="server" ID="gvTest" />
2: <Columns>
3: <asp:CommandField ButtonType="Image" ShowDeleteButton="true"
4: DeleteImageUrl="~/images/delete.gif" ItemStyle-CssClass="GVSmallCell" />
5: </Columns>
6:</asp:GridView>


Die Lösung ist ein kleiner Workarraund, der aber keinen zusätzlichen Code im CodeBehind benötigt! Man muss ein TemplateField nehmen und in dieses einen LinkButton einfügen. Die Eigenschaft CommandName setzt man auf "Delete" und als Text Eigenschaft nimmt man ein img Tag mit den gewünschten Bild. Dadurch sieht der LinkButton genauso aus, wie der alte ImageButton und das Event OnRowCommand bzw. OnRowDeleting wird ganz normal ausgelöst, ohne dass man etwas dazu tun muss.
1:<asp:GridView runat="server" ID="gvTest" />
2: <Columns>
3: <asp:TemplateField ItemStyle-CssClass="GVSmallCell">
4: <ItemTemplate>
5: <asp:LinkButton ID="lbDel" runat="server" CommandName="Delete"
6: ImageUrl="~/images/delete.gif" OnClientClick="return confirm('Wirklich löschen?');"
7: Text="<img src='images/delete.gif' style='border:solid 0px white;' />" />
8: </ItemTemplate>
9: </asp:TemplateField>
10: </Columns>
11:</asp:GridView>
1 Kommentar
Kommentar schreiben

29.03.2010
Sprachdateien (Resourcefiles) in Konsolenanwendungen/Klassenbibliothek verwenden
VB.NET

Wie oft hat man das Problem, dass Anwendungen in verschiedenen Spachen entwickelt werden müssen. Hier zeige ich Euch, wie ihr sehr einfach mit Resourcendateien Eure Anwendungen mehrsprachig erstellt:

Als Beispiel habe ich eine Konsolenanwendung erstellt. Hier die entsprechende Projektmappenstruktur:
http://www.familie-waschke.de/WorkadayNET/Projektstruktur.JPG

So sieht der Inhalt der drei Resourcendateien aus:
http://www.familie-waschke.de/WorkadayNET/Resourcenfiles.JPG

Der Zugriff auf die Inhalte der Resourcenfiles gestaltet sich nun denkbar einfach:
1:    
2:Sub Main()
3: 'Resourcemanager erstellen
4: 'Basename ergibt sich aus folgender Syntax: {Projektname}.{Name des ResourceFiles}
5: Dim rm As New ResourceManager("ConsoleApplication1.MyResource", System.Reflection.Assembly.GetExecutingAssembly)
6:
7: 'Ausgabe bei unbekannter CultureInfo
8: Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("fr-FR")
9: Console.WriteLine(rm.GetString("String1"))
10:
11: 'Zwei ausgaben mit vorhandener Cultureinfo
12: Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("de-DE")
13: Console.WriteLine(rm.GetString("String1"))
14: Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("en-US")
15: Console.WriteLine(rm.GetString("String1"))
16:
17: Console.ReadLine()
18: End Sub

Hier das Projekt
0 Kommentare
Kommentar schreiben

29.03.2010
GridView.RowDeleting wird doppelt ausgeführt
ASP.NET

Die Situation
Ich arbeite viel mit Datenbanken und nutze zum Anzeigen der Daten GridViews. Beim aktuellen Projekt lief das erste GridView perfekt: laden, anzeigen, editieren, löschen usw. Das zweite war auch schnell programmiert, aber beim Testen kam der Schock. Ich wollte nur einen Eintrag löschen, aber es wurden immer 2 entfernt. Schnell die Logik kontrolliert, alles stimmt. Dann den Debugger angeworfen, um zu sehen, was da überhaupt geschieht.

Das Problem
Das Problem war, das RowDeleting Event wurde 2 mal ausgelöst! Das Thema wurde auch schon heiß im Internet diskutiert und ich habe wüste Workarounds gefunden. Die meisten speichern in der Session, dass das Event schon behandelt wurde und fangen damit den zweiten Durchlauf ab. Diese Lösung finde ich äußerst unschön, besser ist dann schon der Vorschlag von Microsoft: MS Artikel
Eigentlich hat ja .NET immer Recht und man selbst hat den Fehler implementiert, hier aber ist es offensichtlich ein anerkannter Bug!

Die Lösung
Wie von Microsoft vorgeschlagen, sollte man entweder aus den ButtonType="Image" einen normalen Button oder einen LinkButton machen. Wem das nicht gefällt, der fügt seinen eigenen ImageButton in ein TemplateField hinzu und nutzt nicht den vorgefertigten DeleteButton von .NET.

Hinweis
  • Das Problem tritt offensichtlich nicht immer auf. Anfangs lief bei mir alles korrekt, dann kam auf einmal der Fehler, momentan läuft es wieder

  • Wenn man dem MS Artikel vertrauen kann, betrifft dieses Verhalten nur IE6 Benutzer
0 Kommentare
Kommentar schreiben

29.03.2010
Combobox mit Enum verheiraten
ASP.NET

Wie häufig hat man das Problem, dass man in Anwendungen Enumerationen verwendet und diese im Idealfall direkt an eine Combobox gebunden werden sollen. Das Beispiel zeigt, wie man einen Enumeration mit userverträglichen Einträgen an die Combobox bindet.

Definition der Enumeration
1:Imports System.ComponentModel
2:
3:Public Enum RecordingPublishType As Integer
4: <Description("Nicht")> _
5: None = 1
6: <Description("Moderatoren")> _
7: Moderators = 2
8: <Description("Teilnehmer")> _
9: Participants = 3
10: <Description("Berechtigte Benutzer")> _
11: TrustedUsers = 4
12:End Enum


Hilfsfunktionen zur übersetzung der Enumerationen
1:    *Public Shared Function GetEnumDescription(ByVal EnumConstant As System.Enum) As String
2: Dim fi As Reflection.FieldInfo = EnumConstant.GetType().GetField(EnumConstant.ToString())
3: Dim attr() As System.ComponentModel.DescriptionAttribute = _
4: DirectCast(fi.GetCustomAttributes(GetType(System.ComponentModel.DescriptionAttribute), False), _
5: System.ComponentModel.DescriptionAttribute())
6: If attr.Length > 0 Then
7: Return attr(0).Description
8: Else
9: Return EnumConstant.ToString()
10: End If
11: End Function
12:
13:
14: *Public Shared Function GetEnumDescriptions(ByVal EnumConstant As Type) As String()
15: Dim res(-1) As String
16: For Each ec As [Enum] In [Enum].GetValues(EnumConstant)
17: ReDim Preserve res(UBound(res) + 1)
18: res(UBound(res)) = GetEnumDescription(ec)
19: Next
20: Return res
21: End Function
22:
23: Public Shared Function GetDescriptionsEnum(ByVal EnumConstant As Type, ByVal value As String) As System.Enum
24: Dim res(-1) As String
25: For Each ec As System.Enum In System.Enum.GetValues(EnumConstant)
26: ReDim Preserve res(UBound(res) + 1)
27: If value = GetEnumDescription(ec) Then
28: Return ec
29: End If
30: Next
31: Return Nothing
32: End Function
33:
* Funktionen von http://blog.dahead.de/howto-vb-net-enums-mit-beschreibungen-versehen übernommen

Combobox an Enum binden
1:cbx_Combobox.Items.AddRange(Functions.GetEnumDescriptions(GetType(RecordingPublishType)))


SelectedItem der Combobox mit Enumwert auswählen
1:cbx_Combobox.SelectedItem = Functions.GetEnumDescription(.PublishingType)


SelectedValue in Enuminstanz schreiben
1:Dim en_Type as RecordingPublishingType
2:en_Type = Functions.GetDescriptionsEnum(GetType(RecordingPublishType), cbx_Combobox.SelectedItem)
1 Kommentar
Kommentar schreiben

22.03.2010
Der Blog ist da
Blog

Endlich erwacht der Blog zum Leben. Lange hat es gedauert, bis ich mit der Blogengine.NET an die Grenzen gestoßen bin und ich mich dazu entschieden habe, etwas eigenes zu programmieren. Mit der gesammelten Erfahrung ging es dann auch richtig schnell voran. Auch wenn noch längst nicht alle Funktionen eingebaut sind und der Style nur aus der Not schnell entstanden ist, möchte ich online gehen!

Warum workaday .NET?
Wer kennt das nicht, man programmiert den ganzen Tag an einen Problem und irgendein sehr hartnäckiger Brocken stellt sich immer wieder in den Weg. Oder die Momente, wo man etwas neues kennen gelernt hat, was man schon so lange gebrauchen hätte können, und man einfach nur noch grinsend am Monitor sitzt. Für genau diese Theman habe ich diesen Blog programmiert, damit ich und andere auserwählte Poster ihre alltäglichen Erfahrungen mit .NET teilen können.

Der Blog ist noch nicht fertig, aber das geht schon
  • Anzeige von Blogeinträgen inkl. ein paar Informationen, wie Author, Zeit, Thema uvm.

  • Kommentare zu Posts

  • Benutzeradministration mit 3 verschiedenen Rollen

  • User- sowie Seitenzähler, um zu sehen, wie viele Leute sich denn hier herum tummeln

  • Facebook Schnittstelle

  • neu: Bewertung der Posts

  • neu: RSS Schnittstelle


Was kommt denn noch?
  • Hoffentlich viele Posts

  • Administration des eigenen Benutzerkontos (momentan kann man nur eins anlegen und sich anmelden, mehr geht nicht)

  • Ein Sub-Blog für weitere Themen

  • Der Style wird noch verbessert

  • Weitere kleine Sachen wie Tag-Cloud, Archiv, Suche uvm.

3 Kommentare
Kommentar schreiben

Du bist angemeldet als: Gast User online: 2 Seitenzähler: 73134
 
  Impressum Datenschutz