Zur Zeit wird gefiltert nach: .net 4.0
Filter zurücksetzen

23.12.2010
10:58

Es ist doch nicht Ostern, wo hat sich die Basisklasse MembershipProvider versteckt?

Sitze gerade an einer Implementierung eines benutzerdefinierten MembershipProviders. Eigentlich nicht das erste Mal – Verweis auf System.Configuration und System.Web und es kann mit der Realisierung begonnen werden, aber in .NET 4.0 gibt es eine kleine Änderung. Die Basisklasse ist nicht mehr in der Assembly System.Web. Neu wird ein Verweis auf die Assembly System.Web.ApplicationServices benötigt, damit die abstrakte Basisklasse MembershipProvider verwendet werden kann.

Zurück

19.08.2010
22:41

.NET 4.0 Code Contracts – Must use the rewriter when using Contract.Requires<TException>

Für ein paar Beispiele möchte ich die Code Contracts intensiver nutzen, damit ich eine bessere Routine bekomme. Das erste Mal stand ich an, als ich Argumente einer Methode auf null prüfen wollte, um im positiven Fall eine entsprechende Exception zu erzeugen.

Bisher war mein Ansatz so:

C# (throw Exception) 
public virtual void Add (T entity)
{
    If (entity == null)
    {
        throw new ArgumentNullException("entity", "The parameter entity is null.") ;
    }
    …
}

Zukünftig soll es bei mir so aussehen:

 C# (Contract)
public virtual void Add (T entity)
{
    Contract.Requires<ArgumentNullException>(entity != null, "The parameter entity is null");
    …
}

Nach der Anpassung in die Contract-Syntax begrüsste mich jedoch folgende Meldung:

Abbildung 1
Abbildung 1 Fehlermeldung Must use the rewriter...

Ich fand schnell den Hinweis, dass bei den Projekteigenschaften unter Code Contracts die Einstellung "Perform Runtime Contract Checking" auf "FULL" gestellt werden muss, nur in meinen Projekteigenschaften konnte ich diesen Reiter nicht finden.

Abbildung 2
Abbildung 2 Projekteigenschaften mit fehlendem Reiter Code Contracts

Damit dieser Reiter mit aufgeführt wird, muss von den MS DevLabs mind. die Version 1.4.3 der Code Contracts heruntergeladen und installiert werden.

Nach erfolgreicher Installation muss dann nur noch die „Finish“-Schaltfläche geklickt werden.

Abbildung 3
Abbildung 3 Erfolgreiche Installation

Und endlich, der Reiter Code Contracts existiert in den Projekteigenschaften.

Abbildung 4
Abbildung 4 Projekteigenschaften mit Reiter "Code Contracts "

Damit diese Fehlermeldung nun nicht mehr erscheint, muss in der Projektmappe, welche die Contract-Definitionen enthält der Assembly Mode auf "Standard Contract Requries" und die Checkbox "Perform Runtime Contract Checking" auf "FULL" gesetzt werden. Mit dieser Anpassung ist der Fehler behoben.

Zurück

Eigener Request Validator in ASP.NET 4.0

Per Zufall bin ich auf eine neue Klasse in .NET 4.0 gestossen. Im März habe ich mir noch Gedanken gemacht, wie die Request Validation abgeschaltet werden kann – gut der Lösungsweg ist in der Fehlermeldung beschrieben – aber es gibt in .NET 4.0 eine neue Klasse mit dem Namen RequestValidator.

Das Problem mit der bisherigen Request Validation, es ist Best Practice diese zu deaktivieren. Unter anderem auch, weil diese bei Eingaben wie a <b bereits eine Ausnahme wirft und den Bearbeitungsprozess beendet. Zudem ist es gelegentlich eine ausdrückliche Anforderung, das einfache HTML-Elemente erfasst werden können.

Abbildung 1
Abbildung 1 Eine ungefährliche gefährliche Anfrage ;-)
Abbildung 2
Abbildung 2 Abbruch der Anwendung bei einfachen HTML

Ab ASP.NET 4.0 besteht nun die Möglichkeit, in diesen Validierungsprozess einzugreifen. Mithilfe der AntiXSS-Library kann so bspw. auf sicheres HTML geprüft werden, dieses zu erlauben und alles andere zu verwerfen und den Verarbeitungsprozess zu beenden. Der Vorteil, die Verarbeitung wird nur noch abgebrochen, wenn die Eingabe HTML enthält, das nicht durch die Prüfung der AntiXSS-Komponente kommt.

Dazu muss von der Klasse RequestValidator abgeleitet und die Methode IsValidRequestString überschreiben werden.

C#
namespace RequestValidation
{
  using System;
  using System.Web;
  using System.Web.Util;
  using Microsoft.Security.Application;

  public class SafeHtmlRequestValidator : RequestValidator
  {
    protected override bool IsValidRequestString(System.Web.HttpContext context, 
        string value, 
        RequestValidationSource requestValidationSource, 
        string collectionKey, 
        out int validationFailureIndex)
    {
      validationFailureIndex = 0;

      if (requestValidationSource == RequestValidationSource.Form)
      {
        if (IsSafeHtmlString(value))
        {
          return true;
        }
      }

      return base.IsValidRequestString(context, 
                 value, 
                 requestValidationSource, 
                 collectionKey, 
                 out validationFailureIndex);
    }

    private static bool IsSafeHtmlString(string value)
    {
      string value1 = HttpUtility.HtmlDecode(AntiXss.GetSafeHtmlFragment(value));
      return value1 == value;
    }
  }
}

Anschliessend wird dieser in der web.config mit Hilfe des httpRuntime-Elements registriert.

web.config
<system.web>
  <httpRuntime requestValidationType="RequestValidation.SafeHtmlRequestValidator"/>
---

Werden die oberen Eingaben wiederholt, so wird der Verarbeitungsprozess nicht mehr beendet. Lediglich wenn Code mit Scriptinhalten eingegeben wird, erzeugt der angepasste Validator einen Fehler und loggt diesen zusätzlich im Event-Log.

Abbildung 3
Abbildung 3 Eingabe a <b erzeugt keinen Abbruch mehr
Abbildung 4
Abbildung 4 Einfaches HTML wird akzeptiert
Abbildung 5
Abbildung 5 HTML mit Script <img src="" onerror="alert('Test')" /> wird abgebrochen

Zurück

Entity Framework 4 - SQL-Verbesserungen

Die generierten SQL-Statements in EF1 sind häufig ein Reizthema. Das Problem mit dem IN-Statement habe ich bereits erwähnt, aber das allein ist nicht das Problem. Ein häufiges Beispiel für Optimierungen sind die kompilierten Abfragen, die aber auf das generierte SQL keinen Einfluss haben. Was zum Teil für unterhaltsame Abfragen im EF1 generiert werden, ist in diesem Blogbeitrag ersichtlich.

Zurück

Entity Framework 4 – ADO.NET Entity Data Model Designer Extension Starter Kit

Für das Entity Framework 4 gibt es neu den T4 – Template Support. Damit besteht die Möglichkeit den generierten Code zu erweitern bzw. anzupassen. Was mit den T4 Vorlagen nicht funktioniert ist das Anpassen der Edmx-Datei, wenn das Modell von der Datenbank erstellt wird. Gerade wenn Datenbank-Richtlinien nicht mit dem des .NET Framework vereinbar sind ist es sinnvoll, wenn diese Richtlinien beim Anlegen des Modells transformiert bzw. eliminiert werden können.

Das Entity Developer Studio von DevArt bietet unter anderem die Möglichkeit Präfixe zu entfernen. Hierfür steht eine separate Maske zur Verfügung.

Abbildung 1
Abbildung 1 Entity Developer Studio Maske für Namensregeln

Wenn die Namensregeln definiert sind, werden die neuen Entities angepasst, die bestehenden bleiben mit den bisherigen Namensregeln erhalten.

Abbildung 2
Abbildung 2 Tabelle tabFunction auf Basis der definierten Namensregeln

Eine neue Variante ist das ADO.NET Entity Data Model Designer Extension Starter Kit (EDMDESK). Diese Visual Studio – Erweiterung kann hier heruntergeladen werden. Nach der Installation steht eine neue Vorlage in Visual Studio zur Verfügung.

Abbildung 3
Abbildung 3 Auswahl der Vorlage ADO.NET Entity Designer Extension Starter Kit

Nach der Auswahl wird eine Solution mit Beispielklassen erstellt, welche in den jeweiligen Prozessen der Generierung der Edmx-Datei eingreifen kann.

Abbildung 4
Abbildung 4 Beispielanwendung

In meinen Beispiel ist die Klasse ModelGenerationExtension von Bedeutung. Die anderen Beispielklassen entferne ich aus dem Projekt. Damit diese auch fehlerfrei kompiliert, muss der Inhalt aus der Beispielmethode AddProperty entfernt werden. Der Einstieg erfolgt über die Ereignismethoden OnAfterModelGenerated und OnAfterModelUpdated. Ich habe es noch nicht mit FxCop getestet, aber der Namensbestandteil After ist gemäss den .NET Framework Richtlinien nicht gerne gesehen ;-)

C# Ereignismethode
        public void OnAfterModelUpdated(UpdateModelExtensionContext context)
        {
            //
            // context.OriginalDocument = The original XDocument before the Update Model Wizard started.
            //                            An extension cannot modify this document.
            //
            // context.GeneratedDocument = The temporary XDocument that was generated by the Update Model wizard from the database.
            //                             An extension cannot modify this document.
            //
            // context.UpdateModelDocument = The contents of context.OriginalDocument merged with the contents of context.GeneratedDocument.
            //                               An extension cannot modify this document.
            //
            // context.CurrentDocument = The XDocument that will be saved.
            //                           An extension can modify this document. Note that the document may have been modified by another extension's implementation of OnAfterModelUpdated().
            //
            //
            // context.ProjectItem = The EnvDTE.ProjectItem of current .edmx file.
            //
            // context.Project = The EnvDTE.Project that contains the .edmx file.
            //
            // context.WizardKind = The wizard that initiated the .edmx file generation or update process (WizardKind.UpdateModel).
            //

            bool efV2Model = IsEntityFrameworkV2Model(context.Project);
            String caption = "OnAfterModelGenerated called";
            String message = String.Format("An EF v{0} model was updated from the database by the 'Update Model From Database' wizard.\n\n", efV2Model ? 2 : 1);

            if (efV2Model)
            {
                // Call helper method to add a new property to the generated EF v2 model.
                AddPropertyToModel(context.CurrentDocument);

                message += "Added a new property to EntityTypes in the updated model.";
            }

            MessageBox.Show(message, caption);
        }

Die Möglichkeiten sind sehr schön in den Methoden dokumentiert, sodass eigentlich gleich programmiert werden kann. Die Edmx-Datei wird als XDocument übergeben. Damit besteht die Möglichkeit, das Modell mit Hilfe von Linq to XML abzufragen.

Szenario

Eine der häufig anzutreffenden Richtlinien auf Datenbankebene ist der Einsatz von Präfixen auf Tabellen-, Sicht- und Spaltennamen. Auf dieser Ebene gibt es wiederum mehrere Varianten. Eine Variante, die sich wunderbar mit diesem Extension Kit eliminieren lässt, ist die ungarische Notationsform. Bei dieser Notation werden die Datentypen als Präfix der Spalte vorangestellt. Im Klassendesign (siehe Abbildung 2) ist so eine Notationsform in meinen Augen nicht zu gebrauchen und das manuelle Anpassen des Modells ist zeitaufwendig und nicht erstrebenswert.

Für diesen Zweck habe ich bereits Klassen erstellt, auf die ich nicht näher eingehe. Die Aufgabe dieser Klassen sind das Abfragen und Bearbeiten des Dokuments. In der Klasse ModelGenerationExtension füge ich dafür eine neue Methode ein, die später von den Ereignismethoden aufgerufen wird.

 C# (Aufruf Methode)
private void ConvertNameAttributes(XDocument model)
{
  var converter = new EfNameConverter();
  converter.PrefixPropertyDescriptions = "lng;str;dbl;dtm";
  converter.PrefixEntityDescriptions = "tab;vw;";
  converter.ReplaceContentList.Add(new Tuple("bit", "Is"));
  converter.ReplaceContentList.Add(new Tuple("AutoID", "Id"));
  converter.ConvertEdmxDocument(model);
}

In dieser Methode wird eine Instanz einer benutzerdefinierten Klasse erzeugt und die Präfixe der Tabellen, Sichten und Spaltennamen definiert. Sonderfälle können mit der ReplaceContentList behandelt werden. So ist es beispielsweise möglich, dass der Präfix bit für bool durch ein „Is“ ersetzt werden kann, damit bitActive in IsActive umgewandelt wird. Auch Namensbestandteile wie AutoID können so in besser klingende Namen umgewandelt werden.

Der Aufruf erfolgt in den Ereignismethoden wie folgt:

C# Aufruf für Ereignismethoden
this.ConvertNameAttributes(context.CurrentDocument);

Hier wird vom Kontext das aktuelle Dokument übergeben, da dies von der Erweiterung bearbeitet werden kann. Nach der Kompilierung des Projekts wird im Ausgabeordner eine *.vsix – Datei erstellt. Hierbei handelt es um eine Visual Studio Erweiterung. Beim Ausführen erscheint folgende Maske:

Abbildung 5
Abbildung 5 EDM Installer
Abbildung 6
Abbildung 6 Visual Studio Erweiterung nach erfolgreicher Installation

Wenn Visual Studio geöffnet ist, muss es geschlossen und neu gestartet werden. Nach dieser Aktion wird unter dem Menüpunkt Extras/Erweiterungs-Manager die Erweiterung angezeigt.

Abbildung 7
Abbildung 7 Erweiterungs-Manager

Wenn die Erweiterung aktiv ist, werden bei allen Entity Modellen anhand der definierten Regeln die Namen umbenannt.

Dazu werden im Assistent die Tabellen ausgewählt.

Abbildung 8
Abbildung 8 Auswahl der Entitäten

Diese Entitäten haben den Präfix „tab“. Wenn die Visual Studio Erweiterung richtig funktioniert, gibt es 2 Klassen mit den Namen Function und Staff. Nach dem drücken der Schaltfläche „Fertig stellen“ erscheint eine Information, die auf den Vorgang der Erweiterung hinweist.

Abbildung 9
Abbildung 9 Nachricht der Visual Studio Erweiterung

Die generierte Datei hat nun 2 Entitäten und die Richtlinien der Datenbanknamen wurden für das Modell eliminiert.

Abbildung 10
Abbildung 10 Erstellte Entitäten mit der Visual Studio Erweiterung

Wenn ich das Entity Developer Studio mit dem ADO.NET Entity Data Model Extension Starter Kit vergleiche, ist es in dieser Situation mächtiger, weil es mir viel mehr Möglichkeiten eröffnet.

In Projekten bei denen die Richtlinien der Datenbank im Bereich der Namen mit denen der .NET Framework Richtlinien sehr stark in Konflikt stehen, ist diese Erweiterungsmöglichkeit eine optimale Lösung um das Problem elegant zu beheben.

Zurück

Translate this page

Kategorien

  • [-].NET Development (207)
  • [-]Datenbank (24)
  • HTML (1)
  • Konfiguration (12)
  • Mind Map (9)
  • Off-topic (9)
  • Open Source (3)
  • Qualität (6)
  • Sharepoint (2)
  • Sicherheit (2)

Archiv

Social Bookmarking

Bookmark bei: Mr. Wong Bookmark bei: Webnews Bookmark bei: Icio Bookmark bei: Oneview Bookmark bei: Linkarena Bookmark bei: Favoriten Bookmark bei: Seekxl Bookmark bei: Favit Bookmark bei: Social Bookmarking Tool Bookmark bei: Power Oldie Bookmark bei: Bookmarks.cc Bookmark bei: Newskick Bookmark bei: Newsider Bookmark bei: Linksilo Bookmark bei: Readster Bookmark bei: Folkd Bookmark bei: Yigg Bookmark bei: Digg Bookmark bei: Del.icio.us Bookmark bei: Reddit Bookmark bei: Simpy Bookmark bei: StumbleUpon Bookmark bei: Slashdot Bookmark bei: Netscape Bookmark bei: Furl Bookmark bei: Yahoo Bookmark bei: Spurl Bookmark bei: Google Bookmark bei: Blinklist Bookmark bei: Blogmarks Bookmark bei: Diigo Bookmark bei: Technorati Bookmark bei: Newsvine Bookmark bei: Blinkbits Bookmark bei: Ma.Gnolia Bookmark bei: Smarking Bookmark bei: Netvouz Information