views:

79

answers:

1

Hi folks,

I have a controller that should add a person to the db, but in the form I have fields for two kinds of person and only one should be add, then when I post it verifies if it is a pf (type 1) or pj (type 2) person, then I do the validation stuff based in the kind of person it is, that's ok, but even if I don't add any error because the form was completely fed, I get errors from the other fields, but I didn't say they are required in any place, why does mvc add an error like this? And what is more weird is that auto erros change based in how many fields I've typed, may they be related with the form I'm feeding? I can't understand what's happening, help!!!

My code files:

Pessoa.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CarvalhoRodrigues.Domain.Repositories.Cadastro;

namespace CarvalhoRodrigues.Domain.Cadastro
{
    public class Pessoa
    {
        public Pessoa()
        {
            this.Endereco = new List<Endereco>();
        }

        public virtual long Id { get; set; }
        public enum TipoPessoa { Fisica, Juridica }
        public virtual TipoPessoa Tipo { get; set; }
        public virtual ICollection<Endereco> Endereco { get; set; }

    }
}

PessoaFisica.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CarvalhoRodrigues.Domain.Cadastro
{
    public class PessoaFisica : Pessoa
    {
        public PessoaFisica()
            : base()
        {
            this.Tipo = Pessoa.TipoPessoa.Fisica;
        }
        public virtual string CPF { get; set; }
        public virtual string Nome { get; set; }
        public virtual string Sexo { get; set; }
        public virtual DateTime DataNascimento { get; set; }
        public virtual string RG { get; set; }
        public virtual string RGOrgaoExpedidor { get; set; }
        public virtual DateTime RGDataExpedicao { get; set; }
        public virtual string Pai { get; set; }
        public virtual string Mae { get; set; }
    }
}

PessoaJuridica.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CarvalhoRodrigues.Domain.Cadastro
{
    public class PessoaJuridica : Pessoa
    {
        public PessoaJuridica()
            : base()
        {
            this.Tipo = Pessoa.TipoPessoa.Juridica;
            this.Representantes = new List<Pessoa>();
        }

        public virtual string CNPJ { get; set; }
        public virtual string RazaoSocial { get; set; }
        public virtual DateTime DataConstituicao { get; set; }
        public virtual string NomeFantasia { get; set; }
        public virtual ICollection<Pessoa> Representantes { get; set; }
    }
}

Inserir.aspx

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

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Inserir
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript" src="../../Scripts/carvalhorodrigues-cadastro.js"></script>
<% using (Html.BeginForm())
   { %>
<h2>Inserir Cliente</h2>
<%= Html.ValidationSummary() %>
<fieldset>
    <legend>Tipo de Pessoa</legend>
    <div>
        <%= Html.RadioButton("TipoPessoa", "PF", true, new { @class = "TipoPessoa" })%> Pessoa Física
        <%= Html.RadioButton("TipoPessoa", "PJ", false, new { @class = "TipoPessoa" })%> Pessoa Jurídica
    </div>
</fieldset>

<fieldset>
    <legend>Dados de Cadastro</legend>
    <div id="PF">
        <p>
        <label for="pf.Nome">Nome:</label> <br />
        <%= Html.TextBox("pf.Nome")%> <%= Html.ValidationMessage("pf.Nome", "*")%>
        </p>

        <p>
        <label for="pf.CPF">CPF:</label> <br />
        <%= Html.TextBox("pf.CPF")%> <%= Html.ValidationMessage("pf.CPF", "*")%>
        </p>

        <p>
        <label for="pf.Sexo">Sexo:</label> <br />
        <%= Html.RadioButton("pf.Sexo", "Masculino", true) %> Masculino
        <%= Html.RadioButton("pf.Sexo", "Feminino")%> Feminino
        </p>

        <p>
        <label for="pf.DataNascimento">Data de Nascimento:</label> <br />
        <%= Html.TextBox("pf.DataNascimento")%> <%= Html.ValidationMessage("pf.DataNascimento", "*")%>
        </p>

        <p>
        <label for="pf.RG">RG:</label> <br />
        <%= Html.TextBox("pf.RG")%> <%= Html.ValidationMessage("pf.RG", "*")%>
        </p>

        <p>
        <label for="pf.RGOrgaoExpedidor">Órgão Expedidor:</label> <br />
        <%= Html.TextBox("pf.RGOrgaoExpedidor")%> <%= Html.ValidationMessage("pf.RGOrgaoExpedidor", "*")%>
        </p>

        <p>
        <label for="pf.RGDataExpedicao">Data de Expedição:</label> <br />
        <%= Html.TextBox("pf.RGDataExpedicao")%> <%= Html.ValidationMessage("pf.RGDataExpedicao", "*")%>
        </p>

        <p>
        <label for="pf.Pai">Pai:</label> <br />
        <%= Html.TextBox("pf.Pai")%> <%= Html.ValidationMessage("pf.Pai", "*")%>
        </p>

        <p>
        <label for="pf.Mae">Mãe:</label> <br />
        <%= Html.TextBox("pf.Mae")%> <%= Html.ValidationMessage("pf.Mae", "*")%>
        </p>
    </div>

    <div id="PJ">
        <p>
        <label for="pj.RazaoSocial">Razão Social:</label> <br />
        <%= Html.TextBox("pj.RazaoSocial")%> <%= Html.ValidationMessage("pj.RazaoSocial", "*")%>
        </p>

        <p>
        <label for="pj.CNPJ">CNPJ:</label> <br />
        <%= Html.TextBox("pj.CNPJ")%> <%= Html.ValidationMessage("pj.CNPJ", "*")%>
        </p>

        <p>
        <label for="pj.NomeFantasia">Nome Fantasia:</label> <br />
        <%= Html.TextBox("pj.NomeFantasia")%> <%= Html.ValidationMessage("pj.NomeFantasia", "*")%>
        </p>

        <p>
        <label for="pj.DataConstituicao">Data de Constituição:</label> <br />
        <%= Html.TextBox("pj.DataConstituicao")%> <%= Html.ValidationMessage("pj.DataConstituicao", "*")%>
        </p>
    </div>
</fieldset>
<input type="submit" value="Cadastrar" />
<% } %>

ClientesController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using CarvalhoRodrigues.Domain.Cadastro;
using CarvalhoRodrigues.Domain.Repositories.Cadastro;

namespace CarvalhoRodrigues.Controllers
{
    public class ClientesController : Controller
    {
        // GET: /clientes/
        public ActionResult Index()
        {
            return View();
        }

        // GET: /clientes/inserir/
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Inserir()
        {
            return View();
        }

        // POST: /clientes/inserir/
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Inserir(string TipoPessoa, [Bind(Exclude = "Id", Prefix="pf")]PessoaFisica pf, [Bind(Exclude = "Id", Prefix="pj")]PessoaJuridica pj)
        {
            IPessoaRepository repository = new PessoaRepository();

            if (TipoPessoa == "PF")
            {
                pf.Tipo = Pessoa.TipoPessoa.Fisica;

                if (pf.Nome == "")
                    ModelState.AddModelError("pf.Nome", "Nome não informado");
                if (pf.CPF == "")
                    ModelState.AddModelError("pf.CPF", "CPF não informado");
                if (pf.DataNascimento == new DateTime())
                    ModelState.AddModelError("pf.DataNascimento", "Data de nascimento não informada");
                if (pf.RG == "")
                    ModelState.AddModelError("pf.RG", "RG não informado");
                if (pf.RGOrgaoExpedidor == "")
                    ModelState.AddModelError("pf.RGOrgaoExpedidor", "Órgão expedidor não informado");
                if (pf.RGDataExpedicao == new DateTime())
                    ModelState.AddModelError("pf.RGDataExpedicao", "Data de expedição não informada");
            }
            else if (TipoPessoa == "PJ")
            {
                if (pj.RazaoSocial == "")
                    ModelState.AddModelError("pj.RazaoSocial", "Razão social não informada");
                if (pj.CNPJ == "")
                    ModelState.AddModelError("pj.CNPJ", "CNPJ não informado");
                if (pj.DataConstituicao == new DateTime())
                    ModelState.AddModelError("pj.DataConstituicao", "Data de constituição não informada");
            }

            if (ModelState.IsValid)
            {
                if (TipoPessoa == "PF")
                    repository.Inserir(pf);
                else if (TipoPessoa == "PJ")
                    repository.Inserir(pj);
            }

            return View();
        }
}

If I don't type any field with the "PF" radio selected I got the following errors:

  • CPF não informado
  • Nome não informado
  • A value is required.
  • Data de nascimento não informada
  • RG não informado
  • Órgão expedidor não informado
  • A value is required.
  • Data de expedição não informada
  • A value is required.

When I think it should be only:

  • CPF não informado
  • Nome não informado
  • Data de nascimento não informada
  • RG não informado
  • Órgão expedidor não informado
  • Data de expedição não informada

And if I type all the PF fields, I get only one error:

  • A value is required.

The messages doesn't say where the error comes from. My model classes are just gets and sets, I'm using Nhibernate, they don't have any logic and neither any required instruction in it's fields.

Help guyz, I'm not understanding what is happening whit the ModelState thing.

+1  A: 

You probably have a non-NULL field somewhere. The "A value is required" error is added by a lower layer.

This could be the primary key if it is not defined as autonumbering (Identity spec) or some other column that is not set from your code.

Henk Holterman
So, can I reset all the erros this "lower layer" fired before I add MY errors? THANKZ for the reply, I still can't understand (the PJ fields are non-NULL, but why I get only one 'value is required' still a mistery, should be 3) but it's a light already! Hug's!
Alaor
Or better, should be ZERO, I took a look in the debug and all the fields of pj are not null, they got empty values, but are not null.
Alaor
"Can I reset..." : probably not, I think that a) you validate as OK, b) the datacontext tries to update the database and aither the mapping layer or the database gives this error.
Henk Holterman
Thankz man, actually what happens is that I have some DateTime fields and in my model they are not nullable, when I post it, the string fields get an empty string, but the model binder do not give an "empty date", it throw an error in modelstate, I resolved it changing my DateTime properties to DateTime?, now it ignores the DateTime properties in the built-in model binder, it's not what I'd want, but it's working. Thankz for you comment's, it make me understand what's happening. Hugs!
Alaor