Domanda

La possibilità di lasciare che il modello di gestire la propria convalida mi ha portato a iniziare a giocare con l'anteprima di rilascio MVC 2. Finora, mi piace la semplicità del sistema di convalida. Tuttavia, ho incontrato un posto di blocco. Questo stile di convalida funziona bene per semplici oggetti vista del modello. Per esempio se ho un oggetto del modello denominato auto e sto cercando di creare una visualizzazione per creare una nuova auto:

----- Modello -------

public class Car
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
}

----- controller ---------

public class CarController : Controller
{
    public ActionResult Create()
    {
        Car myCar = new Car();
        return View("Create", myCar);

    }

    [HttpPost]
    public ActionResult Create(Car myCar)
    {
        if (!ModelState.IsValid)
        {
            return View("Create", myCar);
        }

        //Do something on success
        return View("Index");

    }

}

------- Vedi --------------

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

    <% 
        using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Edit User Profile</legend>
            <p>
                <label for="Id">Id:</label>
                <%= Html.TextBox("Id", Model.Id)%>
                <%= Html.ValidationMessage("Id") %>
            </p>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name", Model.Name)%>
                <%= Html.ValidationMessage("Name") %>
            </p>
            <p>
                <label for="Color">Color:</label>
                <%= Html.TextBox("Color", Model.Color)%>
                <%= Html.ValidationMessage("Color") %>
            </p>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

</asp:Content>

Questo funziona come un fascino. Ma non tutti i miei punti di vista, o oggetti del modello per quella materia, sono semplici. Potrei avere un oggetto modello di auto, come:

----- Modello -------

public class PaintScheme
{
    public int Red { get; set; }
    public int Blue { get; set; }
    public int Green { get; set; }
}

public class Car
{
    public string Id { get; set; }
    public string Name { get; set; }
    public PaintScheme Paint{ get; set; }
}

------- Vedi --------------

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

    <% 
        using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Edit User Profile</legend>
            <p>
                <label for="Id">Id:</label>
                <%= Html.TextBox("Id", Model.Id)%>
                <%= Html.ValidationMessage("Id") %>
            </p>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name", Model.Name)%>
                <%= Html.ValidationMessage("Name") %>
            </p>
            <p>
                <label for="Red">Color Red:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
            </p>
            <p>
                <label for="Blue">Color Blue:</label>
                <%= Html.TextBox("Blue", Model.Paint.Blue)%>
                <%= Html.ValidationMessage("Blue") %>
            </p>
            <p>
                <label for="Green">Color Green:</label>
                <%= Html.TextBox("Green", Model.Paint.Green)%>
                <%= Html.ValidationMessage("Green") %>
            </p>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

</asp:Content>

Quando aggiungo PaintScheme di immobili da mio punto di vista, non sono riportati con l'oggetto "myCar" passato nella mia azione del controller. C'è un modo per risolvere questo senza dover ricostruire l'oggetto da una collezione modulo e quindi il controllo del ModelState?

È stato utile?

Soluzione

  1. Si dovrebbe avere la setter pubblico per le proprietà che si desidera essere vincolato. Mi chiedo come funziona il primo campione per come tutto è privato.
  2. Devi dopo almeno un valore della proprietà PaintScheme per essere in grado di legare esso.
  3. Tutte le proprietà bambino dovrebbe essere preceduto con il path ad esso. Dove path può essere definito come * (PropertyName.) **.

Sembra che il punto 3 non è soddisfatto nella vista. Modificare la parte appropriata della vista a questo:

        <p>
            <label for="Red">Color Red:</label>
            <%= Html.TextBox("Paint.Red")%>
            <%= Html.ValidationMessage("Red") %>
        </p>
        <p>
            <label for="Blue">Color Blue:</label>
            <%= Html.TextBox("Paint.Blue")%>
            <%= Html.ValidationMessage("Blue") %>
        </p>
        <p>
            <label for="Green">Color Green:</label>
            <%= Html.TextBox("Paint.Green")%>
            <%= Html.ValidationMessage("Green") %>
        </p>

Inoltre nota che ho rimosso i valori espliciti dal aiutante TextBox per evitare possibili NullReferenceException.

Altri suggerimenti

Il modo più semplice per affrontare questo è quello di appiattire il modello utilizzando un dto. Quindi utilizzare automapper per mappare l'oggetto di dominio per il vostro modello di vista. Questa traduzione può essere definita in modo tale che si converte l'enum in una stringa e indietro. Poi convalida funzionerà e il tuo bom non toccherà la vista mantenendo la vostra separazione delle preoccupazioni abbastanza bene.

Per la parte di colore si può avere qualcosa di simile, essendo un int io non pensate di usare una casella di testo, ma questo si legherà il colore rosso (se il valore di ingresso è un numero)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top