asp.net MVC Inheritance between Models

3

I'm trying to implement a person's registry where I have inheritances for both individuals and businesses, but my save method is not getting the person's type properly.

Following sample 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);
}

Clicking on save from individual or legal my method is receiving as always was the Person type, never the inheritance.

Persona.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")
}

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

_PessoaJuridica.cshtml

@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; }
    }
    
asked by anonymous 26.02.2016 / 15:16

1 answer

2

The modeling is correct, but I do not understand why ViewModels are treated as Models on your system.

If database generation was done correctly, there will be a Pessoas table with all combined fields of PessoaFisica and PessoaJuridica , plus a column named Discriminator , which indicates which type of entity, whether physical or legal.

In the case of Action Salvar , then you should use a ViewModel with all fields of the two classes, and mount the object corresponding to the type of person in Controller , and do not send the primitive object to the Controller and try to convert. The binding of the fields is done on top of the class placed as the argument of Action , and it does not understand inheritance. So you do not have the values at the time of converting the object.

    
27.02.2016 / 19:20