none
Dúvida AutoMapper RRS feed

  • Pergunta

  • Ola pessoal boa noite.

    Estou com uma dúvida de como fazer. Estou pesquisando na internet e vendo os exemplos não consegui fazer.

    É o seguinte eu tenho uma classe chamada Endereco:

    Endereco:

    public class Endereco 
        {
            public const int LogradouroMaxLength = 150;
            public virtual string Logradouro { get; private set; }
    
            public const int ComplementoMaxLength = 150;
            public virtual string Complemento { get; private set; }
    
            public const int NumeroMaxLength = 50;
            public virtual string Numero { get; private set; }
    
            public const int BairroMaxLength = 150;
            public virtual string Bairro { get; private set; }
    
            public const int CidadeMaxLength = 150;
            public virtual string Cidade { get; private set; }
    
            public virtual Uf? Uf { get; private set; }
    
            public virtual Cep Cep { get; private set; }
    
            protected Endereco() { }
    
            public Endereco(string logradouro, string complemento, string numero, string bairro,
                string cidade, Uf? uf, Cep cep)
            {
                SetCep(cep);
                SetBairro(bairro);
                SetCidade(cidade);
                SetComplemento(complemento);
                SetLogradouro(logradouro);
                SetNumero(numero);
                SetUf(uf);
            }
    
            public void SetCep(Cep cep)
            {
                if (cep.Vazio())
                    throw new Exception("CEP é obrigatório!");
                Cep = cep;
            }
    
            public void SetComplemento(string complemento)
            {
                if (string.IsNullOrEmpty(complemento))
                    complemento = "";
                Complemento = TextHelper.ToTitleCase(complemento);
            }
    
            public void SetLogradouro(string logradouro)
            {
                Validade.ForNullOrEmptyDefaultMessage(logradouro, "Endereço");
                Logradouro = TextHelper.ToTitleCase(logradouro);
            }
    
            public void SetNumero(string numero)
            {
                Validade.ForNullOrEmptyDefaultMessage(numero, "Número");
                Numero = numero;
            }
    
            public void SetBairro(string bairro)
            {
                Validade.ForNullOrEmptyDefaultMessage(bairro, "Bairro");
                Bairro = TextHelper.ToTitleCase(bairro);
            }
    
            public void SetCidade(string cidade)
            {
                Validade.ForNullOrEmptyDefaultMessage(cidade, "Cidade");
                Cidade = TextHelper.ToTitleCase(cidade);
            }
    
            public void SetUf(Uf? uf)
            {
                if (!uf.HasValue)
                    throw new Exception("Estado é obrigatório");
                Uf = uf;
            }
    
            public override string ToString()
            {
                return Logradouro + ", " + Numero + " - " + Complemento + " <br /> " + Bairro + " - " + Cidade + "/" + Uf;
            }
        }


    E uma classe chamada EnderecoViewModel

    EnderecoViewModel

    public class EnderecoViewModel
        {
    
            [Key]
            public int Id { get; set; }
    
            [DisplayName("Data Inclusão")]
            [ScaffoldColumn(false)]
            public DateTime? DataInclusao { get; set; }
    
            [DisplayName("Data Atualização")]
            [ScaffoldColumn(false)]
            public DateTime? DataAtualizacao { get; set; }
    
            [Required(ErrorMessage = "Preencha o Campo Logradouro")]
            [MaxLength(150, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Logradouro")]
            public  string Logradouro { get;  set; }
    
            [MaxLength(150, ErrorMessage = "Máximo {0} Caracteres")]
            public  string Complemento { get;  set; }
    
            [Required(ErrorMessage = "Preencha o Campo Número")]
            [MaxLength(50, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Número")]
            public string Numero { get;  set; }
    
            [Required(ErrorMessage = "Preencha o Campo Bairro")]
            [MaxLength(150, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Bairro")]
            public string Bairro { get;  set; }
    
    
            [Required(ErrorMessage = "Preencha o Campo Cidade")]
            [MaxLength(150, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Cidade")]
            public string Cidade { get;  set; }
    
            [Required(ErrorMessage = "Preencha o Campo UF")]
            [MaxLength(2, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Uf")]
            public string Uf { get;  set; }
    
    
            [Required(ErrorMessage = "Preencha o Campo Cep")]
            [MaxLength(9, ErrorMessage = "Máximo {0} Caracteres")]
            [DisplayName("Cep")]
            public string Cep { get;  set; }
    
            public bool Ativo { get; set; }
            
        }

    o problema esta na hora de mapear de uma para outro os objetos Cep e Uf.  Cep é uma classe e o Uf é um enum.

    Segue o mapeamento:

    CreateMap<Endereco, EnderecoViewModel>().ReverseMap().ForMember(dest => dest.Cep.CepCod, opt => opt.MapFrom(x => x.Cep));
                CreateMap<Endereco, EnderecoViewModel>().ReverseMap().ForMember(dest => dest.Uf, opt => opt.MapFrom(x => x.Uf));

    Porem quando eu rodo da o seguinte erro: 

    Expression 'dest => dest.Cep.CepCod' must resolve to top-level member and not any child object's properties. Use a custom resolver on the child type or the AfterMap option instead.
    Nome do parâmetro: lambdaExpression

    Alguém poderia me ajudar por favor?

    Obrigado


    Adilson

    terça-feira, 19 de julho de 2016 21:15

Todas as Respostas

  • Olá Adilson,

    Olhe esse artigo do Eduardo Pires: http://eduardopires.net.br/2013/08/asp-net-mvc-utilizando-automapper-com-view-model-pattern/

    Valeu!

    quarta-feira, 20 de julho de 2016 03:59
  • Oi eu vi esse artigo, porém não me ajudou eu agradeço. eu estava continuando a pesquisar e achei um outro jeito de fazer segue:

    CreateMap<EnderecoViewModel, Endereco>().ConstructUsing(enderecoViewModel => 
                    new Endereco(enderecoViewModel.Logradouro,
                        enderecoViewModel.Numero,
                        enderecoViewModel.Numero,
                        enderecoViewModel.Bairro,
                        enderecoViewModel.Cidade,
                        (Uf)Enum.Parse(typeof(Uf), enderecoViewModel.Uf)
                        , new Cep(enderecoViewModel.CepCod))
                 );

    Só que na hora de cadastrar da o seguinte erro:

    O tipo fornecido deve ser um Enum.
    Nome do parâmetro: enumType
    
    Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código. 
    
    Detalhes da Exceção: System.ArgumentException: O tipo fornecido deve ser um Enum.
    Nome do parâmetro: enumType

    Alguém poderia me ajudar com esse erro.  Segue a controle de cadatar onde esta gerando o erro

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create(EnderecoViewModel endereco)
            {
    
                if (ModelState.IsValid)
                {           
                    var enderecoDomain = Mapper.Map<EnderecoViewModel, Endereco>(endereco);
                    _enderecoAppService.Add(enderecoDomain);
                    return RedirectToAction("Index");
                }
                return View(endereco);
            }


    Adilson



    • Editado Adilson_ASP quarta-feira, 20 de julho de 2016 20:19
    quarta-feira, 20 de julho de 2016 19:56
  • Eu consegui fazer. Tirei o enum da minha classe Endereco e coloquei o tipo como string ai funcionou.

    Adilson

    quinta-feira, 21 de julho de 2016 14:16