Biggle's Blog

Web- und Software Development

by Mario Binder

RenderUserControl und MVC2

Ich begebe mich gerade auf den Spuren von MVC/MVC2 und durchstöbere ein paar Tutorials über MVC und muss feststellen, dass das eine oder andere in MVC2 nicht bzw. anders umzusetzen ist. So auch, wenn man z.B. ein Template verwenden möchte. In einem HowTo wurde beschrieben, dass man ein Template wie folgt einbindet:

<% Html.RenderUserControl("~/Views/Home/TodoTemplate.ascx", item); %>

Nur leider gibt es kein RenderUserControl in MVC2. Nach etwas Recherche fand ich dann den Lösungsweg, wie man in MVC2 ein Template einbindet. Hier verwendet man RenderPartial anstelle RenderUserControl.

<% Html.RenderPartial("~/Views/Home/TodoTemplate.ascx", item); %>

Ein weiterer Punkt viel mir auf, das im Template der Typ zur Verfügung stehen muss um damit zu arbeiten. In MVC geht das, indem ich im SolutionNavigator mir alle Dateien anzeigen lasse und dort in der CodeDatei den Typen bekannt mache.

In MVC2 geht das (meiner Meinung nach) leider nicht. Auch hier fand ich die Lösung dazu. Ich typisiere das UserControl direkt in der ascx-Datei:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MVCDatabaseDatenAnzeigen.Models.Todo>" %>

Na mal schauen, was noch alles so kommt…

Viel Spaß beim entwickeln : )

by Mario Binder

Mehrere Controller in MVC2 verwenden

Um mehr Übersicht zu bekommen, macht es Sinn mehrere Controller in einem MVC 2 Projekt zu verwenden. Mit wenigen Schritten kann das wie folgt umgesetzt werden:

Zuerst legen wir unter Controllers ein neuen Controller an:

Und in der Global.asax wird der MapRoute eine neue Route hinzugefügt:

1
2
3
4
5
routes.MapRoute(
    "Customer", // Routenname
    "{controller}/{action}/{id}", // URL mit Parametern
    new { controller = "Customer", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
);

Im Menu (bei mir in Site.Master) wird der entsprechenden Link mit der Angabe des neuen Controllers gesetzt:

<%: Html.ActionLink("Blubber", "Blubb", "Customer")%>

Unter den Ordner Views erstellen wir einen neuen Ordner “Customer” und hier erstellen wir unsere entsprechende View.

Und schließlich im neuen Controller dann die ActionResult- und alle anderen Methoden implementieren

1
2
3
4
public ActionResult Blubb()
{
    return View();
}

Viel Spass beim entwickeln : )


by Mario Binder

Neuerungen in Visual Studio 2010

Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen.

Im folgenden Artikel möchte ich über einige Neuerungen in Visual Studio 2010 schreiben

Zu Beginn eine  Übersicht, welche Komponenten in welcher Version enthalten sein werden:


WPF basierter Editor

Der Editor in VisualStudio 2010 ist komplett in WPF umgesetzt.


MultiMonitor Unterstützung

Für alle Fenster wird der Multimonitorbetrieb unterstützt


Stufenloser Zoom

Mit STRG – Mausrad kann der Code vergrößert werden


Navigation

  • Quick Search
  • Highlight References


UML Designer (UltimateVersion)

  • Die Ultimate Edition von Visual Studio unterstützt die Modellierung mit UML (use-case-, class-, sequence-, activity- und componentdiagramme)
  • Beinhaltet eine Code-Generierung (T4-TextTemplate) für C# und Visual Basic
  • Beinhaltet eine Datenbank Script-Generierung

Quelle: http://www.olegsych.com/2010/01/uml-modeling-and-code-generation-in-visual-studio-2010/


Debugging

Mit den neuen Funktionen von VS2010 können Windows-, Web, .NETbasierende Anwendungen effizienter und komfortabel, sowohl in virtuellen als auch in echten 32- und 64Bit Umgebungen, getestet werden.


Pin to Source

Mit Pin2Source kann man aus dem KontextMenu heraus die entsprechende Variable oder Abschnitt im QuellText “anpinnen”:


Tracepoints, Breakpoints, Conditionals

TracePoints

Im KontextMenü des Editors findet man den Punkt “Insert Tracepoint”. TracePoints sind eine Erweiterung der Breakpoints und erlauben es, das Erreichen einer Ausführungszeile mit einer Aktion zu verknüpfen.

Tracepoints kann man beispielsweise zur Ausgabe von Variablenwerten im Ausgabefenster nutzen und so Konstrukte wie Console.WriteLine und die TraceKlasse ablösen – ohne einen Eingriff in den Quelltext!

Angenommen in folgender Schleife ist man an einen Increment interessiert und möchte laufend dessen Wert ausgeben:

1
2
3
for(var i = 0; i < 100; i++) {
  var x = i;
}

Man klickt hier mit der rechten Maustaste auf die zweite Zeile und wählt im Kontextmenü Breakpoint > Insert Tracepoint. Im folgenden Dialog kann man den Tracepoint konfigurieren und für diesen folgende Ausgabe definieren:

i ist {i}

Während der Debug-Sitzung wird im Ausgabefenster nun einhundert Mal der Wert von i gelistet.

Tracepoints können aber noch mehr.

  • Tracepoints können zusätzlich wie ein normaler Breakpoint verwendet werden, wenn die Option Continue execution deaktiviert wird.
  • Die Ausgabe kann mittels weiterer Platzhalter wie {$FUNC} um sinnvolle Informationen erweitert werden.
  • Beim Erreichen eines Tracepoints kann man ein VisualStudio Makro auslösen.


BreakPoints

  • Breakpoint labeln und Export aller Breakpoints
  • Breakpoints können per Drag & Drop heraus gezogen werden
  • Breakpoint-Pakete können verschickt werden
  • Breakpoints im Code definieren, nicht commiten : )
  • Breakpoint Gruppen
  • Tools/Options/Debugging/General Enable Just my Code ausstellen
  • CTRL – B setzt Breakpoint auf beliebige Funktion (use intellisense aus) werden im Tree angezeigt (Breakpoints)


Webcast:

  • Breakpoint exportieren [1]


Conditionals

  • Rechtsklick auf Breakpoint
  • (condition) In C# definieren
  • When hit: kann makro ausführen… oder nur print , Anwendung bleibt nicht stehen


IntelliTrace

Mit IntelliTrace reproduzierbare Fehler finden (Ultimate) IntelliTrace sammelt Informationen, die helfen die Fehlersuche und -diagnose zu vereinfachen und verbessert so die Produktivität beim Debugging. Aus der IntelliTrace Daten kann die Test-Session auf einem Entwickler-Rechner wiederhergestellt und die Fehler somit reproduziert werden.

  • Wie kann man Probleme debuggen, die nur beim Kunden auftreten
  • DumpDebugging
  • Prozesse save as dump
  • Kann sich selbst dumpen
  • File kann debugged werden
  • Alle Threads inkl aller Variablen sind dort enthalten
  • *.DMP in vs2010 öffnen zeigt Exceptions und den StackTrace
  • IntelliTrace hilft beim Debugging von nichtreproduzierbaren Fehlern beim Tester ohne VS
  • TraceDebuggerTools beinhaltet IntellTrace
  • collectionPlan.xml
  • Das entsprechende File kann dann mit IntelliTrace überprüft werden
  • Beinhaltet einen ASP.NET Client Proxy für IntelliTrace der Informationen über http-Aufrufe vom Client zum Webserver sammelt.

IntelliTrace muss in den Optionen > IntelliTrace aktiviert und konfiguriert werden

(IntelliTrace unter 64bit nicht möglich (auf x86 stellen))


Debugger Attributes

Im Namensraum System.Diagnostics gibt es eine Reihe von Attributen, die angewandt auf eigene Klassen das Verhalten des Debuggers beeinflussen können. Die Attribute werden für Klassen, Methoden oder Eigenschaften definiert.

Mit DebuggerBrowsableAttribute legt man fest, ob und wie eine Eigenschaft oder ein Feld in den verschiedenen Debugger- Fenstern (Locals, Autos, ..) angezeigt wird. Über die Enumeration DebuggerBrowsableState kann man einen der folgenden Werte wählen:

  • Never = keine Anzeige,
  • Collapsed = Anzeige,
  • RootHidden = Anzeige der Unterelemente, beispielsweise eines Arrays.


DebuggerDisplay

Wird auf Klassenebene deklariert und legt fest, welche Informationen aus der Klasse in den DebuggingFenstern angezeigt werden sollen.

[DebuggerDisplay("Kunde -  {FirstName}  {LastName}"]


DebuggerVisualizer

Wenn man noch mehr Möglichkeiten sucht, um einen Datentyp zu visualisieren, verwendet man das Attribute DebuggerVisualizer. Damit ist beispielsweise möglich, bei einem Datentyp Image sich dieses in Visual Studio anzeigen zu lassen.


Debuggingrechte in Visual Studio

Mit den Attributen DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode und DebuggerStepTrough lässt es sich festlegen, ob und wie VS das Debuggen einer Klasse oder einer Methode erlaubt.


Thread Debugging

  • Debugging von mehreren Threads (muss aktiviert werden)
  • Icon Diagramm rot grün + aktivieren
  • Rechtsklick flag, flagt den entsprechenden Thread
  • Freeze kann alle Threads anhalten, ein gezielter kann wieder aktiviert werden


Edit and continue

Hier handelt es sich um ein Feature, das es einem ermöglicht – wie schon lange in Visual Basic – im DebuggingModus Änderungen am Quelltext vorzunehmen und ohne Neuzukompilieren diese zu übernehmen.

Das Feature kann unter Optionen > Debugging > Edit and Continue aktiviert werden

(Edit & Continue funktioniert nicht, wenn IntelliTrace aktiviert ist)


Entity Framework 2

  • Model First Development (Generate DataBase from Model)
  • Create the database from code (no model needed)
  • Ermöglicht das Generieren der Datenbank aus dem Modell -und- auch aus dem Code heraus.


Automatic Pluralization

Bietet eine Pluralisierung an. EF würde in dem Fall an jeder Entität ein “s” anzuhängen. …


Foreign Keys in Models

Man kann Fremdschlüssel im Model verwenden, dazu beim Erstellen Include foreign key columns in the model aktivieren.

Lazy Loading

Der EF-Assistenten erzeugt enumerierbare Eigenschaften für jeden ForeignKey, den er auf einer Tabelle findet. Ein “Include” erzeugt innerhalb einer EF-Abfrage einen Join und bindet somit die Daten der verknüpften Tabelle mit ein. Diese Technik wird Eager Loading genannt und sorgt dafür das immer alle Daten im Join sind.

Das ist natürlich meist das Gegenteil, was man erreichen will, denn man möchte Daten erst dann von der Datenbank laden, wenn man sie auch benötigt.

Im Unterschied zur Nutzung von Include direkt auf der Entitäten-Menge Orders (ctx.Orders.Include(“Customers”)) kann das Load nun gezielt auf einzelne Order-Entitäten bei Bedarf erfolgen:

1
2
3
4
5
6
7
8
using (NorthwindEntities ctx = new NorthwindEntities())
{
    foreach (Orders orders in ctx.Orders)
    {
        orders.CustomersReference.Load();
        Console.WriteLine(orders.Customers.ContactName);
    }
}

Lazy Loading auf Feldebene

Fast noch wichtiger als das Lazy Loading auf Mengen-Ebene ist die Steuerung des Ladeverhaltens einer einzelnen Entität. Nehmen wir an, wir benötigen nur zwei Spalten aus der Customer Tabelle, um eine ComboBox mit den Spalten CustomerID und CompanyName zu binden. Im folgenden Code nutzen wir zunächst die scheinbar einfache Methode:

1
2
3
4
5
6
7
8
using (NorthwindEntities ctx = new NorthwindEntities())
{
    BindingSource bs = new BindingSource();
    bs.DataSource = ctx.Customers;
    cbCustomers.ValueMember = "CustomerID";
    cbCustomers.DisplayMember = "CompanyName";
    cbCustomers.DataSource = bs;
}

Also auf den ersten Blick scheint alles gut. Aber wie sieht es denn hinter den Kulissen aus, Das geschickte SQL-Kommando:

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
 [Extent1].[CustomerID] AS [CustomerID],
 [Extent1].[CompanyName] AS [CompanyName],
 [Extent1].[ContactName] AS [ContactName],
 [Extent1].[ContactTitle] AS [ContactTitle],
 [Extent1].[Address] AS [Address],
 [Extent1].[City] AS [City],
 [Extent1].[Region] AS [Region],
 [Extent1].[PostalCode] AS [PostalCode],
 [Extent1].[Country] AS [Country],
 [Extent1].[Phone] AS [Phone],
 [Extent1].[Fax] AS [Fax]
 FROM [dbo].[Customers] AS [Extent1]

Wir fragen also die komplette Tabelle Customers ab, nur um 2 Spalten anzuzeigen bzw. zu nutzen?! Das widerspricht also jeglicher Vernunft. In EF kann man dies durch die Rückgabe anonymer Typen über LINQ lösen:

1
2
3
4
5
6
using (NorthwindEntities ctx = new NorthwindEntities())
{
    var customers = from c in ctx.Customers
                  select new { c.CustomerID, c.CompanyName };
    cboCustomers.DataSource = customers;
}

Dieses SQL Kommando dagegen lässt sich dann schon sehen

1
2
3
4
5
SELECT
1 AS [C1],
[Extent1].[CustomerID] AS [CustomerID],
[Extent1].[CompanyName] AS [CompanyName]
FROM [dbo].[Customers] AS [Extent1]

More LINQ operator Support

.Single(), SingleOrDefault(); …


EF1 vs. EF 2

Neuer Designer

  • Unterstützung von POCO
  • Unterstützung von .tt Vorlagen
  • Unterstützung von Pluralisierung und Singularisierung
  • Fremdschlüssel
  • Model First Unterstützung
  • Lazy Loading Unterstützung
  • Missing LINQ Operators
  • Generated SQL unlesbar
  • N-Tier schwer
  • Bessere Unterstützung von Stored Procedures


Workflow Foundation 4.0


F#

Nach dem Start von J# nun ein erneuter Versuch unter den Namen F# eine Funktionale Sprache die sie nur auf das wesentliche für Mathematiker beschränken soll.


Add-Ons

Für das Installieren eines Addon ist nur noch das Kopieren notwendig (nicht mehr über die Registry).


Architektur Explorer

Ist ein integriertes Tool, das es ermöglicht die bestehende Architektur in einem Projekt oder einer binären Datei zu einen Modell zu erzeugen.


Tipps & Tricks in VS2010

  • Call Hierarchy CTRL + K, T
  • IntelliSense Suggestion Mode (vs. Completion Mode) CTRL + ALT + Space


Visual Studio 2010 Web Frameworks

  • ASP.NET WebForms 4
  • Neue Vorlagen mit Masterpages und Stylesheets
  • Neues Routingmodell
  • ASP.NET MVC 4
  • Komplett neue Herangehensweise an Webseiten
  • Neues Modell, parallel zum WebForms Modell
  • Schwerpunkt: Testbarkeit
  • ASP.NET Ajax 4
  • Windows Azure SDK & Tools
  • Dynamic Data
  • .NET RIA Services


Im nächsten Artikel schreibe ich über einige Neuerungen in WPF 4.0


by Mario Binder

Das MaxLength ASP.NET TextBox Problem

Die TextBox unter ASP.NET beachtet leider nicht die MaxLength wenn man ihr die MultiRow-Eigenschaft mitgibt. Folgender Snippet behebt das Problem:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#region HelperMethod MaxLength
/// <summary>
/// Eine TextBox welche die MultiRow Eigenschaft besitzt, ignoriert die MaxLength (bug)
/// Diese Methode (JavaScript) behebt das Problem.
/// Quelle: http://www.codegod.de/WebAppCodeGod/aspnet-textbox-maxlength-in-multiline-mode-AID297.aspx
/// </summary>
const int maxLengthTextBox = 1000;
protected void MaxLength()
{
    String
    lengthFunction = "function isMaxLength(txtBox){";
    lengthFunction += " if(txtBox) { ";
    lengthFunction += "   return (txtBox.value.length <" + maxLengthTextBox + ");";
    lengthFunction += " }";
    lengthFunction += "}";
 
    txtBox1.Attributes.Add("onkeypress", "return isMaxLength(this);");
    txtBox2.Attributes.Add("onkeypress", "return isMaxLength(this);");
    Page.ClientScript.RegisterClientScriptBlock(GetType(), "txtLength", lengthFunction, true);
}
#endregion


Quellenangabe: codegod

by Mario Binder

KeyDown in ASP .NET – CSharp

Ich hatte ja schon hier einmal beschrieben, wie man in C# via Entertaste  eine TextBox bestätigt und so den eingegebenen Wert weiterverarbeitet.
Ich wollte dies nun in ASP.NET nutzen, musste jedoch feststellen, das es dort kein Eventhandler für KeyDown gibt.

Nach einer Suche im Netz, bin ich dann auf folgende VB.NET Lösung gestossen*, welche ich in C# umgeschrieben habe.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#region EnterButton
void EnterButton(WebControl _textBox, Control _button)
{
    StringBuilder sb = new StringBuilder();
 
    sb.Append(("<SCRIPT language=\"javascript\">" + Environment.NewLine));
    sb.Append(("function fnTrapKD(btn){" + Environment.NewLine));
    sb.Append((" if (document.all){" + Environment.NewLine));
    sb.Append(("   if (event.keyCode == 13)" + Environment.NewLine));
    sb.Append(("   { " + Environment.NewLine));
    sb.Append(("     event.returnValue=false;" + Environment.NewLine));
    sb.Append(("     event.cancel = true;" + Environment.NewLine));
    sb.Append(("     btn.click();" + Environment.NewLine));
    sb.Append(("   } " + Environment.NewLine));
    sb.Append((" } " + Environment.NewLine));
    sb.Append(("}" + Environment.NewLine));
    sb.Append(("</SCRIPT>" + Environment.NewLine));
 
    _textBox.Attributes.Add("onkeydown", "fnTrapKD(document.all." + _button.ClientID + ")");
    Page.ClientScript.RegisterStartupScript(GetType(), "ForceDefaultToScript", sb.ToString());
}
#endregion


Aufgerufen wird dann das ganze im Load und zwar so:

1
EnterButton(txtBoxAddField, btnSave_Method);

Viel Spass damit ; )

* Um den Codeschnipsel in VB.NET beim Janus Kamp Hansen zu sehen, solltest du den IE benutzen und dann im Menu den Punkt Default Button in ASP.NET unter Usefull in ASP.NET wählen