Donnerstag, 10. Dezember 2009

Clientseitige XML Datenbank - client-side XML db

Was ich im Moment versuche ist, eine Art clientseitige Datenbank zu erstellen. Das Prinzip ist folgendes, dass man in einem regulären XHTML Dokument versucht in einem hidden div Layer eine XML Struktur zu erstellen, die es erlaubt vom JavaScript aus über ein Objekt Daten in dieser Struktur zu erstellen und zu löschen. Auf diese Art und Weise benutzt man das Objekt als Schnittstelle zwischen den JavaScript Daten und der pseudo XML Datenbank in der Webseite. Anschliessend werden diese Daten als XML in eine hidden Textbox generiert. Von dort kann sie .NET auslesen und weiterverarbeiten. Mein Ziel ist es, das ganze so generisch wie möglich zu halten um es auch wiederverwenden zu können. Wenn jemand weitere Ideen hat, lasst es mich wissen.

What I am trying at the moment is to create something like a client-based database. The logic behind that is, that you try to store in a general XHMTL document a XML structure. This happens basicaly in a hidden div layer. Then you are able to store values in this structure and delete them as well. I want to add to this an object, that works like an interface between the XML db and the JavaScript code. Afterwards this data is generated into a hidden text-box, from where .NET can pick it up to work with the data. My goal is, to keep everything very generic, so it can be re-used. Any further ideas, let me know.

Mittwoch, 21. Oktober 2009

Vorsicht - Attention

Vorsicht zu dem Beitrag zuvor. Wenn man dann Werte ausliest aus dem HiddenField, sollte man bzgl. SQL injection oder codegefährdeten Elementen die Werte validieren. Denn im Grunde wäre es ein sehr leichtes, Werte abzuändern und damit Schaden zu verursachen. Ist eine gute Methode, aber mit Vorsicht zu geniessen, wie alles was mit JavaScript zu tun hat.

Attention to the post before. When reading out values from the HiddenField, you should be aware of sql injection or code harming elements. That means validate the values read out. Basically it would be very easy to manipulate the values and harm your application. The described method is a good one, but take care, like you always should, when working with javascript.

Dienstag, 13. Oktober 2009

Javascript & .NET

Dieser Post ist nur ein kleiner Tipp, für alle, die sich mit Javascript Cookies schwer tun und gerne Javascript mit .Net Technologie verbinden. I hatte die Aufgabe in einer Applikation im Front-End viel Javascript zu verwenden und es anschliessend im Back-End zu verarbeiten und das über mehrere Postbacks. Meine Lösung war, Werte des Javascripts in einem .Net hidden-field zu speichern, dann über .Net auszulesen und weiterzuverarbeiten, sei es in einer Session, bzw. Datenbank. Somit erreicht man viel clientseitige Funktionalität ohne .Net Postbacks, mit .Net Vorzügen bei einem Postback.

This post is just a little hint for all people, who find javascript cookie handling hard to do and would like to combine it with .Net technology. My job was to include into the front-end a lot of javascript and then working with it in the back-end through multiple post-backs. My solution was, to store the javascript values in a .Net hidden-field and then to read it out through the .Net technology to proceed in storing in a database or session. The pro of this way is, that you have a lot of client-side functionality without .Net post-backs, with the advantage of .Net when performing a post-back.

Umbraco certified


Nachdem ich jetzt 3 Jahre mit Umbraco arbeite und schon den Level 2 Kurs besuchte, habe ich die Zertifizierung gemacht und darf mich ab nun "Umbraco Certified Professional" nennen. Zertifizierung beinhaltete Level 1 und 2.
After working with Umbraco for 3 years and participating in the level 2 course, I decided to do the certification and can call myself now an "Umbraco Certified Professional". My certification was level 1 and 2.

Montag, 10. August 2009

ContentXXL Suche funktioniert nicht - search does not work

Wenn Sie das Problem haben, dass das Suchmodul nicht korrekt funktioniert im ContentXXL, dann kann es an Datenbankeinstellungen liegen. Bei jedem Suchbegriff gibt er immer eine "no results" Ausgabe an. Dann bitte den "Volltextindex" bei den Tabellen aktivieren, welche durchsucht werden sollen.

If you have the problem, that the search-module in ContentXXL does not work properly, then there reason for that could be database settings. If every keyword outputs the "no result" page, then please check the "fulltextindex" in your SQL db on the tables, where the search result will happen.

Freitag, 7. August 2009

Events im Page_Load abfangen - catch events in page_load

Manchmal könnte man einige Informationen einen Events schon im Page_Load benötigen. Hierzu kann man folgenden Code verwenden, damit dies funktioniert.

Sometimes you might need information of an event in the Page_Load. You can use this code to achieve this:

Page_Init
MyButton.OnClientClick = GetPostBackEventReference(MyButton);
Page_Load
string eventTarget = Request["__EVENTTARGET"];
if (!string.IsNullOrEmpty(eventTarget))
{
string[] arrNameParts = eventTarget.Split(Convert.ToChar("$"));
string strButtonName = arrNameParts[arrNameParts.Length - 1];
if(strButtonName == "MyButton")
Response.Write("Works");
MyButton_Click(null,null);
}

Der MyButton_Click event wird dann ausführen, was zu dem Button-Click gehört und somit wurde im Page_Load bereits verarbeitet.

The MyButton_Click event will then raise, what means, that the button-click already happend in Page_Load.

Donnerstag, 6. August 2009

Caching und Tracking - caching and tracking

Manchmal taucht das Problem auf, dass man gerne Seiten, welche gecached werden tracken will. Problem ist, wie kommt man an die Mischung aus gecachedten und aktuellen Daten?
Hier habe ich den Workaround wie folgt erledigt.
Per Javascript werden für die Seite relevante und gecachedte Daten als Querystring an die URL eines Imagefiles angehängt, welches allerdings auf eine aspx oder php oder jsp Seite verweist. In dieser (bei jedem Aufruf trotz Cache) Seite werden dann aktuelle Daten und Datenbankeintrag ausgeführt sowie Daten aus dem Querystring übernommen. Im Grunde ist es ein IFrame per Imagetag.

Sometimes you might have the problem, that you want to track cached pages. The issue is, how do you get to the mix of cached and runtime data?
I used a kind of work-around to achieve this.
Via javascript you get to the cached (for each tracking item equal) data in the page and then you add those as a query-string to the URL of an image-file that has been added and pointing to a aspx, php or jsp file. In this file you can access the database and enter all runtime data and the query-string data. Basically it is a kind of Iframe made with an image-tag.

<img src="myFile/Log.aspx" border="0" height="1" width="1" />


Im Log.aspx werden dann alle Daten in die Datenbank abgefüllt inkl. Datum, welches dort aktuell ist. Dieser Imagetag kann in jede gechachedte Seite eingefügt werden.

The Log.aspx then runs the database insert with current datetime included, which will be always the runtime one. This image-tag can be inserted to any cached page.

WICHTIG! Kein javascript Datum übergeben, denn dann bekommt man die Clientrechnerzeit, welche durch individuelle Einstellung und Zeitzone stark variiert.
IMPORTANT! Do not enter the javascript datetime, because then you get the client-time, that can differ because of individual settings and time-zones.

margin: 0pt auto; funktioniert nicht - does not work

Sie haben ein Problem, dass der CSS Befehl margin: 0pt auto; beim Internet Explorer nicht funktioniert? Egal wie man es anstellt, es will einfach den Layer nicht zentrieren. Das liegt an der Formatierung der kompletten HTML Seite. Hierzu bitte folgendes ändern. Standard <html> Tag ersetzen durch:
<?xml version="1.0" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">


You have a problem with the CSS coding margin: 0pt auto; in Internet Explorer? No matter what you do, it won't center your layer. The reason for this might be the format of the whole HTML template. Just replace the basic <html> tag with:
<?xml version="1.0" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">

Dienstag, 4. August 2009

Doppelter Content - Double content

Ein eigenartiger Fehler machte mir ein paar Stunden zu schaffen. Hierbei wurde bei einer Navigation ein Item doppelt angezeigt, ohne dass dieser im Quellcode ersichtlich war. Er wurde nur vom Internet Explorer verdoppelt und dann auch nur, wenn man aus dem ContentXXL ausgeloggt war. Grund hierfür ist die Standardeinstellung der HTML Definition in ContentXXL. Hierbei unter Portalsettings bei Angepasster Doctype diesen individuell einstellen mit <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. Danach funktionierte alles tadellos.

I had a strange error that I had to spent some time on. One item in my navigation got displayed twice without appearing in the source-code. It was just displayed when using Internet Explorer and when being logged off ContentXXL. Reason for this error is the standard definition of HTML in ContentXXL. To avoid this error, you need to set the Doctype in the portal-settings individually to <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. Then it works.

Montag, 27. Juli 2009

Real Ajax - richtiges Ajax

Wer im Visual Studio das UpdatePanel in Verbindung mit Ajax Requests verwendet, weiss oft nicht, dass der eigentliche Traffic, welcher durch Ajax vermindert werden soll, gar nicht im eigentlichen Umfang vermindert wird. Wie kommt das? Das UpdatePanel vom Visual Studio führt immer einen Request der ganzen Seite aus. Gut sichtbar mit dem Firebug vom FireFox. Hier kann man sehen, dass bei einem auslösen eines Request die gesamte Seite neu geladen wird. Nicht so wenn man einen Ajax Request mit einem Webservice kombiniert. Hierbei programmiert man ein JavaScript selbst, das wiederum eine Methode eines Webservice aufruft. Was man auf die Seite einbindet ist der .NET ScriptManager und man führt die selbstgeschriebenen JavaScript Funktionen auf. Wenn man dann die Seite verfolgt sieht man, dass nur ein Request auf die Methode ausgeführt wird.
Im Detail funktioniert das wie folgt:

People, that use the updatepanel for Ajax request in Visual Studio usually do not know, that the traffic, that is supposed to be reduced with Ajax, is not fully reduced. How does this happen? The updatepanel performs always a full page load of the current page using. You can trace this with the FireBug in FireFox. There you can see, that in triggering a request, the whole page is loaded. This is not the case, when you combine self written javascript with a webservice. In this case you develop a javascript on your own, that calls methods of a webservice. What you include in your aspx page is the .NET ScriptManager and you call the self written javascript functions. If you trace this request afterwards you see, that just the requested methods are loaded.
Here is some detailed information on that:

Füge den ScriptManager mit Verweis auf Javascript und Webservice hinzu
Add the ScriptManager with reference to the javascript and webservice
<asp:ScriptManager runat="server" ID="scriptManagerId">
<Scripts>
<asp:ScriptReference Path="MyJavascript.js" />
</Scripts>
<Services> <asp:ServiceReference Path="MyWebservice.asmx" />
</Services>
</asp:ScriptManager>

<asp:Literal ID="output" runat="server" /><br />
<asp:button ID="Button1" onclick="WriteHello()"><br />

Hier ein kurzes "Hello world!" Skript zur Anschauung. Bitte die Funktion im MyJavascript.js speichern
Here a short "hello world!" script to show how it works. Please save this function in the MyJavascript.js file.
function WriteHello()
{
Sample.MyService.WriteHello( SucceededCallback);
}

function SucceededCallback(WriteThis, eventArgs)
{
var OutputElement = document.getElementById("output");
OutputElement.innerHTML = WriteThis;
}

Danach geht es an den Webservice. Hier die Methode einfügen und als MyWebservice.asmx speichern.
Afterwards we create the webservice and enter the method and save it as MyWebservice.asmx.
namespace Sample {
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class MyService : System.Web.Services.WebService
{
[WebMethod]
public string WriteHello()
{
return "Hello World!";
}
}
}

Das wars eigentlich. Wenn man auf diese Art und Weise ohne UpdatePanel den Ajax Request startet, sieht man im FireBug, dass nur die Methode geladen wird.
This is basically it. If you now perform the Ajax request without the updatepanel, then you see in FireBug, that just the method is loaded.

Freitag, 10. Juli 2009

Content XXL Context.Items

Welche Werte kann man aus der Context.Items im ContentXXL auslesen? Hier eine Liste.
Which values can you get from the Context.Items in ContentXXL? Here is a list.

mailcontacttabid
user_contactid
enableeditmode
user_usersetting2
user_usersetting3
user_usersetting1
portaltitle
user_usersetting4
user_usersetting5
tellafriendbackurl
cuid
htmlversion
theme
useremail
subculture
applicationpath
relatedbaseobject
username
AspSessionIDManagerInitializeRequestCalled
loginalias
pagebaseurl
AspSession
charset
tellafriendpreview
portalid
defaultlanguage
currentDevice
baseurl
isNamedUrl
PortalSettings
culture
pathinfo
tellafriendtitle
isindetailview
lang
relatedbasetab
tabid
usertrackerdisabled
pagename

Dienstag, 30. Juni 2009

ContentXXL - Login module

Anbei der Code um ein Loginformular für das Anmeldemodul zu erstellen.
Below you will find the code to create a login-form for the login-module.


<SCRIPT language="vb" runat="server">
Sub Page_load()
'----------------------------------------------------------------------
' Javascript event-handler will be related to the input field
' to capture the return-key event.
'----------------------------------------------------------------------
username.Attributes.Add("onkeypress", "mykeyhandler('" & send.ClientID & "')")
password.Attributes.Add("onkeypress", "mykeyhandler('" & send.ClientID & "')")
if context.items("lang") <> 1 then
send.text = "Loggin"
else
send.text = "Anmelden"
end if
End Sub
</SCRIPT>

<SCRIPT language="JavaScript" type="text/javascript">
//----------------------------------------------------------------------
// Event handler who is waiting for return-keycode at the username
// and password field to call a postback for the login button
//----------------------------------------------------------------------
function mykeyhandler(sender) {
if (window.event.keyCode == 13) {
mysender = sender;
event.returnValue=false;
try {
document.getElementById(sender).click();
} catch(e) {}
}
}
if (document.captureEvents)
{
window.captureEvents(Event.KEYPRESS);
window.onkeypress = handlenetscape;
}
function getReturnValue(e)
{
if (!document.captureEvents)
return true;
else
{
if (e==13)
return false;
else
return true;
}
}
function handlenetscape(e)
{
if (e.which == 13){
__doPostBack('<%=send.UniqueID.replace(":","$") %>',''); } }
//----------------------------------------------------------------------
// Script which gives the focus to the username field when page is loaded,
// and if no username was entered in the username field, it will be
// prepared with the guest login.
//----------------------------------------------------------------------
function focusInput() { document.getElementById('<%=username.clientid %>').focus();
if(document.getElementById('<%=username.clientid %>').value.length < 1) {
if(<%=context.items("lang")%> == 1) {
document.getElementById('<%=username.clientid %>').value='';
document.getElementById('<%=password.clientid %>').value='';
}
else {
document.getElementById('<%=username.clientid %>').value='';
document.getElementById('<%=password.clientid %>').value='';
}
}}
</SCRIPT>

<DIV class="login_form">
<DIV class="center warning"><SPAN [mvif:haserror:neq:]>[pfl:1:Error in logging in][pfl:2:Login error]!</SPAN>[nbsp]</DIV>
<DIV class="login_label"><SPAN class="lauftext">[pfl:1:User][pfl:2:User]:</SPAN></DIV>
<DIV class="login_input">[tb:username:class="login_input"]</DIV>
<DIV class="login_label"><SPAN class="lauftext">[pfl:1:Password][pfl:2:Password]:</SPAN></DIV>
<DIV class="login_input">[tb:password:TextMode="password" class="login_input"]</DIV>
<DIV class="login_label">[nbsp]</DIV>
<DIV class="login_button">[lbn:send:commandName="Update" text="Login"]</DIV></DIV>
<SCRIPT language="Javascript">
document.body.onLoad=focusInput();
</SCRIPT>

ContentXXL Meine Erfahrung - ContentXXL my experience

ContentXXL ist ein Content Management System, welches einen Contentmanager voraussetzt, der auch HTML Kenntnisse besitzt. Im Grunde braucht man für ContentXXL keine tieferen
.NET Kentnisse um es aufzusetzen - so lang es in der Standardversion ohne benutzerdefinierte Einstellungen läuft. Wenn dann allerdings benutzerdefinierte Elemente eingebaut
werden sollen, wird es sehr ungemütlich. ContentXXL benutzt dann verschiedenste eigene Skriptsprachen für die Erstellung von Formularen beispielsweise. Auch andere Anpassungen
gestallten sich sehr schwierig, weil das System nicht OpenSource ist und vieles nicht besonders einsichtig. Es arbeitet mit einer Armee an SQL Prozeduren, was einzelne
Methodenaufrufe schwer nachvollziehbar macht.
ContentXXL kommt mit einem grossen Umfang an Basismodulen, welche zum Grossteil nicht gebraucht werden. Wie schon erwähnt, für den Contentmanager eine einfache Handhabung,
wenn er Module einrichten will, für den Entwickler von benutzerdefinierten Modulen eher ein heiles Durcheinander.
Sobald man das Prinzip verstanden hat, dass jede Seite aus Modulen, diese aus Objekten besteht, funktioniert das Arbeiten einigermassen, auch wenn das Prinzip für Entwickler
mit CMS Vergleichen, sehr umständlich und kompliziert wirkt. Man erwischt sich sehr oft bei der Frage: "Warum hat man das eigentlich so gelöst, was hat sich der ContentXXL
Entwickler dabei gedacht?".
In der Praxis ist die Anforderung bei grossen Firmen, dass man ein Content Management System in einer Serverfarm oder Loadbalanced betreibt. Da gibt es gravierende Mängel an
diesem System. Man findet sich irgendwann in einigen Workarounds wieder, wenn man das bewerkstelligen will. Da Content und System nicht richtig getrennt sind ist der Einsatz
auch im 3 Levelsystem (dev, stage, live) schwer umzusetzen.
Caching war ebenso ein kleines Problem. Es hat den Makel, dass bei nutzen aller Cachingmöglichkeiten (ContentXXL bietet einige), der Cache bei Contentbearbeitung nicht geleert
wird. Somit hat man die Möglichkeit Cachefeatures zu reduzieren, Contentmanagement irgendwie zu trennen, wobei wir da wieder bei Workarounds sind, die man vom CMS standardmässig
erwartet.

Gut an ContentXXL ist:
- Untere Bereichsführung im Sitemanager
- Support funktioniert gut
- Definieren von Benutzerrechten
- Cachingmöglichkeiten

Nicht gut an ContentXXL ist:
- Keine Informationen zu ContentXXL oder Fragen online in Suchmaschinen zu finden
- Quellcode nicht gut strukturiert
- Datenbank sehr undurchsichtig
- nicht geeignet für die einfache Installation in Multiserversystemen
- Wartung und Updates sind schwierig zu fahren
- Dev, Stage, Live kaum umsetzbar
- Kosten
- Sprachunterstützung - es sollten mehr Sprachen unterstützt werden
- Caching und Contentupdate

Mein Fazit ist. Für eine kleinere Webseite, wo die Rolle des Contentmanagers auch die des Webpublishers ist, sicher ein interessantes System, wenn man nur live arbeitet.
Jedoch für grosse Webseiten, mit mehreren Sprachvarianten, verschiedenen Produktionslevels, Multiserverumgebungen würde ich das CMS nicht empfehlen. Das einzig gute Feature
bei grösseren Webseiten wäre die Benutzerrechteverwaltung.
Wenn jemand ein CMS braucht, welches viel Onlinesupport bietet, einfache Struktur um viel benutzerdefiniert zu entwickeln, dann denke ich ist er bei ContentXXL absolut
falsch. Da würde ich Umbraco oder DotNetNuke empfehlen.

IE Emulatoren

Manchmal würde man gerne seine Webseite in einem älteren Internet Explorer testen. Jedoch ist es im Standardbetrieb nicht möglich den Internet Explorer in mehreren Versionen auf einem Rechner laufen zu lassen. Hierzu kann man Emulatoren des IE verwenden. Eine Webseite, welche verschiedene Emulatoren anbietet ist die folgende. Einfach herunterladen, entzippen und die .exe Datei starten und schon kann man jede Webseite besuchen.

Sometimes you might feel the need to test your website in older version of the Internet Explorer. Usually it is not possible to have several versions running on one PC. But you can do the work-around in using emulators. The following link has several IE version emulators. Just unzip and run the .exe and you can go to any website.

http://browsers.evolt.org/?ie/32bit/standalone

Mittwoch, 17. Juni 2009

Das richtige CMS - the cms that fits

Es gibt mittlerweile hunderte von Content Management Systemen. Jedoch, welches ist das Beste? Hierzu habe ich einmal zwei Kernthemen herausgefiltert. Soll es ein System sein, welches von einem erfahrenen Entwickler eingestellt und von einem kaum erfahrenen User verwaltet wird, oder der umgekehrte Fall, ein System, welches von einem nicht erfahrenen User eingestellt und verwaltet werden kann? Detailiertere Anforderungen wären. Soll es später in einem 1 Webserverbetrieb oder Serverfarm, Loadbalanced funktionieren? Alles zentrale Fragen, welche analysiert werden müssen.
Danach gibt es noch zwei Unterschiede. Geht man den weg Open-Source oder nicht? Open-Source bietet die Möglichkeit ein System den eigenen Anforderungen anzupassen. Jedoch sind manche Systeme schon bei ihrem Kauf angepasst. In meiner PHP und .NET Entwicklerzeit konnte ich ein wenig Erfharung sammeln und muss bisher sagen, dass das bestüberlegteste Konzept bisher das Open-Source CMS Umbraco mit sich bringt. Vorteil von open-source ist, dass sich viele Entwickler beteiligen. Sollte einer abspringen oder seine Tätigkeit beenden, läuft das Projekt selbständig weiter. Bei gekauften Lösungen muss man damit rechnen, dass bei Einstellung des Betriebs einer Firma, jeglicher Support mit eingestellt wird.
(siehe unten)

There are already hundreds of content management systems out there. But how do you get to know which one is the best? Therefore I grab two main topics. Is a system supposed to be integrated and improved by a experienced developer and maintained by a regular user or do you want a regular user to setup and maintian the system? Detailed specifications to a CMS would be: is it supposed to run in a single webserver environment or a server-farm, loadbalanced, etc.? Those are basic and centralized question that need to be analyzed.
Then there are two differences. Are you going the way to open-source or not? Open-source offers the possibility to customize to your needs. Most features are in-box with bought systems. During my development-experience with PHP and .NET, I must say, the best structured concept so far is the open-source CMS Umbraco. Basic advantage of open-source is, that multiple developers are involved. If one of the core-developers should leave the project, it will continue. If a bought solution company will terminate their business, then usually support gets terminated as well.

Nützliche Links zu Content Management Systemen:
Useful links to content management systems:

Open-source:
www.umbraco.org (.NET)
www.dotnetnuke.com (.NET)
www.typo3.org (PHP)
www.joomla.de (PHP)

Lizenzlösungen/licensed versions:
www.sitecore.net (.NET)
www.episerver.com (.NET)
www.contentxxl.de (.NET)

Dienstag, 16. Juni 2009

Separieren von web.config Daten

Es gibt manchmal Situationen in welchen man gerne Daten aus der web.config aus der Applikation bearbeiten würde. Jedoch sind durch ASP.NET .config Dateien aus der Applikation nicht zugänglich. Es gibt einen kleinen Workaround, der jedoch eine kleine Sicherheitslücke öffnet. Dessen sollte man sich bewusst sein. Man hat die Möglichkeit Daten aus der web.config auszulagern. Was man dann machen kann, ist die Daten in einem selbsternannten XML File zu speichern und auf dieses aus der Applikation zuzugreifen.
Man kann in der web.config die AppSettings oder ConnectionStrings per configSource auslagern. Man verwendet dann eine test.test Datei, Endung kann man selbst bestimen z.B. test.Firmenname und dort lagert man die Nodes aus. Man kann jetzt per XML zugreifen und Änderungen vornehmen. Vielleicht sollte man vorher noch die Rechte auf dieses File zur Sicherheit ändern.

There are sometimes situations, where you would like to change data in the web.config out of the application. ASP.NET usually blocks .config files to be changes out of the application. There is a little work-around to this situation. But be aware, that this reduces a little bit your application- security.
You can outsource the AppSettings or ConnectionString with configSource. Then you create a new test.test file (you can use any file-type also own one) and paste the nodes in there. You can now access this file with XML and make changes. Maybe you should set different permissions on this file to add some security.

web.config
<appSettings configSource ="test.test" />

test.test File
<appSettings>
<!-- your key/values -->
</appSettings>

Freitag, 12. Juni 2009

Maxlength in der Textbox

Eine Textbox, welche die Eigenschaft MaxLength auf einen bestimmten Wert gesetzt hat, kann dennoch aus dem Codebehind mit beliebig langen Strings befüllt werden. Eine Änderung zur Laufzeit wird nicht möglich, weil dann die Länge beschränkt ist.

A text-box with the property MaxLenght set to some length can be set with a value longer then the length from the code-bhind. Changes during runtime are not possible, because then the length limit will determine.

Donnerstag, 11. Juni 2009

if-else VS. XML

Ich denke jeder Entwickler hatte schon einmal die Situation, dass er verschiedene Abhängigkeiten abfangen musste. Dies ist mit if-else bzw. switch möglich, jedoch erfordert es bei jeder Änderung der Logik das Änderen des Quellcodes und dieser steht bei einer kompilierten Anwendung oft nicht zur Verfügung. Anbei ein Beispiel das ganze per XML zu lösen. Umgebung für dieses Beispiel ist Framework 3.5 mit Linq. Ich habe zur Ausgabe Dropdownlists verwendet.

I think every developer had already the situation, that he needed to display or catch certain dependencies. With if-else or switch you can do that, but in case of changes to the logic, you need to get into the source code and change that. Sometimes you don't have the source code or just a compiled version. You can handle this with XML. The environment of this example is framework 3.5 with Linq. I used for output dropdown-lists.

aspx - Seite

<form id="form1" runat="server">
<div>
<asp:DropDownList ID="Ebene1" AutoPostBack="true" OnSelectedIndexChanged="LoadSecondMenu" runat="server" /><br />
<asp:DropDownList ID="Ebene2" AutoPostBack="true" OnSelectedIndexChanged="LoadThirdMenu" runat="server" /><br />
<asp:DropDownList ID="Ebene3" AutoPostBack="true" OnSelectedIndexChanged="GetValue" runat="server" /><br />
<asp:Literal ID="MyLit" runat="server" /><br />
</div>
</form>

Codebehind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LoadFirstMenu();
}
}
protected void LoadFirstMenu()
{
Ebene1.Items.Add(new ListItem("Auswahl", "Auswahl"));
XDocument myDocument = XDocument.Load(MapPath("XMLTest.xml"));
var myQuery = from strResult in myDocument.Descendants("Logic").Descendants("Parent") select strResult.Attribute("ID").Value;
foreach (var Item in myQuery)
{
Ebene1.Items.Add(new ListItem(Item, Item));
}
Ebene2.Items.Clear();
Ebene3.Items.Clear();
}
protected void LoadSecondMenu(object sender, EventArgs e)
{
Ebene2.Items.Clear();
if (Ebene1.SelectedItem.Value != "Auswahl")
{
Ebene2.Items.Add(new ListItem("Auswahl", "Auswahl"));
XDocument myDocument = XDocument.Load(MapPath("XMLTest.xml"));
var myQuery = from strResult in myDocument.Descendants("Logic").Descendants("Parent").Descendants("Child") where strResult.Parent.Attribute("ID").Value == Ebene1.SelectedItem.Value select strResult.Attribute("ID").Value;
foreach (var Item in myQuery)
{
Ebene2.Items.Add(new ListItem(Item, Item));
}
}
Ebene3.Items.Clear();
}
protected void LoadThirdMenu(object sender, EventArgs e)
{
if (Ebene2.SelectedItem.Value != "Auswahl")
{
Ebene3.Items.Add(new ListItem("Auswahl", "Auswahl"));
XDocument myDocument = XDocument.Load(MapPath("XMLTest.xml"));
var myQuery = from strResult in myDocument.Descendants("Logic").Descendants("Parent").Descendants("Child").Descendants("Child") where strResult.Parent.Attribute("ID").Value == Ebene2.SelectedItem.Value select strResult.Attribute("ID").Value;
foreach (var Item in myQuery)
{
Ebene3.Items.Add(new ListItem(Item, Item));
}
}
}
protected void GetValue(object sender, EventArgs e)
{
if (Ebene3.SelectedItem.Value != "Auswahl")
{
XDocument myDocument = XDocument.Load(MapPath("XMLTest.xml"));
var myQuery = from strResult in myDocument.Descendants("Logic").Descendants("Parent").Descendants("Child").Descendants("Child") where strResult.Attribute("ID").Value == Ebene3.SelectedItem.Value select strResult.Value;
foreach (var Item in myQuery)
{
MyLit.Text = Item;
}
}
}

XML Datei

<?xml version="1.0" encoding="utf-8" ?>
<Logic>
<Parent ID="ParentItem">
<Child ID="Child1.1">
<Child ID="Child1.1.1">TextBlock 1.1.1</Child>
<Child ID="Child1.1.2">TextBlock 1.1.2</Child>
<Child ID="Child1.1.3">TextBlock 1.1.3</Child>
<Child ID="Child1.1.4">TextBlock 1.1.4</Child>
<Child ID="Child1.1.5">TextBlock 1.1.5</Child>
</Child>
<Child ID="Child1.2">
<Child ID="Child1.2.1">TextBlock 1.2.1</Child>
<Child ID="Child1.2.2">TextBlock 1.2.2</Child>
<Child ID="Child1.2.3">TextBlock 1.2.3</Child>
<Child ID="Child1.2.4">TextBlock 1.2.4</Child>
<Child ID="Child1.2.5">TextBlock 1.2.5</Child>
</Child>
<Child ID="Child1.3">
<Child ID="Child1.3.1">TextBlock 1.3.1</Child>
<Child ID="Child1.3.2">TextBlock 1.3.2</Child>
<Child ID="Child1.3.3">TextBlock 1.3.3</Child>
<Child ID="Child1.3.4">TextBlock 1.3.4</Child>
<Child ID="Child1.3.5">TextBlock 1.3.5</Child>
</Child>
</Parent>
<Parent ID="ParentItem2">
<Child ID="Child2.1">
<Child ID="Child2.1.1">TextBlock 2.1.1</Child>
<Child ID="Child2.1.2">TextBlock 2.1.2</Child>
<Child ID="Child2.1.3">TextBlock 2.1.3</Child>
<Child ID="Child2.1.4">TextBlock 2.1.4</Child>
<Child ID="Child2.1.5">TextBlock 2.1.5</Child>
</Child>
<Child ID="Child2.2">
<Child ID="Child2.2.1">TextBlock 2.2.1</Child>
<Child ID="Child2.2.2">TextBlock 2.2.2</Child>
<Child ID="Child2.2.3">TextBlock 2.2.3</Child>
<Child ID="Child2.2.4">TextBlock 2.2.4</Child>
<Child ID="Child2.2.5">TextBlock 2.2.5</Child>
</Child>
</Parent>
<Parent ID="ParentItem3">
<Child ID="Child3.1">
<Child ID="Child3.1.1">TextBlock 3.1.1</Child>
<Child ID="Child3.1.2">TextBlock 3.1.2</Child>
<Child ID="Child3.1.3">TextBlock 3.1.3</Child>
<Child ID="Child3.1.4">TextBlock 3.1.4</Child>
<Child ID="Child3.1.5">TextBlock 3.1.5</Child>
</Child>
<Child ID="Child3.2">
<Child ID="Child3.2.1">TextBlock 3.2.1</Child>
<Child ID="Child3.2.2">TextBlock 3.2.2</Child>
<Child ID="Child3.2.3">TextBlock 3.2.3</Child>
<Child ID="Child3.2.4">TextBlock 3.2.4</Child>
<Child ID="Child3.2.5">TextBlock 3.2.5</Child>
</Child>
<Child ID="Child3.3">
<Child ID="Child3.3.1">TextBlock 3.3.1</Child>
<Child ID="Child3.3.2">TextBlock 3.3.2</Child>
<Child ID="Child3.3.3">TextBlock 3.3.3</Child>
<Child ID="Child3.3.4">TextBlock 3.3.4</Child>
<Child ID="Child3.3.5">TextBlock 3.3.5</Child>
</Child>
<Child ID="Child3.4">
<Child ID="Child3.4.1">TextBlock 3.4.1</Child>
<Child ID="Child3.4.2">TextBlock 3.4.2</Child>
<Child ID="Child3.4.3">TextBlock 3.4.3</Child>
<Child ID="Child3.4.4">TextBlock 3.4.4</Child>
<Child ID="Child3.4.5">TextBlock 3.4.5</Child>
</Child>
</Parent>
<Parent ID="ParentItem4">
<Child ID="Child4.1">
<Child ID="Child4.1.1">TextBlock 4.1.1</Child>
<Child ID="Child4.1.2">TextBlock 4.1.2</Child>
<Child ID="Child4.1.3">TextBlock 4.1.3</Child>
<Child ID="Child4.1.4">TextBlock 4.1.4</Child>
<Child ID="Child4.1.5">TextBlock 4.1.5</Child>
</Child>
<Child ID="Child4.2">
<Child ID="Child4.2.1">TextBlock 4.2.1</Child>
<Child ID="Child4.2.2">TextBlock 4.2.2</Child>
<Child ID="Child4.2.3">TextBlock 4.2.3</Child>
<Child ID="Child4.2.4">TextBlock 4.2.4</Child>
<Child ID="Child4.2.5">TextBlock 4.2.5</Child>
</Child>
</Parent>
</Logic>

Willkommen

Willkommen in meinem Blog. Ich möchte hier regelmässig über .NET IT Themen berichten. Über Erfahrungen, Work-arounds, etc. aus dem Bereich Applikationsentwicklung im Microsoft .NET Umfeld. Ich arbeite mit folgenden Applikationen und Software. Entwickeln in Visual Studio, sowie Visual Studio Express, dazu MS SQL und MS SQL Express. Als Applikationen zur Weiterentwicklung und Einsatz verwende ich Umbraco und ContentXXL. Ich hoffe die Posts sind interessant und helfen bei der ein oder anderen Fehlermeldung oder verbessern Eure Applikation.

Welcome to my blog. I try to talk in regular periods about .NET topics. About experience, work-arounds, etc. in the .NET environment based on application development. I am working with the following software and applications. Developing in Visual Studio and Visual Studio Express based on MS SQL and MS SQL Express Edition. As applications I am using Umbraco and ContentXXL. I hope you enjoy my posts and that they might help you to solve an error or to improve your application.