Problem beim Updaten eines GridViews bei Verwendung einer ObjectDataSource

Gestern hab ich mich mind. 2 Stunden mit der Error: “… could not find a non-generic method …” abgeärgert bis ich dann zu folgenden Blogeintrag gelangt bin, der dies auf perfekte Art und Weise erklärt und nun geht auch wieder alles 😉

Issues updating a DataGrid row when using an ObjectDataSource and DataSet

I have been having issues using the DataGrid’s built in Edit and Update features when the DataGrid was using the ObjectDataSource.  The code generated by the IDE was causing a “could not find a non-generic method” error when committing the changes to an edited row in a DataGrid control.

Here is my analysis and solution:

The root of the problem has to do with the TableAdapter and its configuration wizard within the DataSet.xsd.

By default, Visual Studio will enable the “Refresh the data table” option on the “Advanced Options” dialog accessible via a button in the lower left corner of the “Enter a SQL Statement” page of the TableAdapter Configuration Wizard.  If the “Refresh the data table” checkbox is checked, it will append a SELECT statement to the end of the UPDATE and INSERT statements to “retrieve identity column values, default values, and other values calculated by the database” of the row that was just updated.  To do this, it needs the “<PKField>” in addition to the “original_<PKField>” to be sent from the DataGrid control .  When the column property for the primary key is set to ReadOnly = True, the DataGrid will not include the “<PKField>” in its Parameters collection during the Update method call.  (note: <PKField> is the field name of your primary key as in “ID”, or “original_ID”)

When ever we Update from the DataGrid, the “original_<PKField>” will be sent.  This is good. It’s the additional requirement of sending the “<PKField>” for the additional SELECT statement at the end of the Update query that is messing up our DataGrid’s functionality.

In other words, if the DataGrid is bound to the methods in the TableAdapter via an ObjectDataSource, and if the primary key column of the DataGrid is set ReadOnly=True, the DataGrid control will not pass the primary key to the Update and Insert methods of the TableAdapter even though those methods require it.  Instead, it will only include the “original_<PKField>”which it will use to locate the correct record to update.

Disabling the “Refresh the data table” checkbox on the “Advanced Options” dialog during configuration of the TableAdapter makes the most sense to me and has the least impact on design and functionality while still allowing the IDE to generate most of the code.

Some people have suggested changing the OldValuesParameterFormatString of the ObjectDataSource from “original_{0}” to simply “{0}”, but this then causes the “original_<PKFieldName>” (i.e. “original_ID”), which is still there in the parameters collection of the ObjectDataSource, to never be initialized (i.e. null will be passed in the Parameters collection during the Update and Insert) by the GridView, resulting in the “Value cannot be null” error if your field cannot be null.  Some people benifited from the OldValuesParameterFormatString fix, but I believe it was because their fields could be null.

.NET und Java

Java Net Ofuturezone.ORF.at Hardcore:

“Leuchtfeuer für offene Standards”

Sun Microsystems hat die stufenweise Freigabe der WSIT-Software-Suite und mehrerer Entwicklerprogramme bekannt gegeben, die Microsofts .NET-Framework mit Suns Java Platform verbinden. TOP-Manager von Oracle, IBM, Motorola, RedHat und anderen haben applaudiert.

Auf der 11. JavaOne, der jährlichen Großkonferenz für Java-Entwickler, die am Freitag zu Ende ging, wurde dem Trend zu Open-Source-Software deutlicher Tribut gezollt.

Vor insgesamt 14.000 Teilnehmern aus 65 Ländern verkündete Jonathan Schwartz, der erst im April die Führung von Sun Microsystems übernommen hatten, dass der Quellcode einer ganzen Reihe von Programmen offengelegt werde.

Was mir jedoch persönlich an dem Artikel am meisten gefallen hat war die Ankündigung der Interoperabilität zwischen .NET und Java. Ich bin es selber Leid ewig lange Diskussionen zu führen welches Programmierframework besser sei. Warum ich momentan .NET einsetze und nicht wieder auf Java programmiere oder wenn man mal mit anderen Firmen Daten austauschen will oder Dienste nutzen will sich immer die Frage stellen zu müssen: “In was könnte das wohl programmiert sein und kann ich damit arbeiten?”

Für .Net und Java könnten dieses Frage und Antwort Spiel in gewissen Bereichen bald der Vergangenheit angehören:

.NET und Java

Die wichtigste davon ist Suns “Web Services Interoperability Technology” [WSIT], die das Microsoft.Net Framework mit Suns Java Platform verbindet – die beiden dominierenden Software-Plattformen zur systemübergreifenden Entwicklung von Web-Applikationen zusammenschaltet.

Ich bin ja mal gespannt was uns die Zukunft so bringen wird.

SQL Injections unter Java abfangen

Das Projekt das Flo und ich gerade in Arbeit haben zeigt uns immer wieder neue Möglichkeiten die uns Java und AJAX bieten. Es werden fast täglich neue Ideen geboren und hinzugefügt und wir freuen uns schon euch allen unsere Arbeit zeigen zu können.

Doch zuerst ein Hoch an Java welches es wie auch das .NET Framework schafft, SQL Injectinos selbst zu handlen, was mir persönlich einiges an Arbeit abnimmt bzw. erspart (nachdem ich den Replacer zuerst händisch geschrieben habe 😉 ). Um euch diese Arbeit zu ersparen hier das Code Sample mit PreparedStatement- welche fast genauso funktionieren wie normale Statement Objekte, jedoch einige Zusatzfeatures bieten.

String query = “INSERT INTO tbl_feed (user_ID, feedurl, feedname) VALUE (? ,?, ?)”;

PreparedStatement pstmt= conn.prepareStatement(query);
pstmt.setString(1, userID);
pstmt.setString(2, feeds[i][1]);
pstmt.setString(3, feeds[i][0]);

pstmt.executeUpdate();

Funktionsweise:
Man verwendet PreparedStatement genauso wie Statement mit einem großen Vorteil, man baut den Query String zusammen und alle dynamisch Werte werden mit einm “?” ersetzt.
Danach kann man jedes “?” mittels setString(position, string) ersetzen und das PreparedStatement Objekt handled das Escapen der nötigen Zeichen selbstständig.