Asp.net c# DDD - problem when passing data from Entity to Viewmodel

Asked

Viewed 665 times

0

I am developing an ASP.NET MVC project, with DDD structure and using Simple Injector. I can perform BD persistence normally, however, when retrieving information and displaying it in a list, it displays the following error message.

The template item inserted in the dictionary is from type'System.Collections.Generic.List1[Domain.Entities.SistemaEntities]', mas esse dicionário requer um item do tipo 'System.Collections.Generic.IEnumerable1[View.Models.Sistemaviewmodel]'.

This is the control that is calling the method to search the information:

public ActionResult Index()
        {
            var resultado = _SistemaDominio.GetAll().AsEnumerable();
            return View(resultado);                 
        }

And this is the page that presents the list.

@model IEnumerable<View.Models.SistemaViewModel>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Insert")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CodSistema)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Nome)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Descricao)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.DTCadastro)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Status)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CodSistema)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Nome)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Descricao)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.DTCadastro)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Status)
        </td>
        <td>
            @Html.ActionLink("Edit", "Update", new { id=item.IDSistema }) |
            @Html.ActionLink("Details", "Details", new { id=item.IDSistema }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.IDSistema })
        </td>
    </tr>
}

</table>

Domain.Service class.

public IList<SistemaEntities> GetAll()
{
    var resultado = _repositorioSistema.GetAll();
    return resultado;
}

Data.Repositories class

public IList<TEntities> GetAll()
{
     return _context.Set<TEntities>().ToList();
}

I am not in any way able to pass the data of the Entity to the Viewmodel.

  • _Systemsdomain.Getall() must be returning a List of Domain.Entities.SistemaEntities and in its View is being created from a View.Models.SistemaViewModel and the mistake is because the types are of different classes.

  • Yes, if I pass the data from the entity directly to Presentation, it works perfectly. However, I will have problems ahead with other methods that I intend to apply. I need the data to be passed from Entity to Viewmodel. And what I can’t do.

  • what’s inside _SistemaDominio.GetAll()? enter the code@

  • I updated with the code of _Systemsdomain.Getall(). It calls the class of the Domain layer that receives the data from the database coming from Date.

  • Look Douglas if you can give one Select there and give a new one ViewModel or you can use packages to move from one class to another such as Automapper. in my view it’s simple and you don’t need a package.

  • Virgilio, thank you so much for the help! It worked with the Automapper.

Show 1 more comment

1 answer

2


You need to map the model to viewModel. there are some libraries for this, among them the Automapper, which can be downloaded via Nuget.

After Download you add a class in App_start, as below:

public static class AutoMapperConfig
{
    public static void Configurar()
    {
        Mapper.Initialize(config =>
        {
            config.AddProfile(new ViewModelToDomainProfile());
            config.AddProfile(new DomainToViewModelProfile());
        });
    }
}

After this create the Domaintoviewmodelprofile and Viewmodeltodomainprofile classes, normally I create an "Automapper" folder in the MVC project and put these two classes inside. In it you will add the mappings, in the Viewmodeltodomainprofile class will be the mappings that will pass viewModel to a model(Insert and update) and in the other class, model to viewModel(selects)

public class DomainToViewModelProfile : Profile
{
    public DomainToViewModelProfile()
    {
        CreateMap<SistemaEntities, SistemaViewModel>();
    }
}

public class ViewModelToDomainProfile : Profile
{
    public ViewModelToDomainProfile()
    {
        CreateMap<SistemaViewModel, SistemaEntities>();
    }
}

After that, in Global.asax just call the configuration

protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        AutoMapperConfig.Configurar(); //Chamando configuração AutoMapper
    }

Finally, every time you switch from a model to a viewModel or a viewModel to a model you will need to call the mapping, which in your case would look like this:

public ActionResult Index()
    {
        List<SistemaEntities> resultado = _SistemaDominio.GetAll();
        List<SistemaViewModel> viewModels = Mapper.Map<List<SistemaViewModel>>(resultado);
        return View(viewModels);                 
    }

When creating the mappings (Createmap) they will serve both Collections and simple objects.

  • THANK YOU!!! I made it here and it worked with Automapper.

Browser other questions tagged

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