AutoMapper Configuration Exception - asp.net-mvc

I have a model class
public class Brochure
{
[Key]
public int BrochureId { get; set; }
public string Name { get; set; }
public string TypeOfCover { get; set; }
public int NumberOfPages { get; set; }
public LibraryType Type { get; set; }
}
and View model
public class BrochureView
{
public int BrochureId { get; set; }
public string Name { get; set; }
public string TypeOfCover { get; set; }
public int NumberOfPages { get; set; }
}
in Brochure service I'm mapping model and viewmodel
public class BrochureService
{
private BrochureRepository _brochureRepository;
public BrochureService(DbContextOptions<LibraryContext> options)
{
_brochureRepository = new BrochureRepository(options);
}
public void Create(BrochureView brochureView)
{
var brochure = Mapper.Map<BrochureView, Brochure>(brochureView);
brochure.Type = LibraryType.Brochures;
_brochureRepository.Create(brochure);
}
}
Here is my automapper profiler:
public static class AutoMapperProfile
{
public static void RegisterMappings()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Brochure, BrochureView>();
cfg.CreateMap<BrochureView, Brochure>()
.ForMember(src => src.Type, opt => opt.Ignore());
});
}
}
but i have an exception:
Unmapped members were found.
AutoMapper cant map "Type" property. How can I resolve this problem?
To answer question from comments, that's the whole MappingProfile
public static class AutoMapperProfile
{
public static void RegisterMappings()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Book, BookView>();
cfg.CreateMap<BookView, Book>();
cfg.CreateMap<Magazine, MagazineView>();
cfg.CreateMap<MagazineView, Magazine>();
cfg.CreateMap<Brochure, BrochureView>();
cfg.CreateMap<BrochureView, Brochure>()
.ForMember(src => src.Type, opt => opt.Ignore());
cfg.CreateMap<PublicHouse, PublicHouseView>();
cfg.CreateMap<PublicHouseView, PublicHouse>();
cfg.CreateMap<Book, LibraryView>()
.ForMember(dest => dest.Name, opt => opt.ResolveUsing(src => src.Name))
.ForMember(dest => dest.Type, opt => opt.ResolveUsing(src => (LibraryType)src.Type));
cfg.CreateMap<Brochure, LibraryView>()
.ForMember(dest => dest.Name, opt => opt.ResolveUsing(src => src.Name))
.ForMember(dest => dest.Type, opt => opt.ResolveUsing(src => (LibraryType)src.Type));
cfg.CreateMap<Magazine, LibraryView>()
.ForMember(dest => dest.Name, opt => opt.ResolveUsing(src => src.Name))
.ForMember(dest => dest.Type, opt => opt.ResolveUsing(src => (LibraryType)src.Type));
});
}
}

Related

Fluent NHibernate Mapping Doesn't Work For Some Tables

I'm using Fluent Migrator and Fluent NHibernate in the same project but when I launch queries using Database.Session.Query<ENTITY>().** some return data and some don't. I can't tell where I'm doing wrong.
Database Query That Returns Users:
var users = Database.Session.Query<Models.User>()
.Where(u => u.Id == id)
.ToList();
Database Query That Doesn't Return Users:
var ourStocks = Database.Session.Query<Models.Stock>()
.Where(stock => stock.Belongstouser == id)
.OrderByDescending(stc => stc.StockId)
.ToList();
Models.User:
public class User
{
public virtual int Id { get; set; }
public virtual string Username { get; set; }
public virtual string Email { get; set; }
public virtual string adSoyad { get; set; }
public virtual string addressMah { get; set; }
public virtual string addRessCadSk { get; set; }
public virtual string addressIl { get; set; }
public virtual string addressIlce { get; set; }
public virtual int Balance { get; set; }
public virtual string PasswordHash { get; set; }
public virtual IList<Roles> Roles { get; set; }
public User()
{
Roles = new List<Roles>();
}
public virtual void SetPassword(string password)
{
PasswordHash = BCrypt.Net.BCrypt.HashPassword(password, 13);
}
public virtual bool CheckPassword(string password)
{
var pass = BCrypt.Net.BCrypt.Verify(password, PasswordHash);
return BCrypt.Net.BCrypt.Verify(password, PasswordHash);
}
}
public class UsersMap : ClassMapping<User>
{
public UsersMap()
{
Table("users");
Schema("projefinalodevi");
Id(x => x.Id, map => map.Generator(Generators.Identity));
Property(x => x.Username, map => map.NotNullable(true));
Property(x => x.Email, map => map.NotNullable(true));
Property(x => x.adSoyad, map => map.NotNullable(true));
Property(x => x.addressMah, map => map.NotNullable(true));
Property(x => x.addRessCadSk, map => map.NotNullable(true));
Property(x => x.addressIl, map => map.NotNullable(true));
Property(x => x.addressIlce, map => map.NotNullable(true));
Property(x => x.Balance, map => map.NotNullable(true));
Property(x => x.PasswordHash, map => { map.Column("password_hash"); map.NotNullable(true); });
Bag(x => x.Roles, x => {
x.Table("role_users");
x.Key(k => k.Column("userid"));
}, x => x.ManyToMany(k => k.Column("roleid")));
}
}
Models.Stock:
public class Stock
{
public virtual int StockId { get; set; }
public virtual int Description { get; set; }
public virtual string Unitprice { get; set; }
public virtual int Belongstouser { get; set; }
public virtual int Quantityinstock { get; set; }
}
public class StockMap : ClassMapping<Stock>
{
public StockMap()
{
Table("stock");
Schema("projefinalodevi");
Lazy(true);
Id(x => x.StockId, map => { map.Column("stock_id"); map.Generator(Generators.Identity); });
Property(x => x.Description, map => map.NotNullable(true));
Property(x => x.Unitprice, map => map.NotNullable(true));
Property(x => x.Belongstouser, map => map.NotNullable(true));
Property(x => x.Quantityinstock, map => { map.Column("quantityInStock"); map.NotNullable(true); });
}
}
And lastly, my Migration:
public override void Down()
{
Execute.Sql("DELETE FROM projeFinalOdevi.roles where name = 'user'");
Execute.Sql("DELETE FROM projeFinalOdevi.roles where name = 'admin'");
Delete.Table("role_users");
Delete.Table("roles");
Delete.Table("sales");
Delete.Table("stock");
Delete.Table("users");
}
public override void Up()
{
Create.Table("users")
.WithColumn("id").AsInt32().Identity().PrimaryKey()
.WithColumn("userName").AsString(50).NotNullable()
.WithColumn("eMail").AsString(50).NotNullable()
.WithColumn("balance").AsInt32().NotNullable()
.WithColumn("adSoyad").AsString(128).NotNullable()
.WithColumn("addressMah").AsString(40).NotNullable()
.WithColumn("addressCadSk").AsString(128).NotNullable()
.WithColumn("addressil").AsString(128).NotNullable()
.WithColumn("addressilce").AsString(128).NotNullable()
.WithColumn("password_hash").AsString(256).NotNullable();
Create.Table("stock")
.WithColumn("stock_id").AsInt32().Identity().PrimaryKey()
.WithColumn("description").AsString(256).NotNullable()
.WithColumn("unitPrice").AsInt32().NotNullable()
.WithColumn("belongsToUser").AsInt32().NotNullable()
.WithColumn("quantityInStock").AsInt32().NotNullable();
Create.Table("sales")
.WithColumn("sales_id").AsInt32().Identity().PrimaryKey()
.WithColumn("stock_id").AsInt32().ForeignKey("stock", "stock_id").OnDelete(System.Data.Rule.Cascade).NotNullable()
.WithColumn("date").AsDate().NotNullable()
.WithColumn("quantity").AsInt32().NotNullable()
.WithColumn("sale_sum").AsInt32().NotNullable();
Create.Table("roles")
.WithColumn("id").AsInt32().Identity().PrimaryKey()
.WithColumn("name").AsString(128);
Create.Table("role_users")
.WithColumn("userid").AsInt32().ForeignKey("users", "id").OnDelete(System.Data.Rule.Cascade)
.WithColumn("roleid").AsInt32().ForeignKey("roles", "id").OnDelete(System.Data.Rule.Cascade);
Execute.Sql("INSERT INTO projeFinalOdevi.roles (name) VALUES ('admin')");
Execute.Sql("INSERT INTO projeFinalOdevi.roles (name) VALUES ('user')");
/* CMD line;
migrate -a D:\ProjeFinalOdevi\ProjeFinalOdevi\bin\ProjeFinalOdevi.dll -db MySql -conn "Data Source=127.0.0.1;Database=projefinalodevi;uid=root;pwd=MySQLPassis8420;"
*//* CMD line;
migrate -a C:\Users\Atabay\source\repos\ProjeFinalOdevi\ProjeFinalOdevi\bin\ProjeFinalOdevi.dll -db MySql -conn "Data Source=127.0.0.1;Database=ProjeFinalOdevinew;uid=root;pwd=root;"
*/
}
Help is appreciated, thanks :).
Turns out I was not registering the stock.

How to implement mapping via automapper in ASP.NET MVC

I have two class. PRODUCT comes from Entity Framework, and Product in Domain solution: Here are the details:
PRODUCT class (source):
namespace SportsStore.Domain
{
using System;
using System.Collections.Generic;
public partial class PRODUCT
{
public int PRODUCT_ID { get; set; }
public string PRODUCT_NAME { get; set; }
public string PRODUCT_DESCRIPTION { get; set; }
public decimal PRODUCT_PRICE { get; set; }
public string PRODUCT_CATEGORY { get; set; }
}
}
Product class (destination):
namespace SportsStore.Domain.Entities
{
public class Product
{
[HiddenInput(DisplayValue = false)]
public int ProductId {get;set;}
public string ProductName {get;set;}
[DataType(DataType.MultilineText)]
public string ProductDescription {get;set;}
public decimal ProductPrice {get;set;}
public string ProductCategory { get; set; }
}
}
Here is the ProductViewModel that used throughout the project:
public class ProductsListViewModel
{
public IEnumerable<Product> Products { get; set; }
public PagingInfo _pagingInfo { get; set; }
public PagingInfo PagingInfo { get; set; }
public string CurrentCategory { get; set; }
}
Here is my mapping in the project, I have a automapper to map these two.
public static class AutoMapperConfig
{
public static void RegisterMappings()
{
AutoMapper.Mapper.CreateMap<PRODUCT, Product>();
AutoMapper.Mapper.CreateMap<PRODUCT, Product>()
.ForMember(dest => dest.ProductCategory,
opts => opts.MapFrom(src => src.PRODUCT_CATEGORY));
AutoMapper.Mapper.CreateMap<PRODUCT, Product>()
.ForMember(dest => dest.ProductDescription,
opts => opts.MapFrom(src => src.PRODUCT_DESCRIPTION));
AutoMapper.Mapper.CreateMap<PRODUCT, Product>()
.ForMember(dest => dest.ProductId,
opts => opts.MapFrom(src => src.PRODUCT_ID));
AutoMapper.Mapper.CreateMap<PRODUCT, Product>()
.ForMember(dest => dest.ProductName,
opts => opts.MapFrom(src => src.PRODUCT_NAME));
AutoMapper.Mapper.CreateMap<PRODUCT, Product>()
.ForMember(dest => dest.ProductPrice,
opts => opts.MapFrom(src => src.PRODUCT_PRICE));
}
}
I call RegisterMappings in the Global.asax.cs's Application_Start.
protected void Application_Start()
{
AutoMapperConfig.RegisterMappings();
}
Under these circumstances, I read the contents from Entity framework, their type is PRODUCT, when I try to assign it to Product, I got error. The point that I get error is here:
public ActionResult List(string category,int page = 1)
{
List<PRODUCT> pr = null;
using(ProductContext pb = new ProductContext())
{
ProductsListViewModel model = new ProductsListViewModel
{
//Error is here
Products = pb.ProductsList.Where(p => category == null || p.PRODUCT_CATEGORY == category).OrderBy(i => i.PRODUCT_ID).Skip((page - 1) * PageSize).ToList().Take(PageSize).ToList(),
_pagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = category == null ? pb.ProductsList.Count() : pb.ProductsList.Where(e => e.PRODUCT_CATEGORY == category).Count()
},
CurrentCategory = category
};
return View(model);
}
}
The error is this:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)
How can I overcome this? Thanks in advance.
The error says everything you need to know. In somewhere you are trying to put a List of objects to a IEnumerable of the same objects.
It seems to me that you shoud alter the line
Products = pb.ProductsList.Where(p => category == null || p.PRODUCT_CATEGORY == category)
.OrderBy(i => i.PRODUCT_ID)
.Skip((page - 1) * PageSize)
.ToList().Take(PageSize).ToList()
into
Products = pb.ProductsList.Where(p => category == null || p.PRODUCT_CATEGORY == category)
.OrderBy(i => i.PRODUCT_ID)
.Skip((page - 1) * PageSize)
.Take(PageSize).AsEnumerable()

Automapper complex mapping

How can I map the following:
public abstract class PersonBase
{
public Address Address { get; set; }
}
public class Address
{
public string AddressHome { get; set; }
public int PostalNumber { get; set; }
}
public class PersonEditVM : PersonBase
{
public int PersonId { get; set; }
}
public PersonEntity
{
public int PersonId { get; set; }
public string AddressHome { get; set; }
public int PostalNumber { get; set; }
}
I would like to map PersonEntity to PersonEditVM.
EDIT: Solved after a cup of coffee but it would be nice if it's a cleaner solution?.
Mapper.CreateMap<PersonEntity, PersonEditVM >()
.ForMember(d=>d.Address, s=>s.MapFrom(p=> new Address{
AddressHome = p.AddressHome,
PostalNumber = p.PostalNumber
}));
Here's one way to do it, which would split your Adress (which is correctly spelled Address by the way) mapping into another CreateMap call:
Mapper.CreateMap<PersonEntity, PersonEditVM>()
.ForMember(dest => dest.Adress, opt => opt.MapFrom(src => src));
Mapper.CreateMap<PersonEntity, Adress>()
.ForMember(dest => dest.AdressHome, opt => opt.MapFrom(src => src.AdressHome))
.ForMember(dest => dest.PostalNumber, opt => opt.MapFrom(src => src.PostalNumber));

Mapping one (entity class) to many (dto's/viewModels)

I am trying to map information about the User to several dto's, but I'm getting null exceptions. Basically, the reason why I distributed the information among several classes is because there are common info that I need in several views. So this is what I ended up with:
User entity class
public class User
{
public int Id { get; set; }
public string Nickname { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public float Credits { get; set; }
public float PromotionalCredits { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public double RatingAverage { get; set; }
public string ProfileImage { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Item> Items { get; set; }
public virtual ICollection<Bid> Bids { get; set; }
public virtual ICollection<CreditCard> CreditCard { get; set; }
public virtual ICollection<Message> ReceivedMessages { get; set; }
public virtual ICollection<Message> SentMessages { get; set; }
public virtual ICollection<Item> WatchList { get; set; }
public virtual ICollection<Rating> OwnRatings { get; set; }
public virtual ICollection<Rating> RatingsForOthers { get; set; }
}
DTO's and ViewModel calsses
public class UserInfoSummaryViewModel
{
public int Id { get; set; }
public string FullName { get; set; }
public UserDetailedStatus DetailedStatus { get; set; }
}
public class UserDetailedStatus
{
public float TotalCredits { get; set; }
public float Credits { get; set; }
public float PromotionalCredits { get; set; }
public BiddingAndItems BiddingAndItems { get; set; }
public int OngoingListings { get; set; }
public int NewMessages { get; set; }
public float Rating { get; set; }
public int NumberOfRatings { get; set; }
}
public class BiddingAndItems
{
public int TotalBids { get; set; }
public int WinningBids { get; set; }
public int AcquiredItems { get; set; }
public int ItemsAwaitingConfirmation { get; set; }
public List<ItemForUserBids> Items { get; set; }
}
Mappings inside AutoMapperBootStrapper class
Mapper.CreateMap<User, BiddingAndItems>()
.ForMember(m => m.TotalBids, o => o.MapFrom(s => s.TotalActiveBids()))
.ForMember(m=>m.ItemsAwaitingConfirmation, o=>o.MapFrom(s=>s.Items.Count(i=>i.IsAwaitingReceptionConfirmation().Equals(true))))
.ForMember(m=>m.AcquiredItems, o=>o.MapFrom(s=>s.AquiredItems().Count))
.ForMember(m => m.WinningBids,
o => o.MapFrom(s => s.Bids.Where(c => c.Item.CurrentHighestBidderId().Equals(s.Id))));
Mapper.CreateMap<User, UserDetailedStatus>()
.ForMember(m => m.NumberOfRatings, o => o.MapFrom(s => s.OwnRatings.Count()))
.ForMember(m => m.NewMessages, o => o.MapFrom(s => s.TotalUnreadMessages()))
.ForMember(m => m.OngoingListings, o => o.MapFrom(s => s.Items.Where(i => i.IsPublished())))
.ForMember(m => m.Rating, o => o.MapFrom(s => s.RatingAverage))
.ForMember(m => m.TotalCredits, o => o.MapFrom(s => s.TotalCredits()));
Mapper.CreateMap<User, UserInfoSummaryViewModel>();
Call to automapper inside UserController
public ActionResult Summary()
{
var user = _helper.GetUserFromSession();
var viewModel = Mapper.Map<User, UserInfoSummaryViewModel>(user);
return View(viewModel);
}
I thought because I have all the necessary mappings inside the bootstrapper this should, theoretically work, apparently I was wrong... How can I fix that?
UPDATE:
I got my mappings fixed and added a couple of value resolvers. Now I'm not getting a null reference exception but there seems to be something wrong because everytime I run the project it gets stuck and then the local server stops responding... Here's my code:
Mapper.CreateMap<User, BiddingAndItems>()
.ForMember(m => m.TotalBids, o => o.MapFrom(s => s.TotalActiveBids()))
.ForMember(m => m.ItemsAwaitingConfirmation,
o => o.MapFrom(s => s.Items.Count(i => i.IsAwaitingReceptionConfirmation().Equals(true))))
.ForMember(m => m.AcquiredItems, o => o.MapFrom(s => s.AquiredItems().Count))
.ForMember(m => m.WinningBids, o => o.ResolveUsing<WinningBidsResolver>())
.ForMember(m => m.Items, o => o.ResolveUsing<BiddingItemResolver>());
Mapper.CreateMap<User, UserDetailedStatus>()
.ForMember(m => m.NumberOfRatings, o => o.MapFrom(s => s.OwnRatings.Count()))
.ForMember(m => m.NewMessages, o => o.MapFrom(s => s.TotalUnreadMessages()))
.ForMember(m => m.OngoingListings, o => o.MapFrom(s => s.Items.Where(i => i.IsPublished()).Count()))
.ForMember(m => m.Rating, o => o.MapFrom(s => s.RatingAverage))
.ForMember(m=>m.BiddingAndItems, o => o.MapFrom(s=> s))
.ForMember(m => m.TotalCredits, o => o.MapFrom(s => s.TotalCredits()));
Mapper.CreateMap<User, UserInfoSummaryViewModel>()
.ForMember(m => m.DetailedStatus, o => o.MapFrom(s => s));
public class BiddingItemResolver : ValueResolver<User, List<ItemForUserBids>>
{
protected override List<ItemForUserBids> ResolveCore(User source)
{
var items = new List<ItemForUserBids>();
foreach (var bid in source.Bids)
{
var item = bid.Item;
var c = new ItemForUserBids
{
BidValue = bid.Amount,
Description = item.Description,
Id = item.Id,
ItemThumb = item.MainImageLink(),
Status = source.ItemBiddingStatus(item.Id),
TimeLeft = TimeUtility.TimeLeft(item.EndDate),
Title = item.Title
};
items.Add(c);
}
return items;
}
}
public class WinningBidsResolver : ValueResolver<User, int>
{
protected override int ResolveCore(User source)
{
return source.Bids.Where(c => c.Item.CurrentHighestBidderId().Equals(source.Id)).Count();
}
}
The problem is that I'm not getting any exceptions to give me any hints about what's going wrong... It just gets stuck! I suspect that my mappings are going into some sort of an infinite loops or something, but I am not sure what is happening exactly... Is there any way I could debug this problem?
Any help would be appreciated...
Without more information about the exception you receive I can only guess what could go wrong: I guess it's because you're using Linq on uninitialized collections in MapFrom. Try implementing a ValueResolver instead.

NCommon 1.1 and EF4

I am new to NCommon and am looking for an example project to get started.
I am using EF4.
I assume one needs to use EF4 with POCOs?
Thanks for any help.
NCommon.Configure.Using(new StructureMapContainerAdapter(ObjectFactory.Container))
.ConfigureState<DefaultStateConfiguration>()
.ConfigureData<EFConfiguration>(config => config.WithObjectContext(
() =>
{
SiteContext db = new SiteContext(ConfigurationManager.ConnectionStrings["TestTheBest"].ConnectionString);
if (Transaction.Current != null )
{
db.Context.Connection.Open();
}
return db.Context;
}))
.ConfigureUnitOfWork<DefaultUnitOfWorkConfiguration>(config => config.AutoCompleteScope());
public class SiteContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Test> Tests { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Section> Sections { get; set; }
public DbSet<Answer> Answers { get; set; }
public DbSet<GlobalSettings> GlobalSettings { get; set; }
public DbSet<PassageTest> PassageTest { get; set; }
public DbSet<PassageTestAnswer> PassageTestAnswer { get; set; }
public DbSet<SaaSUser> SaaSUser { get; set; }
public SiteContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
Context.SavingChanges += new EventHandler(Context_SavingChanges);
}
void Context_SavingChanges(object sender, EventArgs e)
{
if(Context.Connection.State==ConnectionState.Open)
Context.Connection.Close();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasMany(x => x.Invitations).WithRequired(x=>x.user).WillCascadeOnDelete(true);
modelBuilder.Entity<User>().HasMany(x => x.PassageTests).WithRequired(x => x.user).WillCascadeOnDelete(true);
modelBuilder.Entity<PassageTest>().HasMany(x => x.PassageTestAnswers).WithRequired(x => x.passageTest).WillCascadeOnDelete(true);
// modelBuilder.Entity<Company>().HasMany(x => x.Users).WithRequired(x => x.company).WillCascadeOnDelete(true);
modelBuilder.Entity<Question>().HasMany(x => x.Answers).WithRequired(x => x.question).WillCascadeOnDelete(true);
modelBuilder.Entity<Question>().HasMany(x => x.PassageTestAnswers).WithRequired(x => x.question).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.Invitations).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.PassageTests).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Test>().HasMany(x => x.Sections).WithRequired(x => x.test).WillCascadeOnDelete(true);
modelBuilder.Entity<Client>().HasMany(x => x.Tests).WithRequired(x => x.client).WillCascadeOnDelete(true);
}
public ObjectContext Context
{
get { return ((IObjectContextAdapter)this).ObjectContext; }
}
}

Resources