Hier in kurzes Codebeispiel, wie man aus einer HTML Farbe eine DotNet-Farbe machen kann.
Die Umwandlung ist denkbar einfach, denn das .NET Framework hat dafür bereits eine Funktion:
System.Drawing.ColorTranslator.FromHtml(#000000 )
Das wäre auch schon das ganze Geheimnis!
Ich habe gerade ein Tool gefunden mit dem man die MSDE bzw. den SQL Server auch ohne Enterprise Manager verwalten kann. Es bietet nicht die komplette Palette aber die wichtigsten Objekte können damit verwaltet werden Tabellen / Stored Procedure / User...
Dieses macht natürlich besonders bei der MSDE nützlich, da man lizenzrechtlich nicht mit dem Enterprise Manager auf die MSDE zugreifen darf!
http://www.aspenterprisemanager.com/
Dieses Tool ist ein webbasiertes Managementtool und OpenSoruce.
Man kann an eine Stored Procedure im SQL - Server keine Parameter vom Typ Array übergeben. Für den IN Operator einer SQL WHERE Klausel benötigt man aber eine Auflistung von kommaseparierten Werten. Wie das mit einem nvarchar / string Parameter funktioniert habe ich bereits in diesem Blog erklärt. Nun möchte ich aber auch noch Zeigen, wie man dieses mit dem Datentyp Integer / int hinbekommt.
Eine Liste von Parameter kann man nur als String an eine SP übergeben - also: '1,2,3'.
CREATE PROCEDURE [dbo].[GaliNeo_Store_ProductListByProductId]
@productIds nvarchar (1000)
AS
SELECT * FROM GaliNeo_Store_Product P WHERE (P.[ProductID] in (SELECT ID from fn_Split_varcharToint(@productIds)) )
GO
Der Trick hier ist eine userdefined function zu nutzen, die aus dem nvarchar Parameter eine "Tabelle" macht, die dann ohne Probleme mit dem IN Parameter verarbeitet werden kann.
Die userdefined function sieht so aus:
CREATE Function fn_Split_varcharToint (@IDs nvarchar(100) )
Returns @Tbl_IDs Table (ID Int) As
Begin
-- Append comma Set @IDs = @IDs + ','
-- Indexes to keep the position of searching Declare @Pos1 Int Declare @pos2 Int
-- Start from first character Set @Pos1=1 Set @Pos2=1
While @Pos1<Len(@IDs) Begin Set @Pos1 = CharIndex(',',@IDs,@Pos1) Insert @Tbl_IDs Select Cast(Substring(@IDs,@Pos2,@Pos1-@Pos2) As Int) -- Go to next non comma character Set @Pos2=@Pos1+1 -- Search from the next charcater Set @Pos1 = @Pos1+1 End Return End
Für alle die keine Lizenz von CodeSmith kaufen möchten, aber auf den Luxus der Codegeneriung nicht verzichten möchten, gibt es eine Alternative.
Diese Alternative nennt sich MyGeneration und ist zu finden unter: http://www.mygenerationsoftware.com
Dieses Tool ist lizenzkostenfrei und biedet alles was man benötigt. Zumindest ist es in meinem Bereich noch nicht an seine Grenzen gekommen. Was mir lediglich fehlt ist eine Art Batch-Job, da es schon manchmal lästig ist die einzelne Gerneriung von Hand anzustoßen.
Es gibt auch schon für jede Menge Zwecke / Anwendungsfälle Templates - natürlich auch für DotNetNuke (!). Das Erstellen von MyGeneration-Templates finde ich etwas besser und intuitiver gelößt - kann aber auch nur Einbildung sein 
Beim Schreiben von Stores Procedure möchte man von Zeit zu Zeit div. Elemente dynamisch auswählen lassen. Ein gutes Beispiel dafür ist z.B. der Order By - Part einer Abfrage.
Um per Parameter dieses zu steuern hier ein Stückchen Code:
declare @order int set @order = 3
SELECT * FROM GaliNeo_Store_Product P LEFT JOIN GaliNeo_Store_CatProduct CP ON CP.[ProductId] = P.[ProductId]
WHERE CP.[CategoryID] = 19
order by
case @order when 'productname' then [ProductName] when 'productnumber' then P.[ProductNumber] else null end,
case @order when 'productid' then P.[ProductId] else null end
Diesen Code habe ich im SQl Query Analyzer geschrieben und ausgeführt.
Das hier zwei case - Bereiche genutzt werden liegt an den unterschiedlichen Datentypen. ProductName ist ein nvarchar und ProductId ein int Datentyp. Entweder führt man eine Konvertierung durch, besser ist aber wenn man mit zwei Konstrukten arbeitet.
Eine andere Möglichkeit wäre folgende:
declare @order int set @order = 3
SELECT *, case when @order = 1 then [ProductName] when @order = 2 then Convert(nvarchar,P.[Productid]) when @order = 3 then Convert(nvarchar,P.[ProductTypeId]) end as OrderCol FROM GaliNeo_Store_Product P LEFT JOIN GaliNeo_Store_CatProduct CP ON CP.[ProductId] = P.[ProductId]
WHERE CP.[CategoryID] = 19
order by OrderCol
Mit dem Usercontrol URLControl von DNN kann man auf die interne Dateiverwaltung von DNN zugreifen.
Die Einbindung habe ich in einem anderen Artikel bereits erläutert. Hier nur noch kurz der benötigte Code für die ASCX-Datei:
<%@ Register TagPrefix="Portal" TagName="URL" Src="~/controls/URLControl.ascx" %>
<portal:url id="ctlURL" runat="server" width="300" showtabs="false" showfiles="true" showUrls="false" urltype="F" showlog="false" shownewwindow="false" showtrack="false"/>
Die Eigenschaft URL dieses Controls liefert allerdings bei der Auswahl von Dateien lediglich so etwas wie "FileId=7". Um aber Bilder darstellen zu können muss dieses in einer URL umgewandelt werden. Die folgenden Funktion sind genau dafür da.
public string FileNameToImgSrc(string FileName) { string sSrc = GetRelativeFilePath(FileName) ; return this.PortalSettings.HomeDirectory + sSrc; }
public string GetRelativeFilePath(string FileName) { if (FileName.StartsWith("FileID=")) { int fileId = int.Parse(FileName.Substring(7)); FileController objFileController = new FileController(); DotNetNuke.Services.FileSystem.FileInfo objFileInfo = objFileController.GetFileById(fileId, this.PortalId); if (!(objFileInfo == null)) { return objFileInfo.Folder + objFileInfo.FileName; } else { return ""; } } else { return FileName; } }
Es gibt natürlich keine Weg zu verhindern, dass sich User Bilderrunterladen können, den Source Code anschauen oder was es sonst noch so im Context-Menü des Browsers rumtreibt.
Manchmal möchte der Kunden aber einfach, dass der Rechtsklick auf einer Seite unterbunden wird. Hier ist ein wenig Javascript Code, der genau diesen Rechtsklick abfängt.
<script type="text/javascript"> <!-- function right(e) { if (document.layers && e.which == 3) { alert("Der Rechtsklick geht nicht!"); return false; } else if (document.all && event.button == 2) { alert("Der Rechtsklick geht nicht!"); return false; } return true; }
document.onmousedown=right;
if (document.layers) { window.captureEvents(Event.MOUSEDOWN); } // --> </script>
Das Tool Reflector for .NET habe ich bereits vor ein paar Monaten als ein cooles Tool hier im Blog erwähnt. Jetzt habe ich vor kurzen ein noch geileres Plug-In dafür entdeckt:
Reflector.FileDisassembler
Das Tool ist von Denis Bauer und erzeugt Source-Code Dateien aus einer .NET Assembly. Es wird einfach in den Reflector for .NET eingebunden und schon kann man sich nicht nur Methoden anschauen sondern sich direkt ganze Files erzeugen lassen :)
Ein wirklich cooles Tool für .NET ....
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
|