Mapping User table from Asp.Net Identity in AutoMapper - asp.net-web-api

In Asp.Net Core I overrode the IdentityUser table to add more functionalities
public class Person : IdentityUser
{
public string Location {get; set; }
public SellerType SellerType{get; set; }
}
public enum SellerType
{
PrivateSeller ,
Dealer
}
I also have a ViewModel class CredentialModel which I am chaining with the Person class with AutoMapper
public class CredentialModel
{
public string UserName { get; set; }
public string Password { get; set; }
public string FirstName {get;set;}
public string LastName {get; set; }
public string Location {get; set; }
public string SellerType{get; set; }
public string[] SellerTypes {get; set; }
public string PhoneNumber {get; set; }
}
And the AutoMapper Profile Class
public class UserMapProfile : Profile
{
public UserMapProfile(){
CreateMap<CarAdderUser, CredentialModel>()
.ForMember(model=> model.SellerType ,
opt=> opt.MapFrom(vm=>((SellerType)vm.SellerType).ToString()))
.ForMember(model=> model.SellerTypes, opt=> opt.UseValue(Enum.GetNames(typeof(SellerType)).ToArray()))
.ReverseMap();
}
}
My problem is in the Controller
Like this it works but i am returning the entity not the VM
[HttpGet("getUser/{username}")]
public IActionResult GetUser(string username)
{
var user= _userManager.FindByNameAsync(username);
return Ok(user);
}
Like this it throws me a 404 in Postman
[HttpGet("getUser/{username}")]
public IActionResult GetUser(string username)
{
var user= _userManager.FindByNameAsync(username);
return Ok(_mapper.Map<CredentialModel>(user));
}
IT throws me an error
An unhandled exception has occurred: Missing type map configuration or unsupported mapping.
Mapping types:
Task`1 -> CredentialModel
Not sure what to do ... Not an AutoMapper expert

Solved ... the problem was that I forgot that I only need the result ...
so user.Result instead of user in the return ...
Not sure what the other things are ... They are not columns in the User table in the DB

You shouldn't use user.Result. That will block the calling thread. Use async/await instead.
public async Task<IActionResult> GetUser(string username)
{
var user= await _userManager.FindByNameAsync(username);
return Ok(_mapper.Map<CredentialModel>(user));
}

Related

ApplicationUser model is missing in mode class field when trying to create new controller

Missing ApplicationUser:
ApplicationUser in model:
So i try to make User Manager by creating controller with ApplicationUser as model, but i can't find it on model class
I got the same problem but I solved it by creating another model class which does not inherit from identity and fetch the data to it and manage it with empty controller.
The model:
public class MyUser
{
public string Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
and in the Controller:
public ActionResult Index()
{
var users = _context.Users.Select(x => new MyUser
{
Email=x.Email,
FirstName=x.FirstName,
Id=x.Id,
LastName=x.LastName,
UserName=x.UserName
}).ToList();
return View(users);
}
then generate your view.

Url syntax with List property on complex type

Model:
[DataContract]
public class Employee
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[DataMember(Name ="id")]
public int Id{ get; set; }
[DataMember(Name = "fullName")]
public string FullName { get; set; }
}
[DataContract]
public class Department
{
public Department()
{
this.Employees = new List<Employee>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "employees")]
public List<Employee> Employees { get; set; }
}
Controller
public HttpResponseMessage Get([FromUri]Department model)
{
if (ModelState.IsValid)
{
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
Url : "http://localhost:2070/home/get/?id=1&name=IT&Employees=1,John"
I am trying to invoke above URL and the Model does not read the Employees. Other property like int,double,string,decimal are read by the Model.
Can anyone help me on what is the correct format in passing List thru Url.
Also, I dont want to decorate each of my class with modelbinders nor the parameter in my controller.
Tech : WebApi, .Net3.5
You need to specify the index of the list and property to bind with when using FromUri and list/array
Try it this way
http://localhost:2070/home/get/?id=1&name=IT&Employees[0].Id=1&Employees[0].Name=John

Dapper - Query multiple models

My query involves multiple tables and from what I've read on Dapper, I can only find examples, that I understand at least, that query one model.
Below are my 3 classes under the Models folder:
public class User
{
public string UserName { get; set; }
public string UserId { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
public class Date
{
public string UserName { get; set; }
public string UserCode { get; set; }
public string LastLogin { get; set; }
}
public class Photo
{
public class UserName { get; set; }
public string UserId { get; set; }
public string PhotoUrl { get; set; }
}
In my repository I have my connection code and then a method to get all the information I need, however this method is tied to the User model only but I also need to retrieve the photo and when I try to make a compound class so I can the User and Photo models in the view, it gives me an error saying it expects only the User DataView.
public List<User> GetAll()
{
using (SqlConnection cn = new SqlConnection(connectionString))
{
var allResults = cn.Query<User>("SELECT UserName, Email, Phone, (SELECT TOP 1 PhotoPath FROM Photo WHERE User.UserId = Photo.UserId) FROM User)
Your User class does not contain property like PhotoPath - where you expect Dapper put will new/additional value to?
You should create new class (ViewModels/UserAndPhoto.cs for example), which contains all properties you are selecting - then Dapper will read it from database successfully.

EmitMapper Flattering Config NullReferenceException

I am using EmitMapper with Flattering Configuration form EmitMapper samples to map my Entities to DTOs.
The problem is the I am getting NullReferenceException in the case if the source value is the property of the object, which is null, for example:
public class User
{
public Guid Id { get; set; }
public Company Company { get; set; }
}
public class Company
{
public Guid Id { get; set; }
}
public class UserDTO
{
public Guid Id { get; set; }
public Guid CompanyId{ get; set; }
}
I am mapping User to UserDTO: var mapper = ObjectMapperManager.DefaultInstance.GetMapper<User, UserDTO>(
new FlatteringConfig()
);
var dto = mapper.Map(new User());
When EmitMapper will try to get CompanyId, it will call the getter of Company object Id property, but it is null.
Any help will be much appriciated.

Design problem with MVC 3.0

I have a View User :
public class User {
public int id { get; set; }
public string name { get; set; }
public string email { get; set; }
}
I created a login View (strongly typed User)...
But my Login view has others attributes, like RememberMe checkbox... That attribute does not belong to User Model...
So, how is the best way to deal with that? Creating a new UserViewModel with all View attributes is an option, but I think its not the best way...
Paul
So, how is the best way to deal with that?
By using a view model:
public class LoginViewModel
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
Strongly typing a login partial to a User model hardly makes sense.
For best practices I would suggest you use a ViewModel as Darin suggested. Also u can create a factory for copying ViewModel to Entity. Reflection is a bit too much here.
Here is just Darin Dimitrov example in detail.
public class User
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public class LoginViewModel
{
[Required] ... and other validation
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public static class UserFactory
{
public static User GetUserFromModel(LoginViewModel m, User u)
{
u.Username = m.Username;
u.Password = m.Password;
return u;
}
}
public class UserController : DefaultController
{
public ActionResult Login(LoginViewModel m)
{
if (ModelState.IsValid)
{
User u = UserFactory.GetUserFromModel(m);
....code ...
}
... code...
}
}
#Darin sorry for highjacking your example, I remember having a bit of hard time with this myself so just want to help

Resources