Initialize object in Asp.Net MVC

1

I have a class Cidade that has the property Estado of type Estado :

public class Cidade
{
    [Key]
    public int ID { get; set; }

    [Required(ErrorMessage = "Campo Nome é obrigatório!")]
    public String Nome { get; set; }

    [Required(ErrorMessage = "Campo Estado é obrigatório!")]
    public Estado Estado { get; set; }

    public Cidade() { }

    public Cidade(int ID, String Nome, Estado Estado)
    {
        this.ID = ID;
        this.Nome = Nome;
        this.Estado = Estado;
    }

When I register a new Cidade it gives zero reference error. I think it's because the Estado object was not initialized, but where should I initialize this object? I already tried the constructor of class Cidade , but it did not work.

The method in controller that receives the object Cidade from View to the register.

        [HttpPost]
        [Authorize]
        public ActionResult AddCidade(Cidade cidade)
        {
            if (ModelState.IsValid)
            {
                CidadeDal cd = new CidadeDal();
                cd.Salvar(cidade);
                return RedirectToAction("AddCidade");
            }
            else
            {
                ModelState.AddModelError("", "Houve um problema ao preencher o formulário, verifique os erros e tente novamente!");
                return RedirectToAction("AddCidade");
            }
        }

Follow the View:

@model Projeto_P1.Models.Cidade
@{
    ViewBag.Title = "Cadastro de Cidades";
}

@using (Html.BeginForm("AddCidade", "Cidade", FormMethod.Post))
{
    @Html.ValidationSummary(false, "Ocorreram erros no preenchimento das informações, verifique a lista abaixo e corrija os erros!")
    <div class="container">
        <fieldset>
            <div>
                @Html.Label("Cidade")
                @Html.TextBoxFor(model => model.Nome, new { @class = "maiusculo"})
            </div>
            <div>
                @Html.Label("País")
                @Html.DropDownList("pais", (SelectList)ViewData["paises"], "Selecione", new { id = "PaisID"})
            </div>
            <div>
                @Html.Label("Estado")
                @Html.DropDownListFor(model => model.Estado, Enumerable.Empty<SelectListItem>(), "Selecione")
            </div>

            <br />

            <input type="submit" value="Cadastrar" />
        </fieldset>
    </div>
}

<script type="text/javascript">
    $(document).ready(function () {
        $("#PaisID").change(function () {
            $.ajax({
                url: "/Estado/ListaEstados",
                type: 'POST',
                data: { ID: $(this).val() },
                datatype: 'json',
                success: function (data) {
                    var elements = "";
                    $.each(data, function () {
                        elements = elements + '<option value="' + this.ID + '">' + this.Nome + '</option>'
                    })
                    $('#Estado').empty().attr('disabled', false).append(elements);
                }
            });
        });
    });
</script>
    
asked by anonymous 08.08.2014 / 19:09

2 answers

1

Your modeling is incorrect. As it is done, the ModelBinder (class that converts the values of View in the passed parameter to Controller ) can not make the association correctly, because Estado is a complex entity, and what is being putting on screen is just the id of Estado , which is a simpler entity. In this case, an integer.

Modify your Model to the following:

public class Cidade
{
    [Key]
    public int ID { get; set; }
    [Required(ErrorMessage = "Campo Estado é obrigatório!")]
    public int EstadoID { get; set; }

    [Required(ErrorMessage = "Campo Nome é obrigatório!")]
    public String Nome { get; set; }

    public virtual Estado Estado { get; set; }
}

It may seem long-winded to have EstadoID and the virtual Estado object separately, but in fact this is how the Entity Framework and the MVC work. Imagine that you do not want to use the information of Estado , that is, to load it minimally. The only information required for this is the ID of Estado .

Builders are not really necessary for what you need to do. Using the object initializer that @DiegoZanardo put into his response, you can already initialize any object.

Finally, in% w_of%, modify the following:

        <div>
            @Html.Label("País")
            @Html.DropDownList("pais", (SelectList)ViewData["paises"], "Selecione", new { id = "PaisID"})
        </div>
        <div>
            @Html.Label("EstadoID")
            @Html.DropDownListFor(model => model.EstadoID, Enumerable.Empty<SelectListItem>(), "Selecione")
        </div>

This will correlate the integer variable from View to Model .

    
08.08.2014 / 22:01
0

Assuming your Estado class is as follows:

public class Estado
{
    public int ID { get; set; }
    public String Nome { get; set; }
}

To use the constructor of class Cidade , you would have to do the following:

var estado = new Estado()
{
    ID = 1,
    Nome = "SP"
}
var cidade = new Cidade(1, "São Paulo", estado);
    
08.08.2014 / 19:22