Das Schreiben in das Eventlog von Windows ist mit Sicherheit kein Geheimnis mehr und es gibt sehr viele Beispiele dafür. Hier zeige ich nur schnell, wie man in ein eigens - also nicht system, security, usw. - Eventlog von .NET (DotNet) ansprechen kann.
Wie eigentlich fasst alles bei mir ist das in C# geschrieben...
EventLog eLog = null; // Holds the event log reference. EventLogEntry eLogEntry = null; // A single entry.
// To create a special log, then you need to // register an event source first (as you already did in // your example code). if ( ! EventLog.SourceExists( "GaliNeo_Job_Source" ) ) {
// Create the new event source. EventLog.CreateEventSource( "GaliNeo_Job_Source", "GaliNeo_Job_Log", "." );
}
// Register the new event source. eLog = new EventLog( "GaliNeo_Job_Log" ); eLog.Source = "GaliNeo_Job_Source";
eLog.WriteEntry("My Message,EventLogEntryType.Information) ;
// or EventLog.WriteEntry( "GaliNeo_Job_Source", "Special Message", EventLogEntryType.Information, 12, 22 );
Mit den paar Zeilen C# ist das erledigt und man kann eigene EventLog schreiben und später die Daten etwas besser trennen.
Heute ist die neuste Version der Open Source Portalengine DotNetNuke ® zum Download bereitgestellt wurden. Zunächst gibt es nur die Version inkl. Source.
Es ist aber davon auszugehen, dass es auch bald wieder einer Version nur mit den benötigten Dateien für eine Installation gibt.
Änderungen in dieser DotNetNuke ® Version können unter support.dotnetnuke.com nachgelesen werden.
Das Downloadfile enthält keine Dokumentation von DNN, dieser werden derzeit an das neue Branding angepasst und zukünftig einzeln verfügbar sein.
Bei der Installation UNBEDINGT die Readme Datei beachten!
Super klasse (!) ich habe heute den gesamten Nachmittag verschwendet und habe mal wieder an mir und meinen Verstand gezweifelt!
Ich arbeite gerade an einem TabPage - Control. Als Vorlage habe ich den Wizard von DotNetNuke genommen und den Rest reinprogrammiert. Alles gar kein Problem - nur etwas Arbeit.
Dann hatte ich aber das Problem, dass z.B. die ASP:Textbox ihren Viewstate verlor. Nach langen suchen und google, ohne jeden Erfolg, habe ich dann alles auskommentiert und dann Stückchen für Stückchen wieder reingenommen.
Was soll ich sagen, diese Zeile:
_tabCtrl.Rows.Insert(0,_parentTr) ;
ist dafür verantwortlich.
Ich habe ein Tabelle und füge dynamisch eine Zeile an erste Stelle ein... dadurch scheint dann der ViewState aller Elemente, die darunter angeordnet sind weg zu sein.
Jetzt setze ich halt einfach eine zweite Tabelle drüber und dann läuft es.
Also ich bin richtig froh, dass DotNetNuke Opensource ist. Da wir mittlerweile mehrere große Projekte mit DotNetNuke realisiert haben oder gerade noch dabei sind, kann die Abhängigkeit von einem Anbieter für unsere Kunden und deren Geschäftsmodelle im Internet katastrophale Konsequenzen haben. Selbst wenn DotNEtNuke plötzlich nicht mehr frei und opensource wäre, könnten wir mit dem bisherigen STand 3.1 problemlos weiterentwickeln. Interessanterweise liefern die besten Argumente für DotNetNuke und Opensource-Software häufig genug die Fürsprecher anderer Programme ... wie auch hier
http://blog.gandke.de/CommentView,guid,6f0815c7-ff41-4b2a-a657-7512bb94c58e.aspx
Heute Abend habe ich mich mal mit der Scheduler-Technologie von DotNetNuke auseinandergesetzt. Ich habe zwar auch einen eigenen DotNetNuke unabhängigen Scheduler laufen, da ich mich aber mit dieser Seite von DNN noch nicht auseinandergesetzt habe und der Anwendungsfall nicht so zeitkritisch ist viel mein Entschluß auf diese Art der Implementierung.
Zunächst einmal habe ich mir die Dokumentation von DotNetNuke Scheduler Service durchgelesen - allerdings war dort nur sehr wenig über die Implementierung zu lesen.
Die Erstellung ist aber auch eigentlich super simple und somit ist eine Anleitung gar nicht wirklich erforderlich. Hier das Grundgerüst für einen DotNetNuke Scheduler Service:
using System; using DotNetNuke.Services.Exceptions ;
namespace GaliNeo.Modules.Events { public class NotifyScheduler : DotNetNuke.Services.Scheduling.SchedulerClient {
public NotifyScheduler(DotNetNuke.Services.Scheduling.ScheduleHistoryItem objScheduleHistoryItem) { this.ScheduleHistoryItem = objScheduleHistoryItem; }
public override void DoWork() { try { this.Progressing() ; this.ScheduleHistoryItem.Succeeded = true ; this.ScheduleHistoryItem.AddLogNote("GaliNeo Events - Notify User was successfully") ;
} catch(Exception exc) { this.ScheduleHistoryItem.Succeeded = false ; this.ScheduleHistoryItem.AddLogNote("EXCEPTION: " + exc.ToString()) ; this.Errored( ref exc) ; Exceptions.LogException(exc) ; } }
} }
Das Geheimnis ist eigentlich ganz einfach.
- Man erstellt eine Klasse und leitet diese von DotNetNuke.Services.Scheduling.SchedulerClient ab
- Es muss eine Methode (DoWork()) definiert werden, die von der DotNetNuke Engine aufgerufen wird
- Ganz wichtig ist, den Konstruktur nicht zu vergessen. Das ist mir zunächst passiert und ich wunderte mich, warum der Tast nicht ausgeführt wurde.
Innerhalb der Methode DoWork() kann man nun auf die Business-Logik eines Modules zugreifen, um z.B. Daten zu lesen, zu verändern und wieder zu speichern.
Es gibt wohl eine Einschränkung: Auf die MemberRole - Implementierung kann von einem Scheduler aus nicht zugegriffen werden, da der dafür erforderliche Kontext fehlt!
Seit zwei Jahren veranstalltet Microsoft Webcast. Das sind technische Vorträge / Präsentationen die man sich über das Internet anschauen kann.
Nun gibt es eine DVD mit allen bisherigen Webcast. Diese kann man bei Microsoft kostenlos bestellen:
hier bestellen..
Hier eine kleine Übersicht, wie man in .NET runden kann ..
Abrunden:
Wenn man immer abrunde möchte muss man die Funktion Math.Floor verwenden. Floor bekommt als Parameter einen Double-Typ und gibt den nächst kleinere Ganzzahl zurück.
Hier ein Beispiel:
System.Console.WriteLine("Floor " + System.Math.Floor(1.1)); System.Console.WriteLine("Floor " + System.Math.Floor(1.5)); System.Console.WriteLine("Floor " + System.Math.Floor(1.9));
Liefert als Ergebnis folgends Zurück:
Floor: 1 Floor: 1 Floor: 1
Aufrunden:
Im Gegensatz dazu liefert die Funktion System.Math.Ceiling immer die nächst höhere Ganzzahl
Beispiel:
System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.1)); System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.5)); System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.9));
Liefert folgendes zurück:
Ceiling 2 Ceiling 2 Ceiling 2
"Normals Runden"
Die Funktion System.Math.Round rundet dagegen in Abhängigkeit der letzten Zahl auf oder ab.
System.Console.WriteLine("Round " + System.Math.Round(1.1)); System.Console.WriteLine("Round " + System.Math.Round(1.5)); System.Console.WriteLine("Round " + System.Math.Round(1.9));
Liefert als Ergebnis:
Round 1 Round 2 Round 2
Wer schon immer mal in SQL oder einer Stored Procedure die Kalenderwoche eines Datums ermittelt wollte .. hier ist die Lösung.
Das SQL Statement Select Datepart(Week, Getdate()) liefert die Kalenderwoche des aktuellen Datums. Leider ist die ermittelte Kalenderwoche nicht nach europäischer bzw. deutscher Norm. Es wird automatisch der 1. Januar in die 1. Kalenderwoche gesetzt.
Dieses Stored Procedure ermittelt die Kalenderwoche nach europäischer Norm.
CREATE PROCEDURE dbo.ISOweek ( @DATE datetime ) AS BEGIN DECLARE @ISOweek int
SET @ISOweek = DATEPART(wk, @DATE) + 1 - DATEPART(wk, CAST( DATEPART( yy, @DATE ) AS CHAR(4) ) + '0104' ) -- Jan 1-3 may belong to the previous year IF ( @ISOweek = 0 ) BEGIN DECLARE @Date2 datetime SET @DATE2 = CAST( DATEPART( yy, @DATE ) - 1 AS CHAR(4) ) + '12' + CAST( 24 + DATEPART( DAY, @DATE ) AS CHAR(2) ) -- rekursiver Aufruf :( EXEC @ISOWeek = ISOWeek @DATE2 SET @ISOWeek = @ISOWeek + 1 END --Dec 29-31 may belong to the next year IF ( ( DATEPART( mm, @DATE ) = 12 ) AND ( ( DATEPART( dd, @DATE ) - DATEPART( dw, @DATE) ) >= 28 ) ) SET @ISOweek=1 RETURN(@ISOweek) END
Um das allerdings auch in einer Stored Procedure (oder direkt im SQL-Statement) zu verwenden kann man auch eine Userdefined function anlegen:
CREATE FUNCTION dbo.fn_ISOweek ( @DATE datetime ) RETURNS int AS BEGIN DECLARE @ISOweek int
SET @ISOweek = DATEPART(wk, @DATE) + 1 - DATEPART(wk, CAST( DATEPART( yy, @DATE ) AS CHAR(4) ) + '0104' ) --Jan 1-3 may belong to the previous year IF ( @ISOweek = 0 ) BEGIN DECLARE @Date2 datetime SET @DATE2 = CAST( DATEPART( yy, @DATE ) - 1 AS CHAR(4) ) + '12' + CAST( 24 + DATEPART( DAY, @DATE ) AS CHAR(2) ) -- rekursiver Aufruf: EXEC @ISOWeek = ISOWeek @DATE2 SET @ISOWeek = @ISOWeek + 1 END --Dec 29-31 may belong to the next year IF ( ( DATEPART( mm, @DATE ) = 12 ) AND ( ( DATEPART( dd, @DATE ) - DATEPART( dw, @DATE) ) >= 28 ) ) SET @ISOweek=1 RETURN(@ISOweek) END
Infos zur SQL Funktion DATEPART gibt es unter: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_da-db_2mic.asp
Wir suchen zur Entwicklung von Skins für DotNetNuke einen Webdesigner mit guten HTML / CSS-Kenntnissen auf freiberuflicher Basis. Schwerpunkt liegt auf der grafischen Gestaltung.
Bei Interesse bitte Kontakt per eMail aufnehmen mit Michael Gandke (kontakt2005 @ gandke.de). Bitte zwei oder drei bisherige Projekte / Websites (inkl. URL) mit angeben.
Mal in eigener Sache: Wir suchen zur Entwicklung von Webanwendungen unter Microsoft .NET einen Kollegen mit guten ASP.NET-Kenntnissen zur Festanstellung (Großraum Mönchengladbach). Die Zusammenarbeit kann auch freiberuflich auf Projektbasis erfolgen. SQL-Kenntnisse sollten ebenfalls vorhanden sein sowie Erfahrungen mit eCommerce / Online-Shops.
Entwickelt werden hauptsächlich Module für DotNetNuke unter C# und/oder VB.NET. Bei Interesse bitte Kontakt per eMail aufnehmen mit Michael Gandke (kontakt2005 @ gandke.de). Eine kurze Beschreibung der bisherigen Projekte reicht aus.
Es gibt in DotNetNuke keine Möglichkeit eine neu angelegt Gruppe (Rolle) allen oder nur einem bestimmten Teil von Usern zu zuordnen.
Da es heute bei mir schnell gehen mußte, habe ich das über SQL-Statements gelöst aber vielleicht bau ich ja auch mal ein Modul für DNN....
DotNetNuke verwaltet die Zuordnng von Usern und Rollen in zwei Systemen
- Ein eigenes System von DNN, besteht aus ein paar Tabellen
- Die Microsoft Implementierung von MemberRole
Ich erspare mich jetzt zu schildern, warum das so ist ....
Es ist darauf zu achten, dass alle beiden Bereiche von DNN aktuallisiert werden!
Hier die SQL-Befehle:
Declare @ApplicationId nvarchar(255) Declare @RoleGUI nvarchar(255) Declare @RoleId int
--Die interne GUI für das Portal SET @ApplicationId = '{59DFEA62-67E2-450E-A039-91ECA87FCDF4}' --Die eindeutige Kennzeichung einer Rolle in der ASPNET Implementierung SET @RoleGUI = '{D8N05067-B4BD-4ER9-9773-F1BAC67FF47G}' --Die eigene DNN Verwaltung SET @RoleId = 1
INSERT INTO aspnet_UsersInRoles ( UserId, RoleId ) SELECT U.UserID, @RoleGUI As RoleId FROM ASPNET_USERS U WHERE (ApplicationId = @ApplicationId) and (U.UserId not in (SELECT UR.UserId FROM aspnet_UsersInRoles UR WHERE UR.RoleId = @RoleGUI));
--SELECT Count(*) FROM ASPNET_USERSINROLES WHERE RoleId = @RoleGUI;--
INSERT INTO UserRoles ( UserId, RoleId, ExpiryDate ) SELECT U.UserId, @RoleId as RoleId, '03.08.2005' AS ExpiryDate FROM Users U WHERE U.UserId not in (SELECT UserId FROM UserRoles WHERE RoleId = @RoleId)
--SElECT Count(*) FROM UserRoles WHERE (RoleId = @RoleId)---
Wer bei der Erstellung von ASPX / ASCX eine Basisklasse verwendet, kann dabei Probleme bekommen.
Ich hatte bis her immer folgende Fehlermeldung in der VS.NET IDE beim designen von den ASPX / ASXC Seiten.
<Fehlermeldung> Die Datei konnte nicht im Web-Form-Desinger geladen werden. Korrigieren Sie den folgenden Fehler, und laden Sie sie dann erneut:
....
Stellen Sie sicher, dass alle auf der Seite verwendeten Klassen im Projekt erstellt oder referenziert wurde. </Fehlermeldung>
Nachdem ich die .Net-Sicherheitsrechtlinie von der Intranet-Zone auf Full-Trust gestellen habe, konnte VS.NET die ASPX / ASCX auch wieder darstellen.
In der letzten Zeit gab es immer wieder Probleme mit den Passwörtern von Host / Admin Accounts in DotNetNuke.
Mit der Version DNN 3.0.13 hat das Core-Team von DotNetNuke, die Schlüssel für die Passwort Verschlüsselung in die Web.config ausgelagert. Durch ein Update werden die Schlüssel jedes Mal überschrieben bzw. neu erzeugt.
Sollte man nun keine Datensicherung haben (was eigentlich eine Totsünde ist!), gibt es zumindest einen Trick, wie man Host und Admin Passwörter manuell zurücksetzen kann.
- Einfach als neuen User registrieren und das dort vergeben Passwort sich merken.
- Dann in die Datenbank gehen und das Passwort / PasswordSalt (bzw. den Wert der Felder) mit den Werten beim Host und/oder Admin austauschen. Diese Informationen liegen in der Tabelle "aspnet_Membership"....
Somit hat man zumindest den Zugang zu diesen Accounts wieder hergestellt.
Natürlich hilft das einem auch nicht, wenn man keine öffentlichen Registrierungen zulässt und man muss Zugriff auf die Datenbank der DotNetNuke - Installation haben.
Vor einiger Zeit habe ich bei DotNetNuke einen Fehler in der automatischen Anmeldung festgestellt.
Die User können über den Schalter "Anmeldedaten merken" ein automatisches Login durchführen lassen. Sollte ein Benutzerkonto nun gespert sein (z.B. durch falsche Eingabe von Benutzername / Passwort), dann wird beim LogIn dieses ignoriert und der User kann sich weiterhin automatisch anmelden.
Um das zu umgehen habe ich den Core-Code ein wenig modifiziert (ja ja .. nicht schön und gefällt mir auch selber nicht, war jetzt aber erst mal eine quick-and-dirty Lösung).
In der Klasse "compontens\Users\UserController.vb" die Funktion "GetCurrentUserInfo" modifizieren:
Dim objUser As UserInfo = CType(HttpContext.Current.Items("UserInfo"), UserInfo) If Not ObjUser Is Nothing Then Return objUser Else Return New UserInfo End If
Ersetzen durch:
Dim objUser As UserInfo = CType(HttpContext.Current.Items("UserInfo"), UserInfo) If Not ObjUser Is Nothing Then If objUser.Membership.LockedOut Then Dim _portalSettings As PortalSettings = PortalController.GetCurrentPortalSettings
FormsAuthentication.SignOut()
HttpContext.Current.Response.Cookies("portalaliasid").Value = Nothing HttpContext.Current.Response.Cookies("portalaliasid").Path = "/" HttpContext.Current.Response.Cookies("portalaliasid").Expires = DateTime.Now.AddYears(-30)
HttpContext.Current.Response.Cookies("portalroles").Value = Nothing HttpContext.Current.Response.Cookies("portalroles").Path = "/" HttpContext.Current.Response.Cookies("portalroles").Expires = DateTime.Now.AddYears(-30)
' Redirect browser back to portal Dim strURL As String = "" If _portalSettings.HomeTabId <> -1 Then strURL = NavigateURL(_portalSettings.HomeTabId) Else strURL = GetPortalDomainName(_portalSettings.PortalAlias.HTTPAlias, HttpContext.Current.Request) End If HttpContext.Current.Response.Redirect(strURL, True) Else Return objUser End If
Else Return New UserInfo End If
Dieser Weg ist noch keine wirklich sauber Lösung aber zumindest erst mal ein brauchbarer Bugfix. Wenn ich etwas mehr Luft haben, versuche ich eine andere Lösung zu finden.
Für große Seiten kann es hilfreich sein die zu übertragenden Bytes zu komprimieren. Dadurch können die Ladezeit optimiert werden.
Eine HTTPModule für .NET (DotNetNuke) gibt es unter http://www.blowery.org/code/HttpCompressionModule.html.
Die Installation ist sehr einfach und ist innerhalb von wenigen Minuten erledigt.
Zuerst die Dateien in das "\bin" Verzeichnis der Webanwendung kopieren.
blowery.Web.HttpCompress.dll
blowery.Web.HttpCompress.dll.xml
ICSharpCode.SharpZipLib.dll
ICSharpCode.SharpZipLib.dll.xml
Dann muss die Web.config angepasst werden:
Im Abschnitt configSection folgendes hinzufügen:
<sectionGroup name="blowery.web"> <section name="httpCompress" type="blowery.Web.HttpCompress.SectionHandler, blowery.Web.HttpCompress"/> </sectionGroup>
Das httpModul hinzufügen
<system.web> <httpModules> <add name="CompressionModule" type="blowery.Web.HttpCompress.HttpModule, blowery.web.HttpCompress"/> </ httpModules> </system.web>
In die Web.config aber nicht innerhalb der system.web folgende Zeilen einfügen
<blowery.web> <httpCompress preferredAlgorithm="deflate" compressionLevel="high"> <excludedMimeTypes> <add type="image/jpeg"/> <add type="image/gif"/> </excludedMimeTypes> <excludedPaths></excludedPaths> </httpCompress> </blowery.web>
Schon ist die Konfiguration abgeschlossen!
Aber VORSICHT! Bevor ein Update von DotNetNuke eingespielt wird, muss dass httpModul deaktiviert werden.
Eine Microsoft Veranstalltung hat gestern acht Personen zusammengeführt, die sich alle mit dem Thema DotNetNuke beschäftigen.
Viele kannte man nur aus dem Forum und es war eine sehr gute Gelegenheit mal endlich die Gesichter hinter den Namen zu sehen.
Kurzentschlossen ist dann nach ein paar Bierchen dieses Bild hier entstanden:

Es war ein sehr netter Abend und schnell waren wir uns einig, dieses in der Zukunft fortzusetzen. Immerhin gibt es eine ganze Menge Stuff rund um DotNetNuke.
Weiter Kommentare gibt es im unter http://blog.gandke.de und im Forum http://www.dnnportal.de
|