Posted by AlexanderZeitler on 11/27/2003 8:49 AM | Comments (0)

Gestern tauchte in der ASP.NET-Mailingliste die Frage auf, wie man am geschicktesten und möglichst resourcenschonend auf die Application-Settings der web.config zugreifen könnte.

Normalerweise geschieht der Zugriff etwa in dieser Form:

web.config (Auszug):
<?xml version="1.0" encoding="utf-8" ?>
<
configuration
>
<appSettings
>
    <add key="ConnectionString"

         value="PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source="mydb.mdb"
/>
    <add key="SmtpServer"
 
         
value="127.0.0.1" />
</appSettings>

mypage.aspx.cs:
SqlConnection cn = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);


Dies ist allerdings weder gut lesbar, noch sind die Application-Settings damit typsicher. Ferner schleichen sich leicht Tippfehler in den Bezeichnungen ein, welche mit der Anzahl der Settings steigen.

Markus Renschler kam dabei auf einen ebenso einfachen wie genialen Ansatz, wie man alle drei genannten Nachteile abschaffen kann. Kurzerhand bauten wir uns in der Liste einen AppSettings-Wrapper. Dieser wandelt die gespeicherten Application-Settings in typfeste, nur lesbare Variablen um und cached diese, falls nötig - ein weiterer Vorteil des Wrappers. Aufgrund der sich daraus ergebenden Objektorientierung der Settings, stehen diese nun auch über die Intellisense von VS.NET zur Verfügung - Tippfehler und das Vergessen der Bezeichnung der Settings sind ausgeschlossen.

Der Wrapper sieht nun wie folgt aus:

using

System;
using
System.Configuration;
using System.Web;


namespace DotNetGerman.WrapperSample
{
   internal class Configuration
   {
      /// <summary>
     
///
Liefert den in der web.config gespeicherten
      ///
Connectionstring zurück.
      ///
</summary>
      
public static
string ConnectionString
      {
        
get
           
{
               return LoadConfigValue("ConnectionString");
           
}
      }


      /// <summary>
     
/// Liefert den angefordeten Keyvalue aus der
      ///
web.config zurück und cached diesen, falls
     
///
noch nicht gecached.
     
///
</summary>
     
/// <param name="nameInWebConfig">
Der angefordete Keyname
     
/// in der web.config
</param>
     
/// <returns>Der Keyvalue aus der web.config.
</returns>
     
private static
string LoadConfigValue(string
nameInWebConfig)

      {
         string nameInApplication = "Config" + nameInWebConfig;
         HttpApplicationState app = HttpContext.Current.Application;
        
if( app[nameInApplication] == null
)
         {
             app[nameInApplication] =
                 ConfigurationSettings.AppSettings[nameInWebConfig];
         }

         return
            
app[nameInApplication].ToString();
      }
   }
}

Der Aufruf erfolgt folgendermaßen:

mypage.aspx.cs (Auszug):
SqlConnection cn = new SqlConnection(Configuration.ConnectionString);

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: FAQ.NET, VisualStudio.NET Posted by AlexanderZeitler on 11/26/2003 7:41 PM | Comments (0)

Häufig macht es, der Übersicht wegen, Sinn, Parameter von WebControls mit Tabulatoren eingerückt untereinander zu schreiben, was z.B. so aussehen könnte:

<asp:DataGrid   ID="myDataGrid"
                Runat="Server"
                AutoGenerateColumns="False"
                AllowPaging="True"
                Width="100%">
                              

Allerdings ist VisualStudio.NET per default der Auffassung, dass man solche Auflistungen nicht benötigt. Ergo ändert es spätestens beim Speichern der .aspx-, .ascx oder sonstigen HTML/XML-basierten Dateien die Parameterauflistung wieder wie folgt:

<asp:DataGrid ID="myDataGrid" Runat="Server" AutoGenerateColumns="False" AllowPaging="True" Width="100%">

Doch VisualStudio ist nur auf den ersten Blick so stur. Der zweite Blick führt uns direkt in die Optionen (Menü Extra - Optionen):



Dort sind die beiden rot markierten Optionen zu deaktivieren - ab sofort sind wir Herr im Hause, sprich VS.NET ändert die Formatierung des HTML/XML-basierten QuellCodes nicht mehr eigenmächtig.

Ein Dank für die Lösung dieser häufig gestellten Frage gebührt Joachim van de Bruck, der in den Mailinglisten von www.glengamoi.com sein "Unwesen" treibt.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: Allgemein Posted by AlexanderZeitler on 11/26/2003 8:40 AM | Comments (0)

DotNetGerman.com ist um einen Blogger reicher: Daniel Fisher beschert der .NET-Community immer wieder interessante Beiträge in seinem Blog unter http://www.dotnetgerman.com/blogs/lennybacon.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: Patterns/Practices, Allgemein, FAQ.NET Posted by AlexanderZeitler on 11/26/2003 8:30 AM | Comments (0)

Auf der Suche nach Design Patterns bin ich auf folgende, sehr gelungene, Seite gestoßen:

http://www.dofactory.com/Patterns/Patterns.aspx

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: ASP.NET, Controls.NET, FAQ.NET Posted by AlexanderZeitler on 11/25/2003 12:02 PM | Comments (0)

Ein kürzlich behandeltes Problem in der ASP.NET-Mailingliste war die Übergabe von Parametern an ein UserControl in der LoadControl-Anweisung. Eine mögliche Lösung werde ich heute vorstellen.

Platziert man das LoadControl im Page_Load der .aspx-Seite und benötigt das mittels LoadControl zu ladende UserControl zur korrekten Funktion Parameter, so braucht man eine Möglichkeit, diese Parameter an das UserControl zu übergeben, bevor das UserControl ausgeführt wird.

Eine mögliche Lösung besteht darin, dem UserControl eine Bind()-Methode zu spendieren, welche den Aufruf der Funktionalität des UserControls aus dem Page_Load() des UserControls zieht.

Befindet sich der Aufruf der Funktionalität des UserControls hingegen im Page_Load(), so wird die Seite, auf der das UserControl dynamisch geladen wird, bis Page_Load() ausgeführt, danach startet der LifeCycle des User Controls und wird ebenfalls bis Page_Load() (des UserControls) ausgeführt, d.h. man hat keine Möglichkeit mehr, die Parameter zu übergeben.

Die Lösung sieht also wie folgt aus:

myControl.ascx.cs:

public class MyUserControl : System.Web.UI.UserControl
{
    protected
System.Web.UI.WebControls.Label LBLFirstName;
    protected
System.Web.UI.WebControls.Label LBLLastName;
    private string _firstName = "";
    private string _lastName = "";

    private void Page_Load(object
sender, System.EventArgs e)
   
{
        if
(IsPostBack)
        
{
        
}
   
}

    public void Bind()
    {
        LBLFirstName.Text = this.FirstName;
        LBLLastName.Text  = this.LastName;
    }

    public
string FirstName
    {
        get
            {
                return _firstName;
            }
        set
            {
                _firstName = value;
            }
    }

    public
string LastName
    {
        get
            {
                return _lastName;
            }
        set
            {
                _lastName = value;
            }
    }
}


myPage.aspx.cs:

public class myPage : System.Web.UI.Page
{
    private void Page_Load(object sender, System.EventArgs e)
   
{
        if
(!IsPostBack)
        
{
            MyUserControl uc = (MyUserControl)Page.LoadControl("myControl.ascx");
            uc.FirstName = "Alexander";
            uc.LastName = "Zeitler";
            uc.Bind();
            Page.Controls.Add(uc);
        
}
   
}
}

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: Allgemein Posted by AlexanderZeitler on 11/24/2003 1:16 PM | Comments (0)

Andreas Roth hat in seinem Blog einen Bericht über das .NET Klassentreffen am 22.11.2003 bereitgestellt.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: FAQ.NET Posted by AlexanderZeitler on 11/20/2003 10:47 AM | Comments (0)

Das DataGrid ist ein nettes Control, wenn es um die Darstellung von Daten in tabellarischer Form geht.
Allerdings ist es unschön, wenn keine Datensätze vorhanden sind, und nur die Headerzeile angezeigt wird.

Besser wäre ein Hinweis in der Art "Es liegen keine Daten vor.".

Doch wie lässt sich das realisieren?
Möglichkeiten gibt es viele, einige werde ich hier vorstellen:

1. Prüfung bereits in der Datenquelle:

Angenommen, wir verwenden zum Lesen der Daten einen SqlDataReader, könnte eine Prüfung wie folgt aussehen:

public void ReadMyData(string myConnString) 
{
    // Erzeugen des SQL-Strings und ausführen der Abfrage
    string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders";
    SqlConnection myConnection = new SqlConnection(myConnString);
    SqlCommand myCommand = new SqlCommand(mySelectQuery,myConnection);
    myConnection.Open();
    SqlDataReader myReader;
    myReader = myCommand.ExecuteReader();
    // Prüfen, ob Daten vorhanden sind
   if(myReader.HasRows)
    {
        // Daten an DataSet / DataGrid übergeben
    }
    else
    {
         Page.Response.Write("Es liegen keine Daten vor");
    }

    // SqlDataReader schließen
    myReader.Close();
    // Verbindung zur Datenbank schließen
    myConnection.Close();
}

 

2. Prüfung im DataSet:

Eine weitere Möglichkeit ist, das DataSet, das als Datenquelle verwendet wird, auf Daten zu überprüfen:

public void DisplayMyGrid(string myConnString, DataSet myDataSet) 
{
    // Prüfen, ob Daten vorhanden sind
    if(myDataSet.Tables(0).Rows.Count>0)
    {
        // ja, dann Daten ausgeben
        DataGrid myDataGrid = new DataGrid();
        myDataGrid.DataSource = myDataSet;
        myDataGrid.DataBind();
    }
    else
    {
        // nein, dann Fehlermeldung ausgeben
        Page.Response.Write("Es liegen keine Daten vor.");
    }
}

 

3. Prüfung im DataGrid selbst

Letztlich besteht auch noch die Möglichkeit, die Prüfung im DataGrid selbst vorzunehmen.
Hierzu muß man die Anzahl der Items im DataGrid mittels DataGrid.Items.Count auslesen.
Hierbei sind allerdings die Unwägbarkeiten im Verhalten des DataGrids mit (in)aktivem Header / Footer / Pager zu berücksichtigen, wie ich sie in meinem Artikel Das ASP.NET DataGrid selbst erweitern unter "Objekt-Orientierung" beschrieben habe.
Aufgrund der Fehlerträchtigkeit dieses Ansatzes möchte ich auf nähere Erläuterungen verzichten.
Die beiden ersten vorgestellten Ansätze funktionieren mit kleinen Anpassungen mit praktisch jeder Datenquelle und vor allen Dingen zuverlässig. Weshalb also unnötig Probleme provozieren?



 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: FAQ.NET Posted by AlexanderZeitler on 11/18/2003 8:53 PM | Comments (0)

Heute gibt es seit langem mal wieder einen Eintrag der Marke "Fragen aus der ASP.NET-Mailingliste":

Versucht man Request.UrlReferrer.AbsolutePath auf Null zu prüfen, erhält man - wenn kein Referer existiert - eine System.NullReferenceException.

Gerade diese Exception will man aber doch mit der einer Prüfung wie
if(Request.UrlReferrer.AbsolutePath==null)
abfangen.

Was tun? Die Lösung ist relativ simple. Existiert kein Referer, ist bereits Request.UrlReferer Null, somit existiert auch die Eigenschaft .AbsolutePath nicht und ein Zugriff löst die genannte Exception aus.

Die Prüfung muß also wie folgt aussehen:

if(Request.UrlReferrer==null)
{
   Response.Write("kein Referer vorhanden!");
}
else
{
   Response.Write(Request.UrlReferrer.AbsolutePath);
}

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: Allgemein Posted by AlexanderZeitler on 11/18/2003 12:16 PM | Comments (0)

Microsoft will die XML-basierten Dateiformate der Office 2003 Applikationen offenlegen.

Die XML-Schemata (inkl. Dokumentation) können ab 5. Dezember über MSDN kostenlos lizenziert werden.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories: Allgemein Posted by AlexanderZeitler on 11/18/2003 10:33 AM | Comments (0)

Ich habe mich nun endlich an das Eingemachte von dasBlog getraut und ein wenig mit dem Design experimentiert.
Hoffe, es gefällt ;-)

Wie bei solchen Dingen üblich: Kritik, Bug-Reports aber auch Lob sind willkommen.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5