Automapper missing type map configuration or unsupported mapping error - asp.net

I am using Auto mapper and I am getting this error, I am getting this error within AddAsync() method. Please help me out to solve this issue.
Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\nDepartmentsViewModel -> Departments\r\nEmployeeAttendanceApp.ViewModels.DepartmentsViewModel -> EmployeeAttendanceApp.Models.StaffManagement.Departments
My class
public interface IMapperConfig
{
IMapper CreateMapper();
}
public class MapperConfig : IMapperConfig
{
public IMapper CreateMapper()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<RegisterStaffs, RegisterStaffViewModel>();
cfg.CreateMap<AttendanceRecorder, AttendanceRecorderViewModel>();
cfg.CreateMap<ManageLeaves, ManageLeavesViewModel>();
cfg.CreateMap<RegisterDevices, RegisterDevicesViewModel>();
cfg.CreateMap<Departments, DepartmentsViewModel>();
});
return config.CreateMapper();
}
}
public class DepartmentsViewModel
{
[Key]
public int DepartmentId { get; set; }
[DisplayName("اسم القسم/ الادارة")]
[Required(ErrorMessage = "الرجاء ادخال اسم القسم")]
public string DepartmentName { get; set; }
[DisplayName("اضافة ملاحظات القسم")]
public string Remarks { get; set; }
public bool? IsUpdated { get; set; }
public bool? IsDeleted { get; set; }
public string CreatedBy { get; set; }
public string DeletedBy { get; set; }
public string UpdatedBy { get; set; }
[DisplayName("عدد الموظفيين")]
[Required(ErrorMessage = " الرحاء إدخال عدد موظفيين القسم")]
public long? StaffNumber { get; set; }
public DateTime? CreatedDate { get; set; }
public virtual ICollection<RegisterDevicesViewModel> RegisterDevices { get; set; }
public virtual ICollection<RegisterStaffViewModel> RegisterStaffs { get; set; }
}
public partial class Departments
{
[Key]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public string Remarks { get; set; }
public bool? IsUpdated { get; set; }
public bool? IsDeleted { get; set; }
public string CreatedBy { get; set; }
public string DeletedBy { get; set; }
public string UpdatedBy { get; set; }
public long? StaffNumber { get; set; }
public DateTime? CreatedDate { get; set; }
public virtual ICollection<RegisterDevices> RegisterDevices { get; set; }
public virtual ICollection<RegisterStaffs> RegisterStaffs { get; set; }
}
**I am getting the error in this method**
public async Task<bool> AddAsync(DepartmentsViewModel departmentsView)
{
try
{
var department = mapper.Map<DepartmentsViewModel, Departments>(departmentsView);
await context.Departments.AddAsync(department);
await context.SaveChangesAsync();
return true;
}
catch(Exception ex)
{
logger.LogError(ex, ex.Message);
return false;
}
}
//here is startup file where I have registered the services
services.AddSingleton<IMapperConfig, MapperConfig>();
services.AddTransient<IDepartmentManager, DepartmentManager>();

I have resolved this issue by adding .ReverseMap() inside MapperConfig class
cfg.CreateMap<Departments, DepartmentsViewModel>().ReverseMap();
but still I can't understand why it didn't work previously with out it because I have seen various examples never using ReverseMap()

Related

Expression of type 'System.Collections.Generic.List`1[API.Entities.CompanySetting]' cannot be used for parameter of type 'System.Linq.IQueryable

I am trying to find a simple way using AutoMapper to return all companies that are linked to a specific User Id in a many-to-many relationship scenario. I followed the SO Automapper many to many mapping but I get the error message "Expression of type 'System.Collections.Generic.List`1[API.Entities.CompanySetting]' cannot be used for parameter of type 'System.Linq.IQueryable" when trying to follow the logic.
My AppUser entity:
public class AppUser
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
My CompanySetting entity:
public class CompanySetting
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
And I have the Join table
public class AppUserCompanySetting
{
public int AppUserId { get; set; }
public virtual AppUser AppUser { get; set; }
public int CompanySettingsId { get; set; }
public virtual CompanySetting CompanySettings { get; set; }
}
I then created a CompanySettingDto
public class CompanySettingDto
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
}
And a MemberDto:
public class MemberDto
{
public int Id { get; set; }
public string Username { get; set; }
public string PhotoUrl { get; set; }
public string KnownAs { get; set; }
public int TimeActive { get; set; }
public DateTime LastActive {get; set;}
public ICollection<PhotoDto> Photos { get; set; }
public ICollection<CompanySettingDto> CompanyInformation { get; set; }
}
I then tried Automapper to bring the relationships between the User and the Company Information I require:
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<AppUser, MemberDto>()
.ForMember(dest => dest.CompanyInformation, opt => opt.MapFrom(x => x.AppUserCompanySettings.Select(y => y.CompanySettings).ToList()))
CreateMap<CompanySetting, CompanySettingDto>();
}
}
I am writing an API call to get all companies that are linked to a specific UserId.
public async Task<IEnumerable<MemberDto>> GetCompaniesByUserIdAsync(int userId)
{
return await _context.Users
.Where(x => x.Id == userId)
.ProjectTo<MemberDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}

How to Create EF one-to-one relationship with Asp.net Identity

Goal: Create a one-to-one relationship between EF Asp.Net.Identity.User and EF UserBusiness
This is my EF Asp.Net.Identity.User:
public class UserEntity:IdentityUser
{
public override string Id { get; set; }
public override string UserName { get; set; }
public override string Email { get; set; }
public override string NormalizedUserName { get; set; }
public override string NormalizedEmail { get; set; }
public string Telephone { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
public DateTime? DateOfBirth { get; set; }
public string NIF { get; set; }
public string Gender { get; set; }
public string Password { get; set; }
public bool IsUserProfileCompleted { get; set; }
**public ICollection<UserBusinessEntity> Business { get; set; }**
public ICollection<PatientEntity> Patients { get; set; }
public DateTime UpdatedOn { get; set; }
public bool IsDeleted { get; set; }
public DateTime CreatedOn { get; set; }
My EF UserBusiness:
[Table ("UserBusiness")]
public class UserBusinessEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string BusinessId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
public string Fax { get; set; }
public string Owner { get; set; }
public string OwnerPointofContact { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime DeletedOn { get; set; }
public DateTime UpdatedOn { get; set; }
[ForeignKey("Id")]
public string Id { get; set; }
public virtual UserEntity User { get; set; }
}
Repository:
==> RepositoryExtension:
public static IQueryable<UserEntity> BuildUserWithBusiness(this IQueryable<UserEntity> query)
{
return query.Include(u => u.Business);
}
==> Repository
public async Task<UserEntity> GetByIdWithBusinessAsync(string businessId)
{
return await _context.Users
.BuildUserWithBusiness()
.FirstOrDefaultAsync(x => x.Id == businessId);
}
Fluent API:
public class DentalClinicDbContext : IdentityDbContext<UserEntity, UserRoleEntity, string>
{
public DbSet<UserBusinessEntity> UserBusiness { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<UserEntity>(entity =>
{
entity.ToTable("Users");
});
builder.Entity<UserEntity>(entity =>
{
entity.HasOne(b => b.Business)
.WithOne(u => u.User);
});
I got an error on u.User
Error:
'ICollection' does not contain a definition for 'User' and no accessible extension method 'User' accepting a first argument of type 'Collection could be found (are you missing a using directive or an assembly reference?)
There is a line in your code,
public ICollection<UserBusinessEntity> Business { get; set; }
which should be changed to,
public UserBusinessEntity Business { get; set; }
Also, the model builder should be changed to,
builder.Entity<UserEntity>(entity =>
{
entity.HasOne(b => b.Business)
.WithOne(u => u.User);
.HasForeignKey<BusinessUser>(c => c.Id);
});
Please note that I haven't tried the code real-time.
You should follow this example:
https://www.entityframeworktutorial.net/efcore/configure-one-to-one-relationship-using-fluent-api-in-ef-core.aspx

Can't convert from model to viewmodel, using AutoMapper asp.net core

I am using Auto mapper to map between modelviews and models. I have followed the same steps given by the Auto mapper documentation and still can't find where the issue is.
public class RegisterStaffViewModel
{
public int Id { get; set; }
[Required(ErrorMessage = "StaffName Required")]
public string StaffName { get; set; }
[Required(ErrorMessage = "Gender Required")]
public string Gender { get; set; }
[Required(ErrorMessage = "Address Required")]
public string Address { get; set; }
[Required(ErrorMessage = "StaffCode Required")]
public string StaffCode { get; set; }
[DisplayName("Department")]
[Required(ErrorMessage = "Department is Required")]
public int? DepartmentId { get; set; }
public string CardNo { get; set; }
[Required(ErrorMessage = "Mobileno Required")]
[RegularExpression(#"^(\d{10})$", ErrorMessage = "Wrong Mobileno")]
public string MobileNo { get; set; }
[Required(ErrorMessage = "EmailID Required")]
[RegularExpression(#"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Please enter a valid e-mail adress")]
public string Email { get; set; }
public DateTime EntryDate { get; set; }
[Display(Name = "Position")]
[Required(ErrorMessage = "Position is Required")]
public int? PositionId { get; set; }
[Display(Name = "Staff Type")]
[Required(ErrorMessage = "Staff Type is Required")]
public int? StaffTypeId { get; set; }
public string CardIdNo { get; set; }
public bool? IsDeleted { get; set; }
public bool? IsUpdated { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
public string DeletedBy { get; set; }
public string Remarks { get; set; }
public virtual ApplicationUser CreatedByNavigation { get; set; }
public virtual ApplicationUser DeletedByNavigation { get; set; }
public virtual Departments Department { get; set; }
public virtual Positions Position { get; set; }
public virtual StaffTypes StaffType { get; set; }
public virtual ApplicationUser UpdatedByNavigation { get; set; }
public virtual ICollection<AttendanceRecorderViewModel> AttendanceRecorder { get; set; }
public virtual ICollection<ManageLeavesViewModel> ManageLeaves { get; set; }
public virtual ICollection<RegisterDevicesViewModel> RegisterDevices { get; set; }
}
=============================================================================================
public partial class RegisterStaffs
{
public int Id { get; set; }
public string StaffName { get; set; }
public string Gender { get; set; }
public string Address { get; set; }
public string StaffCode { get; set; }
public int? DepartmentId { get; set; }
public string CardNo { get; set; }
public string MobileNo { get; set; }
public string Email { get; set; }
public DateTime EntryDate { get; set; }
public int? PositionId { get; set; }
public int? StaffTypeId { get; set; }
public string CardIdNo { get; set; }
public bool? IsDeleted { get; set; }
public bool? IsUpdated { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
public string DeletedBy { get; set; }
public string Remarks { get; set; }
public virtual ApplicationUser CreatedByNavigation { get; set; }
public virtual ApplicationUser DeletedByNavigation { get; set; }
public virtual Departments Department { get; set; }
public virtual Positions Position { get; set; }
public virtual StaffTypes StaffType { get; set; }
public virtual ApplicationUser UpdatedByNavigation { get; set; }
public virtual ICollection<AttendanceRecorder> AttendanceRecorder { get; set; }
public virtual ICollection<ManageLeaves> ManageLeaves { get; set; }
public virtual ICollection<RegisterDevices> RegisterDevices { get; set; }
}
============================================================================================
public interface IMapperConfig
{
IMapper CreateMapper();
}
public class MapperConfig : IMapperConfig
{
public IMapper CreateMapper()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<RegisterStaffs, RegisterStaffViewModel>();
cfg.CreateMap<AttendanceRecorder, AttendanceRecorderViewModel>();
cfg.CreateMap<ManageLeaves, ManageLeavesViewModel>();
cfg.CreateMap<RegisterDevices, RegisterDevicesViewModel>();
});
return config.CreateMapper();
}
}
==========================================================================================
public async Task<ReturnResult<List<RegisterStaffViewModel>>> GetAllEmployees()
{
var result = new ReturnResult<List<RegisterStaff>>();
try
{
var employees = await context.RegisterStaffs.Where(x => (bool)!x.IsDeleted).OrderByDescending(x => x.EntryDate).AsNoTracking().ToListAsync();
// **here is the error**
result.Success(mapper.Map<List<RegisterStaffs>, List<RegisterStaffViewModel>>(employees));
}
catch(Exception ex)
{
}
return result;
}
============================================================================================
public class ReturnResult<T>
{
public ReturnResult()
{
ErrorList = new List<string>();
}
public bool IsSuccess { get; set; }
public HttpCode HttpCode { get; set; }
public T Data { get; set; }
public List<string> ErrorList { get; set; }
/// <summary>
/// Set success result with data
/// </summary>
/// <param name="Data"></param>
public void Success(T Data)
{
this.IsSuccess = true;
this.HttpCode = HttpCode.Success;
this.Data = Data;
}
/// <summary>
/// Set Server Error result with error message
/// </summary>
/// <param name="Error"></param>
public void ServerError(string Error)
{
this.IsSuccess = false;
this.HttpCode = HttpCode.ServerError;
this.ErrorList.Add(Error);
}
/// <summary>
/// Set Not Found result with error message
/// </summary>
/// <param name="Error"></param>
public void NotFound(string Error)
{
this.IsSuccess = false;
this.HttpCode = HttpCode.NotFound;
this.ErrorList.Add(Error);
}
}
I found the issue was here
var result = new ReturnResult<List<RegisterStaff>>();
i have changed it to
var result = new ReturnResult<List<RegisterStaffViewModel>>();

MVC4 EF5 entity property not updating on SaveChanges()

I've been reading through lots of articles trying to learn MVC4, but I'm stumped as to why my entity is not getting updated to database.
I've been trying to modify the MVC4 VS2012 Internet template.
So, here's the Controller action:
[HttpPost, ActionName("Approve")]
[Authorize]
public ActionResult ApproveConfirmed(long id)
{
using (StudentiContext context = new StudentiContext())
{
// context.Configuration.AutoDetectChangesEnabled = false;
var studente = (from d in context.STUDENTI_STRANIERI_MASTER_REG
where d.ID_PERSONA == id
select d).Single();
STUDENTI_STRANIERI_MASTER_REG st2 = studente;
st2.ESITO = 1;
//studente.ESITO = 1;
var statos = context.Entry(studente).State;
Console.WriteLine("Before DetectChanges: {0}",statos);
//context.ChangeTracker.DetectChanges();
context.Entry(studente).State = EntityState.Modified;
context.Entry(studente).CurrentValues.SetValues(st2);
// var tracked = context.ChangeTracker.Entries();
context.Entry(studente).Property( o => o.ESITO ).IsModified = true;
TryUpdateModel(studente);
context.SaveChanges();
Console.WriteLine("After DetectChanges: {0}",statos);
return RedirectToAction("PrivateIndex");
}
}
The aim is just to update one property, ESITO and set it to 1. Currently its value is 2.
This is the model:
namespace MvcStudenti2.Models
{
using System;
using System.Collections.Generic;
public partial class STUDENTI_STRANIERI_MASTER_REG
{
public long ID_PERSONA { get; set; }
public string COGNOME { get; set; }
public string NOME { get; set; }
public string SESSO { get; set; }
public System.DateTime DATA_NASCITA { get; set; }
public long ID_STATO_NASCITA { get; set; }
public string LUOGO_NASCITA_ESTERO { get; set; }
public string CODICE_FISCALE { get; set; }
public string TITOLO_POSSEDUTO { get; set; }
public Nullable<short> DURATA_TITOLO { get; set; }
public string VOTAZIONE { get; set; }
public string UNI_PROVENIENZA { get; set; }
public long ID_STATO_UNI { get; set; }
public string CERT_LINGUISTICA { get; set; }
public string CERT_PUNTEGGIO { get; set; }
public string NOTE { get; set; }
public System.DateTime DATA_RICHIESTA { get; set; }
public short ESITO { get; set; }
public string CDS_COD { get; set; }
public string EMAIL { get; set; }
public string NUMERO_TELEFONO { get; set; }
public string INDIRIZZO { get; set; }
public string CAP_INDIRIZZO { get; set; }
public string CITTA { get; set; }
public long ID_STATO_INDIRIZZO { get; set; }
public string DESCRIZIONE_CIT_NAZ { get; set; }
public Nullable<System.DateTime> DATA_COMPLETAMENTO_ATTESO { get; set; }
public Nullable<System.DateTime> ANNO_COMPLETAMENTO { get; set; }
public Nullable<short> DURATA_CORSO_COMPLETATO { get; set; }
public decimal GPA { get; set; }
public string ALTRI_TITOLI { get; set; }
public string MADRELINGUA { get; set; }
public Nullable<short> CERT_TOEFL_PUNT { get; set; }
public string CERT_FIRSTCERT_GRADE { get; set; }
public Nullable<short> CERT_FIRSTCERT_PUNT { get; set; }
public byte[] FILE_CV { get; set; }
public byte[] FILE_CARRIERA { get; set; }
public byte[] FILE_CERT_LINGUA { get; set; }
public byte[] FILE_DOC_IDENTITA { get; set; }
public string PWD { get; set; }
public string FILE_CV_NOME { get; set; }
public string FILE_CARRIERA_NOME { get; set; }
public string FILE_CERT_LINGUA_NOME { get; set; }
public string FILE_DOC_IDENTITA_NOME { get; set; }
public string FILE_CV_TIPO { get; set; }
public string FILE_CARRIERA_TIPO { get; set; }
public string FILE_CERT_LINGUA_TIPO { get; set; }
public string FILE_DOC_IDENTITA_TIPO { get; set; }
public Nullable<short> STATO { get; set; }
public Nullable<short> VALUTATO { get; set; }
public Nullable<short> ARCHIVIATO { get; set; }
public string CDS_COD_2 { get; set; }
public Nullable<short> MAIL_INVIATA { get; set; }
public string LINK_ULTIMO_CORSO { get; set; }
public Nullable<short> ATTIVO { get; set; }
public byte[] FILE_LETTERA_ACCETTAZIONE { get; set; }
public string FILE_LETTERA_ACCETTAZIONE_NOME { get; set; }
public string FILE_LETTERA_ACCETTAZIONE_TIPO { get; set; }
}
}
Everywhere I read I find that SaveChanges() should be enough, possibly after the EntityState.Modified.
I can correctly edit the entity, if I pass the whole entity to the Action, but in this case the Approve view is a built on a Detail template, so I don't have anything to POST from it (and I'd prefer not to: I could insert a hidden field and post just that, but I'm trying to update a single filed from code, and I'm not sure if the whole entity would get updated or overwritten ).
statos goes to "modified", if I understand correctly, because I have done a query on the entity.
Another thing I don't understand is why ESITO gets update -also- in studente, but then reverts to "2" after SaveChanges().
Are property changes being detected? I've wrapped every Action in a using block, as suggested elsewhere, so not to have multiple contextx/instances around.
Could anyone please point me to what I'm doing wrong? The code above is probably over-redundant, but I've been trying everything I have found on SO.
Thanks, everyone.
The following is all that is required to change the ESITO property.
[HttpPost, ActionName("Approve")]
[Authorize]
public ActionResult ApproveConfirmed(long id)
{
using (StudentiContext context = new StudentiContext())
{
// context.Configuration.AutoDetectChangesEnabled = false;
var studente = (from d in context.STUDENTI_STRANIERI_MASTER_REG
where d.ID_PERSONA == id
select d).Single();
studente.ESITO = 1;
context.SaveChanges();
return RedirectToAction("PrivateIndex");
}
}

Retrieving twitter with json

I'm having trouble with parsing a twitter flow, this code is returning this error message:
No parameterless constructor defined for type of
'System.Collections.Generic.IEnumerable`1[[Xxxx.Website.Templates.WidgetViews.Tweet,
Dolphin, Version=1.0.4801.24288, Culture=neutral,
PublicKeyToken=null]]'.
I would very much appreciate your help!
public partial class TwitterWidgetView
{
protected override void OnLoad(System.EventArgs e)
{
string listName = "sas";
string twitterListPath = "https://search.twitter.com/search.json?q=" + listName;
WebClient wc = new WebClient();
var json = wc.DownloadString(twitterListPath);
JavaScriptSerializer ser = new JavaScriptSerializer();
var tweetList = ser.Deserialize<IEnumerable<Tweet>>(json);
}
}
public class Metadata
{
public string result_type { get; set; }
}
public class Tweet
{
public Tweet()
{}
public string created_at { get; set; }
public string from_user { get; set; }
public int from_user_id { get; set; }
public string from_user_id_str { get; set; }
public string from_user_name { get; set; }
public object geo { get; set; }
public object id { get; set; }
public string id_str { get; set; }
public string iso_language_code { get; set; }
public Metadata metadata { get; set; }
public string profile_image_url { get; set; }
public string profile_image_url_https { get; set; }
public string source { get; set; }
public string text { get; set; }
public string to_user { get; set; }
public int to_user_id { get; set; }
public string to_user_id_str { get; set; }
public string to_user_name { get; set; }
public long? in_reply_to_status_id { get; set; }
public string in_reply_to_status_id_str { get; set; }
}
public class RootObject
{
public RootObject()
{}
public double completed_in { get; set; }
public long max_id { get; set; }
public string max_id_str { get; set; }
public string next_page { get; set; }
public int page { get; set; }
public string query { get; set; }
public string refresh_url { get; set; }
public List<Tweet> results { get; set; }
public int results_per_page { get; set; }
public int since_id { get; set; }
public string since_id_str { get; set; }
}
Try using a list instead
var tweetList = ser.Deserialize<List<Tweet>>(json);

Resources