Pergunta

A capacidade de deixar o modelo lidar com sua própria validação me levou a começar a jogar com a versão de visualização do MVC 2. Até agora, gosto da simplicidade do esquema de validação. No entanto, eu encontrei um obstáculo. Esse estilo de validação funciona bem para obter objetos de modelo simples de exibição. Por exemplo, se eu tiver um objeto modelo chamado carro E estou procurando criar uma visão para criar um carro novo:

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

    }

}

-------Visão--------------

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

Isso funciona como um charme. Mas nem todos os meus pontos de vista, ou objetos modelo para esse assunto, são simples. Eu posso ter um objeto de modelo de carro 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; }
}

-------Visão--------------

<%@ 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 eu adiciono o Paintscheme Propriedades para minha opinião, elas não são transportadas com o objeto "mycar" passado para a minha ação do controlador. Existe uma maneira de resolver isso sem precisar reconstruir o objeto de uma coleção de formulários e depois verificar o ModelState?

Foi útil?

Solução

  1. Você deveria ter o setter público Para propriedades que você deseja estar vinculado. Eu me pergunto como a primeira amostra funciona para você, pois tudo é privado.
  2. Você tem que postar pelo menos um valor da propriedade Paintscheme para poder ligá -la.
  3. Todas as propriedades infantis devem ser prefixadas com o caminho para isso. Onde caminho pode ser definido como*(PropertyName.) **.

Parece que o ponto 3 não está satisfeito na opinião. Altere a parte apropriada da visão para isso:

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

Além disso, observe que removi valores explícitos do auxiliar de caixa de texto para evitar possível NullReferenceException.

Outras dicas

A maneira mais fácil de lidar com isso é achatar seu modelo usando um DTO. Em seguida, use o AutomApper para mapear seu objeto de domínio para o seu modelo de visualização. Essa tradução pode ser definida de tal maneira que você converta a enumeração em uma corda e traseira. Em seguida, a validação funcionará e sua boa não tocará na visão, mantendo sua separação de preocupações bastante bem.

Para a parte da cor, você pode ter algo assim, sendo um int, não acho que você usará uma caixa de texto, mas isso ligará sua cor vermelha (se o valor de entrada for um número)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top