Blog Schröder

Sammlung von Codeschnipseln zu Programmierproblemen.
Daten aus fremden Quellen unterliegen deren Rechten.
Siehe auch: Disclaimer auf www.computer-schroeder.de

Dienstag, 11. August 2009

Web-Zugriff auf SQL Server

Der SQL Server 2005 erlaubt einer Web-Lösung (hier PHP) keinen Zugriff auf eine DB-Tabelle? Hier ein Beispiel für eine Fehlermeldung:

Warning: mssql_query() [function.mssql-query]: message: Die SELECT-Berechtigung wurde für das 'xxxx'-Objekt, 'yyyy'-Datenbank, 'dbo'-Schema verweigert. (severity 14) in C:\www\zzzz.php on line 26

Lösung:
Es gibt den speziellen Datenbankbenutzer *.IUSR_* (* für lokale Bezeichnungen). Diesen Benutzer muß man nicht selbst anlegen.
Über die Datenbankeigenschaften, Register Berechtigungen muß man ihm die Rechte für CONNECT, DELETE, INSERT, SELECT, UPDATE (soweit nötig) eintragen. Achtung, bei den Eigenschaften des Nutzers selbst ist das weder sichtbar noch möglich.

Hintergrund:
Der Nutzer IUSR - der bei Microsoft auch in anderen Kontexten existiert - ist speziell für anonyme Internetbenutzer gedacht, wie sie typischerweise bei Webbenutzung auftreten. Das heißt nicht, daß jeder Nutzer nun per DELETE einfach in der Datenbank irgendwas löschen kann, sondern nur, daß dies die Oberfläche darf, die der Nutzer benutzt. Nur wenn das PHP-(/ASP...)Programm von sich aus ein DELETE schickt, wird dies ausgeführt.
Beachten: die berühmte SQL-Injection (Es darf dem Benutzer nicht möglich sein, irgendwo einen SQL-Befehl einzutragen, der dann ungewollte Operationen ausführt - s. http://de.wikipedia.org/wiki/SQL-Injection).

Labels: , , , , , , , , , ,

Donnerstag, 10. Januar 2008

AJAX 1.0-enabled ASP.NET 2.0 program - Runtime Error

Labels: , , ,

Freitag, 21. Dezember 2007

Fehler beim Zugriff auf die IIS-Metabasis

Das Konto, welches ASP.Net ausführt, hat im .Net FW keine Berechtigung, die Metabasis zu lesen. Normalerweise wird das bei der Installation von .Net automatisch gesetzt. Leider nur, wenn dann schon die IIS installiert sind. Wenn man IIS NACH .NET installiert, muß man das manuell machen:

Konsole: (als Admin? - weiß ich nicht) im Windows Verzeichnis:
>> cd Microsoft.Net\Framework\v2.0.'blabla'
>> aspnet_regiis -i -enable

Dann sollte es klappen :) [nach 2 Stunden Suche gefunden bei: http://groups.google.de/group/microsoft.public.de.inetserver.iis.asp/browse_frm/thread/9ad6ae63f302e82e/ce63891555a491a3?lnk=st&q=Fehler+beim+Zugriff+auf+die+IIS-Metabasis&rnum=1&hl=de#ce63891555a491a3]

Labels: ,

Freitag, 16. November 2007

Ereignis: Seite wurde geschlossen

Ein solches Ereignis gibt es leider nicht (und kann es nicht geben).
Um es annähernd zu simulieren, gehe ich folgendermaßen vor:
1) Das der Seite zugrundeliegende Objekt bekommt eine date-Eigenschaft LastContact
2) Die Seite läßt einen Timer laufen, in dessen Tick-Ereignis LastContact mit dem aktuellen Zeitstempel gefüllt wird. Der Trick: beim Schließen der Seite hört der Timer auf zu laufen und die Eigenschaft bleibt auf dem letztzugewiesenen Zeitstempel stehen.
3) Eine Serveranwendung läßt ebenfalls einen Timer laufen, in dessen Tick die LastContact-Eigenschaft mit der aktuellen Zeit verglichen wird. Wird ein Limit überschritten, dann ist bekannt, daß die Seite nicht mehr existiert.

Code:
1) die Eigenschaft:
Public Class Objekt
Private mLastContact As Date
Public Property LastContact() As Date
Get
Return mLastContact
End Get
Set(ByVal value As Date)
mLastContact = value
End Set
End Property
...
2) der Objekttimer:
ASPX:
<asp:Timer ID="Timer" runat="server" Interval="5000" />
ASPX.VB:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If not Page.IsPostBack Then
Timer.Interval = CycleTime
...
3) der Servertimer:
Private loopTimer As System.Timers.Timer
Private New(...
loopTimer = New System.Timers.Timer
AddHandler loopTimer.Elapsed, AddressOf OnTimedEvent
loopTimer.Interval = SERVERLoopTimerInterval
loopTimer.Enabled = True
' Der Timer läuft so lange diese Klasse besteht (wird praktisch nie beendet)
GC.KeepAlive(loopTimer)
...
End Sub
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As System.Timers.ElapsedEventArgs)
'prüfe, ob Objekt als wartend eingetragen ist, obwohl nicht mehr aktiv
If (Now - obj.LastContact).Minutes * 60000 + _
(Now - obj.LastContact).Seconds * 1000 + _
(Now - obj.LastContact).Milliseconds >= 3 * CycleTime Then obj.istFrei...
End If
...
End Sub

Labels:

Donnerstag, 11. Oktober 2007

ASP.NET-Benutzersteuerelement programmgesteuert erstellen

1. Stellen Sie sicher, dass die @ Control-Direktive des Benutzersteuerelements ein ClassName-Attribut enthält, das dem Benutzersteuerelement eine Klasse zuweist, um das Benutzersteuerelement strikt zu typisieren.
<%@ Control className="MyUserControl" %>
2. Erstellen Sie in der Seite, in der Sie mit dem Benutzersteuerelement arbeiten möchten, unter Verwendung der @ Reference-Direktive einen Verweis auf das Benutzersteuerelement.
Beim programmgesteuerten Erstellen eines Benutzersteuerelements steht der ASP.NET-Webseite die strikte Typbindung für das Benutzersteuerelement erst zur Verfügung, nachdem ein Verweis darauf erstellt wurde. Mit folgendem Code wird z. B. ein Verweis auf ein Benutzersteuerelement erstellt, das in der Datei MyUserControl.ascx erstellt wurde.
<%@ Reference Control="MyUserControl.ascx" %>

Hinweis
Verwenden Sie @ Reference, wenn Sie beabsichtigen, das Steuerelement programmgesteuert zu laden.
Verwenden Sie @ Register, wenn Sie der Seite ein Benutzersteuerelement deklarativ hinzufügen.
3. Erstellen Sie mit dem Klassennamen des Steuerelements eine Instanzvariable für das Benutzersteuerelement. Die Klasse ist Teil des ASP-Namespaces.
Protected Spinner1 As ASP.Spinner
4. Erstellen Sie im Code eine Instanz des Benutzersteuerelements, indem Sie die LoadControl-Methode aufrufen.
5. Weisen Sie je nach den Erfordernissen Eigenschaftenwerte zu, und fügen Sie das Steuerelement dann der ControlCollection-Auflistung eines Containers auf der Seite zu.
Hinweis
Wenn Sie dem ControlCollection-Objekt mit der Add-Methode Steuerelemente hinzufügen, werden die Steuerelemente in der Reihenfolge ihrer Verarbeitung in der Auflistung platziert. Wenn Sie ein Steuerelement an einer bestimmten Position in der Auflistung hinzufügen möchten, verwenden Sie die AddAt-Methode und geben die Indexposition an, an der Sie das Steuerelement speichern möchten.

Beispiel
<%@ Page Language="VB" %>
<%@ Reference Control="~\Controls\Spinner.ascx" %>

<script runat="server">
Private Spinner1 As ASP.Spinner
Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs)
    Spinner1 = CType(LoadControl("~\Controls\Spinner.ascx"), _
        ASP.Spinner)
    ' Set MaxValue first.
    Spinner1.MaxValue = 20
    Spinner1.MinValue = 10
    PlaceHolder1.Controls.Add(Spinner1)
End Sub

Protected Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs)
    Label1.Text = Spinner1.CurrentNumber.ToString()
End Sub
</script>
<html>
<head id="Head1" runat="server">
  <title>Load User Control Programmatically</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:PlaceHolder runat=server ID="PlaceHolder1" />
      <br />
      <asp:Button ID="Button1" runat="server"
        Text="Button"
        OnClick="Button1_Click" />
      <br />
      <br />
      <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    </div>
  </form>
</body>
</html>
(Auszug von http://msdn2.microsoft.com/de-de/library/c0az2h86(VS.80).aspx)

Labels: , , ,

Freitag, 5. Oktober 2007

Wartemeldungen für Benutzer - Response.write

http://www.devtrain.de/news.aspx?artnr=866

Labels: ,

AutoCompleteExtender - Clientseitig auf Auswahl reagieren

http://blog.thomasbandt.de/53/1689/de/aspnet/aspnet-ajax/autocompleteextender ---clientseitig-auf-auswahl-reagieren.aspx
(Leerzeichen entf.)

Labels: , ,

Freitag, 7. September 2007

verlorenen Benutzer ASPNET wiederherstellen

Zuerst: aspnet_regiis /u (Deinstallation ASP.NET)
Dann: aspnet_regiis /i (Installation ASP.NET)
Protokolle dazu heißen ASPNETSetup_0000i.log und liegen in
C:\Dokumente und Einstellungen\Username\Lokale Einstellungen\Temp

Labels: , , ,

Freitag, 31. August 2007

Serverholder

Eine zentrale (Server)-Klasse, die auch unter ASP.NET dank Timer "ewig" lebt.

Public Class ServerHolder
' Enthält die einzige Serverinstanz und kann diese an andere Klassen übergeben
Shared ServerinstanceExists As Boolean = False

' Diese Variable enthält die einzige Serverinstanz
Shared WithEvents mServer As TMServer

' Gibt die (einzige) Instanz der Serverklasse zurück
' Wenn die Serverinstanz nicht existiert, wird Nothing zurückgegeben
Shared Function GetServer() As TMServer
If Not ServerinstanceExists Then
mServer = New Server
ServerinstanceExists = True
End If

Try
Return mServer
Catch ex As Exception
MsgBox("Es konnte keine Serverinstanz übergeben werden" & vbCrLf & ex.Message)
Return Nothing
End Try
End Function
End Class
-----------------------------------------
Public Class Server
Shared serverIsRunning As Boolean = False
Private loopTimer As System.Timers.Timer
'Variablen, Methoden usw.
Private mStatus As ...
Public Property Status() As ...
...
Public Sub New()
If serverIsRunning Then
MsgBox("Server läuft bereits!")
Exit Sub
End If
serverIsRunning = True

'Erzeuge die Timerinstanz
loopTimer = New System.Timers.Timer
'übergib den Behandler für den Timer
AddHandler loopTimer.Elapsed, AddressOf OnTimedEvent
' Setze Interval
loopTimer.Interval = 10000
loopTimer.Enabled = True
' Der Timer lebt bis zum "Ende"
GC.KeepAlive(loopTimer)
...
End Sub
End Class
----------------------------------------------------
'Zugriff auf die einzige Serverinstanz
Class Irgendwas
Shared Server As Server = ServerHolder.GetServer
...
Dim x = Server.PublicVar
Server.PublicMethode()
...
End Class

Labels: , , ,