2013-12-09 16 views
6

Ich habe zwei Entitäten:MVC Required Property innerhalb Optional Property

public class ParentThing 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    public ChildThing TheFirstThing { get; set; } 

    public ChildThing TheSecondThing { get; set; } 
} 

public class ChildThing 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    public string Code { get; set; } 

    public string Name { get; set; } 
} 

und einen Blick Modell:

public class ParentViewModel 
{ 
    public string Message { get; set; } 

    public ParentThing ParentThing { get; set; } 
} 

und eine Ansicht:

@using (@Html.BeginForm()) 
{ 
    <label>Code 1</label> 
    @Html.EditorFor(model => model.ParentThing.TheFirstThing.Code) 

    <label>Name 1</label> 
    @Html.EditorFor(model => model.ParentThing.TheFirstThing.Name) 

    <label>Code 2</label> 
    @Html.EditorFor(model => model.ParentThing.TheSecondThing.Code) 

    <label>Name 2</label> 
    @Html.EditorFor(model => model.ParentThing.TheSecondThing.Name) 

    <input type="submit" value="Save" /> 
} 

In meinem Beitrag zurück ich hinzufügen das ParentThing in den Kontext und versucht, Änderungen zu speichern. Ich erhalte einen Überprüfungsfehler für die Code-Eigenschaft der TheSecondThing-Eigenschaft von dem ParentThing, wie es erforderlich ist.

Welche Alternativen gibt es zum Speichern einer optionalen Eigenschaft, die erforderliche Eigenschaften enthält?

+0

Die Alternative besteht darin, die Abhängigkeit von Entitätsklassen in Ihren Ansichtsmodellen zu entfernen. Sie möchten Datenübertragungsobjekte (DTOs) verwenden. Diese http://stackoverflow.com/questions/5995140/models-viewmodel-dtos-in-mvc-3-application hilft Ihnen beim Einstieg. – Jasen

Antwort

0

Wie Jamie vorgeschlagen, entfernen Sie alle Abhängigkeiten zwischen Ihren Entitäten und Ihren Modellen ... sie sind 2 separate Dinge Verwenden Sie keine Datenanmerkungen für Ihre Entitäten, verwenden Sie Datenanmerkungen auf Ihren Modellen. Entfernen Sie die ParentThing-Eigenschaft Ihres Modells und fügen Sie sie nach Bedarf als primitive Eigenschaften in Ihr Modell ein (z. B. Message, ParentThingId, TheFirstThingId, TheFirstThingCode, TheFirstThingName usw.) und fügen Sie dem Modell alle Ihre Annotationsattribute hinzu. Wenn Sie Ihre Entitäten validieren müssen (was Sie wahrscheinlich tun werden), tun Sie dies in Ihrer Geschäftslogik.

Ich hoffe, dass es Sinn

Leo macht.

0

Als Antwort auf die aktuellen Vorschläge ist das, was ich jetzt habe.

Entitäten bleiben gleich.

Das modifizierte Ansicht Modell:

public class ParentViewModel 
{ 
    public string Message { get; set; } 

    public string FirstThingCode { get; set; } 

    public string FirstThingName { get; set; } 

    public string SecondThingCode { get; set; } 

    public string SecondThingName { get; set; } 
} 

Modifiziertes Ansicht:

@using (@Html.BeginForm()) 
{ 
    <label>Code 1</label> 
    @Html.EditorFor(model => model.FirstThingCode) 

    <label>Name 1</label> 
    @Html.EditorFor(model => model.FirstThingName) 

    <label>Code 2</label> 
    @Html.EditorFor(model => model.SecondThingCode) 

    <label>Name 2</label> 
    @Html.EditorFor(model => model.SecondThingName) 

    <input type="submit" value="Save" /> 
} 

Der DTO:

public class ParentThingDTO 
{ 
    public ParentThingDTO(ParentViewModel model) 
    { 
     FirstThingCode = model.FirstThingCode; 
     FirstThingName = model.FirstThingName; 
     SecondThingCode = model.SecondThingCode; 
     SecondThingName = model.SecondThingName; 
    } 

    public int Id { get; set; } 

    public string FirstThingCode { get; set; } 

    public string FirstThingName { get; set; } 

    public string SecondThingCode { get; set; } 

    public string SecondThingName { get; set; } 

    public ParentThing GenerateEntity() 
    { 
     var thing = new ParentThing(); 
     thing.TheFirstThing = new ChildThing 
     { 
      Code = FirstThingCode, 
      Name = FirstThingName 
     }; 

     if (!string.IsNullOrWhiteSpace(SecondThingCode)) 
     { 
      thing.TheSecondThing = new ChildThing 
      { 
       Code = SecondThingCode, 
       Name = SecondThingName 
      }; 
     } 

     return thing; 
    } 
} 

die Postback Aktion in der Steuerung:

[HttpPost] 
    public ActionResult Create(ParentViewModel model) 
    { 
     try 
     { 
      var dto = new ParentThingDTO(model); 
      var parentThing = dto.GenerateEntity(); 

      using (var context = new QuantumContext()) 
      { 
       context.ParentThings.Add(parentThing); 
       context.SaveChanges(); 
       model.Message = "Saved"; 
      } 
     } 
     catch (Exception ex) 
     { 
      model.Message = ex.Message; 
     } 

     return View(model); 
    } 

Der Null- oder Leerraumtest in der dto GenerateEntity-Methode löst mein anfängliches Problem der MVC-erforderlichen Eigenschaft innerhalb der optionalen Eigenschaft. Wie sieht es aus?

+0

Wenn Sie eine Zeile editieren, wollen Sie statt der Generierung eines neuen 'ParentThing' die 'ParentThing' -Instanz (nach ID) suchen und abrufen. Bearbeiten Sie dann die Entity-Werte basierend auf den neuen Werten, die von Ihrer 'ParentThingDTO' kommen. Bei der Erstellung haben Sie keine bestehende Zeile, so dass Sie sicher eine neue Entität erstellen können, wie Sie es getan haben. – Jasen