Asp.net MVC Models Heritage

Asked

Viewed 1,173 times

3

I am trying to implement a person register where I have the inheritances for legal and physical person, but my saving method is not getting the type of person properly.

follows example code

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Salvar(PessoaViewModel model)
{
    if (ModelState.IsValid)
    {
        if (model is PessoaFisicaViewModel)
            await SalvarPessoaFisica(context, model as PessoaFisicaViewModel);
        else if (model is PessoaJuridicaViewModel)
            await SalvarPessoaJuridica(context, model as PessoaJuridicaViewModel);
        else await SalvarPessoa(context, model);

        await context.SaveChangesAsync();

        return RedirectToAction("Index");
    }

    return View(model);
}

by clicking on the save of natural or legal person my method is receiving as always the type Person, never the inheritance.

Pessoa.cshtml

@model PessoaViewModel

<div class="row">
    <div class="col-lg-12">
        <div class="panel panel-default">
            <div class="panel-heading">
                @if (Model.PessoaId > 0)
                {
                    <label>Edição da pessoa - @Model.Nome</label>
                }
                else
                {
                    <label>Cadastro de pessoa</label>
                }
            </div>
            <div class="panel-body">
                @using (Html.BeginForm("Salvar", "Pessoa"))
                {
                    @Html.AntiForgeryToken()

                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

                    if (Model is PessoaFisicaViewModel)
                    {
                        @Html.Partial("_PessoaFisica", Model)
                    }
                    else if (Model is PessoaJuridicaViewModel)
                    {
                        @Html.Partial("_PessoaJuridica", Model)
                    }
                    else
                    {
                        @Html.Partial("_Pessoa", Model)
                    }

                    <div class="row">
                        <div class="col-lg-12">
                            <a href="@Url.Action("Index")" class="btn btn-default"><i class="fa fa-arrow-left fa-fw"></i> Voltar</a>
                            <button type="submit" class="btn btn-primary"><i class="fa fa-save fa-fw"></i> Salvar</button>
                        </div>
                    </div>
                }
            </div>
        </div>
    </div>
</div>

@section scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/ajax")
}

_Personal.cshtml

@model PessoaFisicaViewModel

@Html.HiddenFor(a => a.PessoaId)
@Html.HiddenFor(a => a.Ativo)

<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => model.CpfCnpj, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.CpfCnpj, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => model.CpfCnpj, "", new { @class = "text-danger" })
    </div>
</div>
<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
    </div>
</div>

<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => model.RgNumero, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.RgNumero, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => model.RgNumero, "", new { @class = "text-danger" })
    </div>
</div>

_Personal.cshtml legal.

@model PessoaViewModel

@Html.HiddenFor(a => a.PessoaId)
@Html.HiddenFor(a => a.Ativo)

<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => model.CpfCnpj, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.CpfCnpj, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => model.CpfCnpj, "", new { @class = "text-danger" })
    </div>
</div>
<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
    </div>
    <div class="row form-group">
        <div class="col-lg-4">
            @Html.LabelFor(model => (model as PessoaJuridicaViewModel).NomeFantasia, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(model => (model as PessoaJuridicaViewModel).NomeFantasia, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
            @Html.ValidationMessageFor(model => (model as PessoaJuridicaViewModel).NomeFantasia, "", new { @class = "text-danger" })
        </div>
    </div>
</div>
<div class="row form-group">
    <div class="col-lg-4">
        @Html.LabelFor(model => (model as PessoaJuridicaViewModel).InscricaoMunicipal, htmlAttributes: new { @class = "control-label" })
        @Html.EditorFor(model => (model as PessoaJuridicaViewModel).InscricaoMunicipal, new { htmlAttributes = new { @class = "form-control", @autofocus = "" } })
        @Html.ValidationMessageFor(model => (model as PessoaJuridicaViewModel).InscricaoMunicipal, "", new { @class = "text-danger" })
    </div>
</div>

Models

public interface IPessoa
    {
        bool Ativo { get; set; }
        string CpfCnpj { get; set; }
        string Nome { get; set; }
        int PessoaId { get; set; }
    }
    public class PessoaViewModel : IPessoa
    {
        public bool Ativo { get; set; }
        public string CpfCnpj { get; set; }
        public string Nome { get; set; }

        public int PessoaId { get; set; }

    }

    public interface IPessoaFisica : IPessoa
    {
        int? RgNumero { get; set; }
    }

    public class PessoaFisicaViewModel : PessoaViewModel, IPessoaFisica
    {
        public int? RgNumero { get; set; }
    }

    public interface IPessoaJuridica : IPessoa
    {
        string InscricaoMunicipal { get; set; }

        string NomeFantasia { get; set; }
    }

    public class PessoaJuridicaViewModel : PessoaViewModel, IPessoaJuridica
    {
        public string InscricaoMunicipal { get; set; }

        public string NomeFantasia { get; set; }
    }

1 answer

2


The modeling is correct, but I don’t understand why Viewmodels are treated as Models in your system.

If database generation was done correctly, there will be a table Pessoas with all fields combined from PessoaFisica and PessoaJuridica, another column called Discriminator, indicating the type of the entity, whether physical or legal.

Already in the case of Action Salvar, then you should use a Viewmodel with all fields of both classes, and assemble the object corresponding to the person’s type in Controller, and not send the primitive object to the Controller and try to convert. The Binding fields is done on top of the class placed as argument of Action, and it does not understand inheritance. So you do not have the values when converting the object.

  • is that I make each entity a table, so I have the tables Person, Personal and Personal.

  • 2

    Besides not justifying it, you’re wrong. A Natural Person cannot also be a Legal Person at the same time, which makes inheritance the most recommended. Viewmodels are not Models. They cannot be objects of databases. They are models of data used to collect and process data, and so there is this separation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.