net mvc example ejemplo custom anexsoft c# asp.net-mvc-3 viewmodel automapper

c# - mvc - Cómo manejar las propiedades personalizadas en AutoMapper



automapper net core (2)

En automapper donde crea el Mapa, puede especificar procesos adicionales para miembros específicos del tipo de destino.

Entonces, ¿dónde estaría su mapa por defecto?

Mapper.Map<Domain.User, UsersDetailsViewModel>();

hay una sintaxis fluida para definir las asignaciones más complicadas:

Mapper.Map<Domain.User, UsersDetailsViewModel>() .ForMember(vm=>vm.UserName, m=>m.MapFrom(u=>(u.UserName != null) ? u.UserName : "User" + u.ID.ToString()));

Aquí, el ForMember toma dos argumentos: el primero define la propiedad a la que se asigna. El segundo proporciona un medio para definir el mapeo. Para un ejemplo, he copiado y mostrado una de las asignaciones fáciles.

Si necesita una asignación más difícil (como la asignación de CurrentUser), puede crear una clase que implemente la interfaz de IResolver, incorporar su lógica de asignación en esas nuevas clases y luego agregarla a la asignación.

Mapper.Map<Domain.User, UsersDetailsViewModel>() .ForMember(vm=>vm.IsUserMatch, m=>m.ResolveUsing<MatchingUserResolver>()));

Cuando Mapper llegue a hacer la asignación, invocará su resolución personalizada.

Una vez que descubra la sintaxis del método .ForMember, todos los demás tipos de ranuras están en su lugar.

Tengo un ViewModel que toma algunos datos del modelo y los altera ligeramente.

La forma en que lo hago "funciona", ya que acabo de pasar el DomainModel al constructor de ViewModel , pero como uso AutoMapper en algunos de mis ViewModels uno a uno, pensé que lo intentaría y aprendería. para hacer el mapeo en todos los ViewModels.

Aquí hay un ejemplo de un modelo de vista que hace un poco más.

public class UsersDetailsViewModel { public string UserName { get; set; } public string Email { get; set; } public string Website { get; set; } public int ID { get; set; } public List<OpenID> OpenIds { get; set; } public string UserAge { get; set; } public string About { get; set; } public string Slug { get; set; } public System.DateTime LastSeen { get; set; } public string Region { get; set; } public string MemberSince { get; set; } public string Reputation { get; set; } public bool IsUserMatch { get; set; } private readonly MarkdownDeep.Markdown _markdown; public UsersDetailsViewModel(Domain.User user) { AuthUserData currentuser = AuthenticationHelper.RetrieveAuthUser; _markdown.NoFollowLinks = true; _markdown.SafeMode = true; _markdown.ExtraMode = false; _markdown.MarkdownInHtml = true; // We want to ensure that the user has a username, even if they // haven''t set one yet. What this does is check to see if the // user.UserName field is blank, and if it is, it will set the // username to "UserNNNN" where NNNN is the user ID number. _UserName = (user.UserName != null) ? user.UserName : "User" + user.ID.ToString; // Nothing fancy going on here, we''re just re-passing the object from // the database to the View. No data manipulation! _Email = user.Email; _Website = user.WebSite; _ID = user.ID; // Get''s a list of all of the user''s OpenID''s _OpenIds = user.OpenIDs.ToList; // Converts the users birthdate to an age representation _UserAge = user.BirthDate.ToAge; //IE: 29 // Because some people can be real ass holes and try to submit bad // data (scripts and shitè) we have to modify the "About" content in // order to sanitize it. At the same time, we transform the Markdown // into valid HTML. The raw input is stored without sanitization in // the database. this could mean Javascript injection, etc, so the // output ALWAYS needs to be sanitized. // This method below was used in conjunction with MarkDownSharp // _About = Trim(Utilities.HtmlSanitizer.Sanitize(Markdown.Transform(user.About))) _About = _markdown.Transform(user.About); // Removes spaces from Usernames in order to properly display the // username in the address bar _Slug = Strings.Replace(user.UserName, " ", "-"); // Returns a boolean result if the current logged in user matches the // details view of tBhe user in question. This is done so that we can // show the edit button to logged in users. _IsUserMatch = (currentuser.ID == user.ID); // Grabs the users registration data and formats it to a <time> tag // for use with the timeago jQuery plugin _MemberSince = user.MemberSince; // Grabs the users last activity and formats it to a <time> tag // for use with the timeago jQuery plugin _LastSeen = user.ActivityLogs.Reverse.FirstOrDefault.ActivityDate; // Formats the users reputation to a comma Deliminated number // IE: 19,000 or 123k _Reputation = user.Reputation.ToShortHandNumber; // Get the name of the users Default Region. _Region = user.Region.Name.FirstOrDefault; } }

Y aquí es cómo utilizo actualmente el ViewModel anterior

public ActionResult Details(int id) { User user = _userService.GetUserByID(id); if (user != null) { Domain.ViewModels.UsersDetailsViewModel userviewmodel = new Domain.ViewModels.UsersDetailsViewModel(user); return View(userviewmodel); } else { // Because of RESTful URL''s, some people will want to "hunt around" // for other users by entering numbers into the address. We need to // gracefully redirect them to a not found page if the user doesn''t // exist. throw new ResourceNotFoundException(); } }

¿Cómo puedo usar (o debo usar) AutoMapper para asignar mi DomainModel a mi ViewModel mientras se realiza el procesamiento personalizado que se ve arriba?


La asignación personalizada se puede definir en global.ascx (en el inicio) mediante los siguientes códigos:

AutoMapper.Mapper.CreateMap<Domain.User, UsersDetailsViewModel>() .ForMember(o => o.Email, b => b.MapFrom(z => z.Email)) .ForMember(o => o.UserName , b => b.MapFrom(user => (user.UserName != null) ? user.UserName : "User" + user.ID.ToString));

Puedes hacer algo de inicialización a través del método BeforeMap (). Pero es posible que tengas que hacer algunos cambios en tu modelo de vista.