2016-03-21 6 views
0

Ich habe eine Datenbank mit Ordnern, in denen ich den gesamten Pfad zu einem Ordner als folder_name speichern, also etw. wie: //MainFolder/subFolder/folderName. In meiner Anwendung habe ich ein Modell namens Folder, die die Ordner von db darstellt.Zugriff [NotMapped] -Eigenschaft mit einem benutzerdefinierten Getter/Setter

Modell:

public class Folder 
{ 
    [Key] 
    public string folder_name { get; set; } 
    [NotMapped] 
    public string folder_name_short 
    { 
     get 
     { 
      string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); //System.NullReferenceException here 
      return shortname; 
     } 
     set 
     { 
      string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); 
      this.folder_name = folder_name.Replace(shortname, value); 
     } 
    } 
} 

folder_name_short wird nicht abgebildet, da sie nur ein Teil aus dem ganzen Weg ist, so will ich nicht zweimal speichern. Beispiel möchte ich meine:

Console.WriteLine(folder_name)   output://MainFolder/subFolder/folderName 
Console.WriteLine(folder_name_short) output:/folderName 

Meiner Ansicht der Benutzer den Ordner umbenennen. So würde Ich mag die alten folder_name_short auf den neuen ersetzen und speichern Sie den neuen String in folder_name

Ausblick:

. 
. 
using (Html.BeginForm("Rename", "Folders", FormMethod.Post)) 
{ 
    @Html.EditorFor(model => model.folder_name_short) 
    <input type="submit" value="rename folder" id="submit" class="btn btn-default" /> 
} 
. 
. 

Problem: Die Inputtextbox macht und zeigt den aktuellen Wert des folder_name_short drin. Wenn ich es ändere und auf den Submit-Button klicke, erhalte ich eine System.NullReferenceException im Model (wie im Quelltext markiert, bitte nach rechts scrollen). Ich verstehe nicht, was falsch ist und welche Änderungen nötig sind.

Edit:

wenn die Setter-Kommentar gesetzt wird, verschwinden die Ausnahme. Vielleicht verursacht der Setter den Fehler?

Lösung:

Verwendung der Standard-Setter und Getter zum Speichern des folder_name_short Wert, sondern ein öffentliches get/set-Methode implementieren, um die folder_name in der db zu setzen und diese Methode in der Steuerung aufrufen. Also:

[NotMapped] 
public string folder_name_short { get; set; } 
public string getfolder_name_short() 
{ 
    string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); 
    return shortname; 
} 
public void setfolder_name_short(string newname) 
{ 
    string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); 
    folder_name = folder_name.Replace(shortname, newname); 
} 
+0

Sind Sie sicher zu verstehen, dass Ordner-Objekt aus der Datenbank gefüllt wird und folder_name ist auch nicht null nach einreichen? – TSungur

+0

Ja, der aktuelle Wert von folder_name_short ist in der imputbox sichtbar. –

+0

Ich meine, wenn Sie die Seite übergeben, direkt bevor Sie in die Ausnahmelinie kommen (Sie könnten einen Haltepunkt in dieser Zeile setzen), schauen Sie sich die Eigenschaft folder_name an, ist sie in diesem Moment anders als null? – TSungur

Antwort

1

Wenn der Wert, der auf dem Formular bearbeitet wird, ist der Kurzname folder_name_short dann könnte die Modellklasse seine String-Eigenschaft enthalten:

public string folder_name_short { get; set; } 

Diese Eigenschaft enthält keine Logik. Jeder andere Code, der Logik enthält, könnte sich in einer Aktionsmethode im Controller befinden.

Es scheint, dass Sie die gleiche Klasse für DB-Zugriff und als eine Modellklasse für die MVC-Ansicht verwenden, die die Ursache des Problems ist.

+0

Ich bin relativ neu zu asp.net, also entschuldige mich für diese Frage, aber was meinst du mit "gleiche Klasse für DB-Zugriff und als eine Modellklasse für die MVC-Ansicht"? Wenn ich diese einfache Logik hier nicht implementiere, muss ich es in jedem Controller machen. Bitte beachten Sie auch meine Edit –

+0

Die Klasse 'Folder' ist mit dem' Key' Attribut versehen, von dem ich annahm, dass Sie diese Klasse in der Datenzugriffsschicht und auch als Klasse für die Ansicht in der Webanwendung verwenden, ist es das Fall? Das Modell für ein Formular und ein Modell für eine Entität sind in der Regel unterschiedlich, und dann enthält die eine ausgeführte Klasse gemischte Daten mit verschiedenen Gruppen von Dekorationsattributen (Datenzuordnung vs. Formularvalidierung). Es ist sauberer, eine separate Klasse für das Ansichtsmodell zu haben. Die Logik, die wiederholt wird, kann einer Business-Klasse oder einer Hilfs- (Hilfs-) Klasse zugeführt werden. –

+0

Ja, das ist der Fall. Ich verwende diese Klasse in der Ansicht und für das Datamapping. Aber es funktioniert für alle anderen veiws und Controller. Ich meine, ich kann das 'folder_name_short' in allen anderen Fällen bekommen, aber nur in dieser Ansicht versuche ich es zu setzen und bekomme einen Fehler auf dem ** Getter ** nicht dem Setter. Ich verstehe nicht warum. Abgesehen davon, wenn ich den Setter auskommentiere, arbeitet der Getter ohne Ausnahmen. –

0
[HttpPost] 
[("Rename")] 
public async Task<IHttpActionResult> ChangeFolderPath(Folder folder) 
{ 
    //Put a breakpoint here and make sure the folder has a value 
} 

wahrscheinlich, dass die Setter-Methode den Wert von folder_name überschreibt.

würde ich diesen Thread empfehlen zu helfen, individuelle Setter C# properties: how to use custom set property without private field?

EDIT

public class Folder 
    { 
     [Key] 
     public string folder_name { get; set; } 

     /*Model Logic shouldn't be in the Poco*/ 
     /*You may put that in your model or best thing would be to implement a repository pattern*/ 
     public string ShortName() 
     { 
      string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); //System.NullReferenceException here 
      return shortname; 
     } 
     public void SetUsingShortName(string value) 
     { 
      string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); 
      this.folder_name = folder_name.Replace(shortname, value); 
     } 
    } 
+0

Willst du, dass ich das zu meinem Controller hinzufüge? Ich komme nicht mal zur Umbenennen Aktion im Controller, die Ausnahme im Model kommt vor –

+0

Sie sollten folder_name_short durch eine Methode anstelle einer Eigenschaft ersetzen. Ich habe meinen Beitrag aktualisiert – Alegrowin

+0

Wenn Sie eine Logik für den Zugriff auf Ihre Poco (Objekte) benötigen, ist die beste Sache, Logik in einer Top-Level-Entität wie das Modell zu implementieren. Sie trennen also die 'Datenbank-Entität' von der Logik der Einstellung, um die Daten zu erhalten, und diese Methoden könnten später woanders wiederverwendet werden. – Alegrowin

Verwandte Themen