Pregunta

La capacidad de dejar que el modelo maneje su propia validación me ha llevado a comenzar a jugar con la versión preliminar de MVC 2.Hasta ahora, me gusta la simplicidad del esquema de validación.Sin embargo, me he topado con un obstáculo.Este estilo de validación funciona bien para objetos de modelo de vista simple.Por ejemplo, si tengo un objeto modelo llamado auto y estoy buscando crear una vista para crear un auto nuevo:

-----Modelo-------

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

-----Controlador---------

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");

    }

}

-------Vista--------------

<%@ 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>

Esto funciona de maravilla.Pero no todas mis vistas, ni todos los objetos modelo, son simples.Podría tener un objeto de modelo de automóvil como:

-----Modelo-------

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; }
}

-------Vista--------------

<%@ 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>

Cuando agrego el Esquema de pintura En mi opinión, las propiedades no se transfieren con el objeto "myCar" pasado a la acción de mi controlador.¿Hay alguna manera de resolver esto sin tener que reconstruir el objeto a partir de una colección de formularios y luego verificar ModelState?

¿Fue útil?

Solución

  1. Deberías tener el colocador público para propiedades que desea vincular.Me pregunto cómo te funcionará la primera muestra, ya que todo es privado.
  2. Tienes que publicar al menos un valor de la propiedad PaintScheme para poder vincularlo.
  3. Todas las propiedades secundarias deben tener el prefijo camino lo.Dónde camino se puede definir como *(NombrePropiedad.)**.

Parece que el punto 3 no se cumple en la Vista.Cambie la parte apropiada de la vista a esto:

        <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>

Además, tenga en cuenta que eliminé valores explícitos del asistente TextBox para evitar una posible excepción NullReferenceException.

Otros consejos

La forma más fácil de lidiar con esto es para aplanar su modelo utilizando un dto. A continuación, utilice AutoMapper para mapear el objeto de dominio a su modelo de vista. Esta traducción se podría definir de tal manera que convierta la enumeración de una cadena y la espalda. Luego de validación va a funcionar y su lista de materiales no tocará la vista el mantenimiento de su separación de las preocupaciones bastante bien.

Para la parte de color que puede tener algo como esto, siendo un int No creo que va a utilizar un cuadro de texto, pero esto va a obligar a su color rojo (si el valor de entrada es un número)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top