ADO.NET: Feld ausschließen

Als ich den letzten Beitrag schrieb, viel mir ja ein, dass man nicht immer alle Spalten an das Modell übergeben möchte. Oder das es nur Readonly oder ähnliches ist.
Im Prinzip ist es auch einfach, wenn man weiß wie es geht. Der Designer in Visual Studio ist da meiner Meinung etwas umständlich in der Handhabung.
So möchte ich bei meinem letzten Modell die ID auf Readonly setzen, da dies in der Datenbank automatisch hochgezählt wird. Die ID daher manuell zu setzen würde keinen Sinn ergeben.
ADO.NET Modell

Dazu öffne ich das Modell im Visual Studio Designer und wähle oben die Tabelle aus. Unten wird mir nun das Fenster „Zuordnungsdetails“ angezeigt (alternativ über Ansicht » Weitere Fenster). Hier wähle ich die Spalte durch anklicken aus, die ich bearbeiten möchte. Wichtig ist jetzt dass ich hier nicht das vordere MSSQL-Feld sondern den hinteren Bereich, also den C# Typen auswähle (siehe Markierung).
ADO.NET Feld bearbeiten

Im Eigenschaftsfenster könnt ihr nun die entsprechenden Werte ändern. In dem Fall setzen wir den Setter auf Private.
Eigenschaften

Wenn wir nun versuchen eine Id zu setzen, hagelt es Fehlermeldungen:

TestTable test = new TestTable();
test.Id = 3;

Fehlermeldung lautet:

Die Eigenschaft oder der Indexer "MvcApplication1.Models.TestTable.Id" kann in diesem Kontext nicht verwendet werden, da der set-Accessor nicht verfügbar ist.

Auf diesen Weg können wir auch noch andere Sachen ändern, z.B. den Getter verändern oder den Namen des Attributs ändern.

Ach sollte man ein Feld gar nicht im Modell haben wollen, so wählt man bei den Zuordnungdetails einfach „Löschen“ aus.
ADO.NET Feld löschen

Auf den Weg könnt ihr das Feld später auch wieder ins Modell reinholen.

ASP.NET MVC: Seiten gehen nicht auf IIS5.1

Wir hatten folgendes Problem, wir entwickeln an einer ASP.NET Seite. Mit dem lokalen Entwicklungswebserver funktionierten die Seiten tadellos.
Als wir sie dann hochluden, gingen einige Seiten nicht und wir wussten nicht genau warum.

Nach einiger Sucherei konnten wir dies auf die <connectionStrings> in der web.config zurückführen.
Durch einen Kollegen stand dort folgende zwei Einträge drin:

    <add name="PersonalSettingsEntities" 
    connectionString="metadata=res://*/Models.Personal.csdl|res://*/Models.Personal.ssdl|res://*/Models.Personal.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=WXPAPP02\SQLEXPRESS;Initial Catalog=IntranetDB;User ID=sa;Password=sa;Pooling=False;MultipleActiveResultSets=True&quot;" 
    providerName="System.Data.EntityClient" />
    <add name="PersonalEntities" 
    connectionString="metadata=res://*/Models.Home.csdl|res://*/Models.Home.ssdl|res://*/Models.Home.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=WXPAPP02\SQLEXPRESS;Initial Catalog=IntranetDB;User ID=sa;Password=sa;Pooling=False;MultipleActiveResultSets=True&quot;" 
    providerName="System.Data.EntityClient" />

Der Unterschied zu den anderen Connectionstrings war, dass diese Einträge die Einträge „Pooling=False;“ enthält, und den Eintrag „Persist Security Info=True;“ war nicht enthalten.
Die Zeilen entsprechend abgeändert, schon ging es.
Werde nachher noch mal genaue Erklärung zu den beiden Parametern raussuchen.

ASP.NET MVC: nl2br() Ersatz für HtmlHelper

Da ich ja ursprünglich von PHP herkomme, habe ich natürlich eine schöne Funktion wie nl2br() vermisst.
Da ich nichts gescheites gefunden habe, habe ich natürlich die Funktionen von C#3.0 ausgenutzt und einfach die HtmlHelper Class erweitert.
Vielleicht kann es ja wer gebrauchen.

using System.Web.Mvc;

namespace MyProject.CustomExtensions
{
    public static class MyHtmlHelperExtensions
    {
        public static string Encode(this HtmlHelper html, string text, bool convertNewLine)
        {
            if (convertNewLine)
            {
                return html.Encode(text).Replace("\n", "<br />");
            }
            return html.Encode(text);
        }

        public static string Encode(this HtmlHelper html, object text, bool convertNewLine)
        {
            if (convertNewLine)
            {
                return html.Encode(text).Replace("\n", "<br />");
            }
            return html.Encode(text);
        }
    }

}

C# – Wissenwertes zu IEnumerable und wie man es richtig nutzt

Peter Bucher hat einen interessanten Artikel rund um IEnumerable und wie und wann man es richtig nutzt veröffentlicht.
Sollte man mal gelesen haben und natürlich auch anwenden. Ich werd es auf jeden Fall!

Wann IEnumerable nutzen, wann ICollection und wieso überhaupt IList?

Gibt in dem Blog übrigens noch andere lesenswerte Beiträge!

Html.Textbox und Ajax.BeginForm

So langsam sammel ich meine Erfahrung mit ASP.NET MVC, gute sowie schlechte.
Da kommen wir mal zu meinem heutigen Problem. Ich habe ein Formular, welches ich per Ajax an den Server senden möchte, dieser überprüft die Daten und gibt bei Bedarf ein Zusammenfassung der Fehler aus, wobei das Formular ausgefüllt bleibt.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyModel>" %>
<%= Html.ValidationSummary(); %>
<% using(Ajax.BeginForm("MyAction", new AjaxOptions { UpdateTargetId = "fromDiv" })) { %>
Benutzername: <%= Html.Textbox("username", Model.Username) %>
<input type="submit" value="Absenden" />
<% } %>

Hier mal als Beispiel. Das ganze wurde dann an den Server gesendet, validiert und bei Bedarf halt mit Fehlermeldung noch mal ausgegeben.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(string username) {
   if(this.UsernameExists(username)) {
      this.ModelState.AddModelError("errorUsername","Benutzername existiert schon!");
      MyModel user = new MyModel { Username = username + "1" };
      return PartialView("MyControl", user);
   }
   //...
}

So, angenommen wir geben nun einen Benutzername ein, welcher schon existiert. Dann sollte nun das Formular erscheinen, oben die ValidationSummery und als Benutzername vorgeblendet der von eben + 1. Möge man meinen, ist aber nicht so. Es erscheint zwar die ValidationSummary aber nicht die 1 hinter dem Namen.
Ich hab das gute Teil rauf und runter debugt, in div. Browsern, bei allen das selbe Ergebnis. Im Model steht der richtige Wert, er wird aber nicht angezeigt.
Eine Erklärung konnte ich nicht finden, aber eine Lösung.

Das Problem liegt an Html.Textbox(). Es scheint, als ob er das Objekt im Cache vorhält. Da werden ganz böse Erinnerungen an ViewState wach. Lösen konnte ich das Problem, in dem ich die Textbox manuell erstelle:

Benutzername: <input type="text" name="username" value="<%= Html.Encode(Model.Username) %/>" />

Aber auf so etwas muss man erstmal kommen. Löst ja eigentlich nicht das Problem sondern nur umgangen. Vielleicht find ich ja noch mal einen Beitrag dazu in der MSDN oder jemand hinterlässt mir einen schönen Link in den Kommentaren.