2010-11-18 4 views
1

Ich habe endlich eine Hürde überwunden und kann nun erfolgreich neue Modelldaten erstellen. Jetzt gibt es noch einen Haken - Validierung. Der Großteil der Validierung scheint einfach zu sein, da viele meiner Modelldaten skalare Werte sind. Es gibt jedoch eine Viele-zu-Viele-Beziehung, mit der ich mich verbinde, daher bin ich mir nicht sicher, wie ich das überprüfen soll. Mein Modell ist (wieder einmal):Wie macht man MVC2/EF4 EntityCollection Validierung mit Datenanmerkungen?

Game (only listing the relevant columns): 
    GameID - int (primary key, auto-incr) 

Platform: 
    PlatformID - int (primary key, auto-incr) 
    Name - string 

GamePlatform (not a visible entity): 
    GameID - int (foreign key from Games) 
    PlatformID - int (foreign key from Platforms) 

Und meine Methode Create (ja, ich weiß, es ist schlampig und dilettantisch - ich am einen Amateur und versuchen zu lernen, ich werde auf jeden Fall fügt Fehler es zu überprüfen.. ich versuche nur, um das große Bild von der view- zu bekommen> Controller-> Validierungs-> persistieren-in-db/show Fehler verarbeiten unten):

public ActionResult CreateReview([Bind(prefix = "GameData")]Game newGame, int[] PlatformIDs) 
{ 
    try 
    { 
     foreach(int i in PlatformIDs) 
     { 
      Platform plat = _siteDB.Platforms.Single(p => p.PlatformID == i); 
      newGame.Platforms.Add(plat); 
     } 

     newGame.LastModified = Datetime.Now; 

     _siteDB.Games.AddObject(newGame); 
     _siteDB.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

das Array von PlatformIDs wird von einer Gruppe geliefert von Kontrollkästchen in meiner Sicht. Damit mein Spiel gültig ist, muss es mit mindestens einer Plattform verknüpft sein. Ich bin mir nicht sicher, wie ich das mit Datenanmerkungen validieren kann oder ob es überhaupt möglich ist. Jede Hilfe würde sehr geschätzt werden.

Antwort

1

Wenn ich Ihre Frage richtig verstehe, enthält Ihr int [] möglicherweise Ints mit der ID einer Plattform in Ihrer DB und Sie möchten sicherstellen, dass Ihr int [] mindestens eine gültige PlatformID enthält, korrekt?

Ab sofort können Sie tun, nur eine einfache Prüfung, bevor sie in Ihrer Logik zu gehen:

// If there aren't any IDs in Platform that are in PlatformIDs... 
if (!_siteDB.Platforms.Any(p => PlatformIDs.Contains(p.PlatformID))) 
    Return RedirectToAction("Index"); 
    // And probably tell the user to check a box, if they did, 
    // One of your checkboxes isn't matching up with your PlatformIDs 

Ideal tun, was man will, ist die int [] zum Modell hinzufügen, so dass Sie die Modellvalidierung überprüfen können. Da datenbankbasierte Daten normalerweise nicht int [] speichern, fügen Sie sie Ihrem Spielmodell hinzu. Die EF legt wahrscheinlich Ihre DB-Entitäten in Ihrem Modellordner ab und wenn Sie sie betrachten, sehen Sie, dass sie Teilklassen sind. So fügen Sie diese in Ihrem Ordner Modelle:

public partial class Game 
{ 
    public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited 
} 

// Also add this which you'll see why below 
public partial class Platform 
{ 
    public static bool IsValidPlatformID(int PlatformID) 
    { 
     using (SiteDBEntities _siteDB = new SiteDBEntities()) 
      return _siteDB.Platforms.Any(p => p.PlatformID.Equals(PlatformID)); 
    } 
} 

Dann eine benutzerdefinierte Validation Klasse hinzufügen:

public ContainsValidPlatformIDAttribute : ValidationAttribute 
{ 

    public ContainsValidPlatformIDAttribute() { } 

    public override bool IsValid(object value) 
    { 
     Dictionary<int, bool> supportedPlatforms = (Dictionary<int, bool>)value; 
     if (value == null) 
      return true; 
     foreach (int i in values) 
     { 
      if (supportedPlatforms.Values.Any(b => b.Equals(true)))// Edited 
       return false; 
     } 
     return true; 
} 

Jetzt ist Ihre Immobilie mit ihm in der Spielklasse dekorieren:

[ContainsValidPlatformID(Error = "You did not select a valid Platform.")] 
public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited 

(Edited) Anstatt nun ein Kontrollkästchen für jede Plattform zu programmieren, fügen Sie dieses stattdessen hinzu:

<%: Html.CheckboxFor(model => model.SupportedPlatforms[0]) %> 
<%: Html.ValidationMessageFor(model => model.SupportedPlatforms[0]) %> 

(bearbeitet) Jetzt sind Ihre Kontrollkästchen an das Modell gebunden, Sie können das Modell im Controller validieren, und Sie können das Argument int [] von Ihrer Aktionsmethode entfernen. Dies alles wurde von meinem Kopf aus in diesen Editor programmiert, so dass Sie hier und da einige Dinge verändern müssen, aber das ist die Richtung, in die Sie gehen sollten, wenn Sie mit Modellen in Ansichten arbeiten.

Schauen Sie sich auch an, was Scott Guthrie in seinem Blog zum Thema MVC Model Validation geschrieben hat. Hoffentlich werden Sie mit meiner Probe und Scotts Blog in die richtige Richtung zeigen.

+0

Ja, das Formular ist ein bisschen ein Problem. Ich habe die Checkboxen manuell hart codiert, so dass es sich größtenteils um reines HTML handelt, deren Werte in einer Schleife mit Model.AllPlatforms [i] .PatformID gesetzt werden. Ich diskutiere immer noch darüber, ob ich der Platform einen nicht-db-backed Boolean hinzufügen soll oder nicht, um anzugeben, ob eine Platform in der Ansicht ausgewählt wurde. Es würde mir erlauben, einen stark typisierten HTML-Helfer zu verwenden, und würde wahrscheinlich die Validierung auf lange Sicht erleichtern. Ihre Gedanken? –

+0

Macht so etwas Sinn? http: // Pastie.org/1311555 –

+0

Hey Kevin, habe gerade meine Antwort bearbeitet. Ich denke, was ich zur Verfügung gestellt habe, ist etwas nach dem, was man tun sollte. Ich bin mir sicher, dass es eine Vielzahl von Möglichkeiten gibt, wie Sie die Checkboxen in das Modell einbinden können, aber letztendlich möchten Sie sie in irgendeiner Form in das Modell einbinden. Lass mich wissen, ob das Sinn macht oder nicht. – nwayve

Verwandte Themen