AutoMapper在MVC中的運用05-對映中的忽略、處理null、多種對映轉換

Darren Ji發表於2014-02-26

本篇AutoMapper使用場景:

※ 動態實現介面方法或屬性

※ 目標中的屬性如果比源多,可以忽略多出的屬性

※ 目標有virtual屬性,可忽略

※ 目標屬性值為null的解決辦法

※ int轉string

※ bool轉string

※ DateTime轉String

※ 判斷條件


  動態實現介面方法或屬性


    public interface ICreateOrderMessage

    {

        string CustomerName { get; set; } 

    }


□ 使用


        public ActionResult Dynamic()

        {

            var order = new {CustomerName = "darren"};

            var message = Mapper.DynamicMap<ICreateOrderMessage>(order);

            //message中會有CustomerName屬性和值

            return View(message);

        }    

□ 要點


傳入的實現類或匿名類,動態實現介面方法或屬性。


  目標中的屬性如果比源多,可以忽略多出的屬性


□ View model


    public class Order3Dto

    {

        public decimal Amount { get; set; }

    }



□ Domain model


    public class Order3

    {

        public int Id { get; set; }

        public decimal Amount { get; set; }

    }


□ 對映配置


Mapper.CreateMap<Order3Dto, Order3>()

                .ForMember("Id", opt => opt.Ignore());


□ 使用


        public ActionResult To()

        {

            var orderDto = new Order3Dto() {Amount = 50m};


            //源沒有的屬性,預先賦值

            var order = new Order3() {Id = 4};

            Mapper.Map(orderDto, order);

            return View(order);

        }


□ 要點


如果目標的屬性多於源中的屬性,並且不賦值,會報錯。


  目標有virtual屬性,可忽略


□ View model


    public class UserInfoViewModel

    {

        public int ID { get; set; }

        public string LoginName { get; set; } 

    }


□ Domain model


    public class UserInfo

    {

        public UserInfo()

        {

            this.R_UserInfoActionInfo = new HashSet<R_UserInfoActionInfo>();

        }

        public int ID { get; set; }

        public string LoginName { get; set; }

        public DateTime SubTime { get; set; } //目標中多出的屬性

        public virtual ICollection<R_UserInfoActionInfo> R_UserInfoActionInfo { get; set; } //目標中多出的屬性,且是virtual

    }


    public class R_UserInfoActionInfo

    {

        public string Name { get; set; }

    }  


□ 對映配置


Mapper.CreateMap<UserInfoViewModel, UserInfo>()

                .ForMember("SubTime", opt => opt.Ignore())

                .ForMember("R_UserInfoActionInfo", opt => opt.Ignore());


□ 使用


        public ActionResult Concern()

        {

            UserInfoViewModel vmodel = new UserInfoViewModel()

            {

                LoginName = "Darren"

            };


            UserInfo dmodel = Mapper.Map<UserInfoViewModel, UserInfo>(vmodel);

            dmodel.SubTime = DateTime.Now; //多出的屬性雖然在對映配置中忽略了,但還是可以賦值

            return View(dmodel);

        }       


  目標屬性值為null的解決辦法


.ForMember(dto => dto.AuthorBio, opt => opt.NullSubstitute("Not set yet."))


  int轉string


.ForMember(dto => dto.NumberOfPosts, opt => {

                opt.AddFormatter<NumberOfPostsFormatter>();

            })


public class NumberOfPostsFormatter : IValueFormatter

    {

        public string FormatValue(ResolutionContext context)

        {

            int value = (int)context.SourceValue;

            if(value = 1)   

                return "Number of Posts: One post";

            return "Number of posts:" + value;

        }

    }    


  bool轉string


.ForMember(dto => dto.VIP, m => m.ResolveUsing<VIPResolver>().FromMember(x => x.VIP))


public class VIPResolver : ValueResolver<bool, string>

    {

        protected override string ResolveCore(bool source)

        {

            return source ? "Y" : "N";

        }

    }


  DateTime轉String


.ForMember(dto => dto.DateOfBirth, m => m.AddFormatter<DateFormatter>());


public class DateFormatter : IValueFormatter

    {

        public string FormatValue(ResolutionContext context)

        {

            return ((DateTime)context.SourceValue).ToLongDateString();

        }

    }    


  判斷條件


Mapper.CreateMap<AutoMapperInMvc01.Portal.Models.Foo, AutoMapperInMvc01.Portal.Models.Bar>()

            .ForMember("baz", opt => opt.Condition(context => context.SourceValue.ToString() == "0"));    

  

相關文章