Using nested mapping in automapper
I am trying to configure Automapper so that it automatically maps an object to another object type when mapping the object it's contained in.
I have an event entity:
public class Event {
public int Id { get; set; }
public String Name { get; set; }
public AppUser Creator { get; set; }
public Photo MainPhoto { get; set; }
}
This is the AppUser Entity:
public class AppUser
{
public int Id { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
}
This is the Photo entity:
public class Photo
{
public int Id { get; set; }
public string publicId { get; set; }
public string Url { get; set; }
}
I have this CreateEvent method in one of my controllers which handles the creation of the event and adds it to my sql lite database:
[HttpPost]
public async Task<ActionResult<EventDto>> CreateEvent(EventDto newEvent)
{
var createdEvent = _mapper.Map<EventDto, Event>(newEvent);
await _eventsRepository.CreateEvent(createdEvent);
return newEvent;
}
This is the EventDto:
public class EventDto
{
public int Id { get; set; }
public string Name { get; set; }
public PhotoDto MainPhoto { get; set; }
public MemberDto Creator { get; set; }
}
This is the Automapper config class I have:
public class AutoMapperProfile : Profile
{
public AutoMapperProfile() {
CreateMap<AppUser, MemberDto>();
CreateMap<MemberDto, AppUser>();
CreateMap<Photo, PhotoDto>();
CreateMap<PhotoDto, Photo>();
CreateMap<Event, EventDto>();
CreateMap<EventDto, Event>();
}
}
So when the EventDto is converted to the Event entity here (see above in the CreateEvent method) :
var createdEvent = _mapper.Map<EventDto, Event>(newEvent);
I want the 'PhotoDto' to automatically convert into a 'Photo' object and the 'memberDto' to automatically convert into an 'AppUser'.
Is there anyway to achieve this with Automapper?
See also questions close to this topic
-
Filter items in a listbox that have been added with json
Well I'm trying to list items that are from listbox created with UserControl and the text properties are defined with a json file.
This is my .json file:
{ "Games": { "Quantity": 2, "Title0": "SomeGame1", "Description0": "Fps game", "Image0": "Some image link", "Link0": "GameStore.com/Somegame1", "Title1": "SomeGame2", "Description1": "RPG game", "Image1": "Some image link", "Link1": "GameStore.com/Somegame2", } }
This is the code to load the games as items in the listbox:
string JsonFile = Environment.CurrentDirectory @"\Test.json"; dynamic jasonfile = JsonConvert.DeserializeObject(JsonFile); GameUserControl[] Games = new GameUserControl[jasonfile["Games"]["Quantidade"]]; for (int quantity= 0; quantity < Games.Length; quantity++) { Games[quantity] = new GameUserControl(); Games[quantity].Descrição.Content = (jasonfile["Games"]["Title" + quantity]); Games[quantity].jog = (jasonfile["Games"]["Titulo" + quantity]); Games[quantity].lin = (jasonfile["Games"]["Link" + quantity]); string image = jasonfile["Games"]["Image" + quantity]; Games[quantity].imag = new ImageBrush(new BitmapImage(new Uri(image, UriKind.Absolute))); GamesListBox.Items.Add(Games[quantity]); }
This is the code I used in a textbox to try to filter:
if (CollectionViewSource.GetDefaultView(GamesListBox.Items) != null) CollectionViewSource.GetDefaultView(GamesListBox.Items).Filter = (o) => { return o.ToString().ToLower().Contains(Search.Text.ToLower()); };
But it didn't work, the item names are always GameUserContro.Can someone help me?
-
Advantage of .Net Core over WCF for RESTful APIs
We are currently using WCF to create RESTful APIs, it is working fine and has an added advantage that it can be consumed via SOAP too if we ever need to. We have all our systems using Microsoft technologies.
There is no active development on WCF but the current functionality is working fine for us. However, I believe the recommended approach is to start using .Net core for RESTful services. What are the additional advantages .Net core offers over WCF (apart from being platform independent)?
-
Generic class type constraint with a generic class having another constraint
Let's say I have a generic class
public class G<T> { }
and I want to declare final class as
public class F<T> where T : G<T> { }
that seems to be possible, but what if I want to complicate the task and add a constraint to the class G like that
public class A { } public class DA : A { } public class DB : A { } public class G<T> where T : A { }
and finally I want to do this
public class F<T> where T : G<T> { }
that does not work, it says T has to be of type A which is understandable and it looks like I can rewrite it like this
public class F<T, U> where T : G<U> where U : A { }
but in this case the usage has a redundant declaration
public class DF : F<G<DA>, DA> { }
I have to repeat DA twice when using class F even though it is quite clear if I use G as a generic type the generic type of G is DA. Is there a way to avoid this redundancy?
-
Cascading databound <ajaxtoolkit:combobox> and <asp:dropdownlist> in asp.net
I have an
asp.net
search form that includes anajaxToolkit Combobox
and a standardasp DropDownList
. Both controls are bound to two separatedSqlDatasource
components.Something like this:
<ajaxToolkit:ComboBox ID="cbConvenzionato" runat="server" AutoCompleteMode="SuggestAppend" DropDownStyle="DropDownList" DataSourceID="sdsConvenzionati" DataTextField="nome" DataValueField="id" AutoPostBack="true" OnSelectedIndexChanged="cbConvenzionato_SelectedIndexChanged" /> <asp:DropDownList ID="ddlVeicoli" DataSourceID="sdsVeicoli" DataTextField="targa" DataValueField="id" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlVeicoli_SelectedIndexChanged" AppendDataBoundItems="true"> <asp:ListItem Text="TUTTI" Value="" Selected="True" /> </asp:DropDownList> <asp:SqlDataSource ID="sdsConvenzionati" runat="server" ConnectionString="<%$ ConnectionStrings:db %>" ProviderName="<%$ ConnectionStrings:db.ProviderName %>" SelectCommand=" SELECT id, nome FROM anag_convenzionati ORDER BY nome;" /> <asp:SqlDataSource ID="sdsVeicoli" runat="server" EnableCaching="false" CancelSelectOnNullParameter="false" ConnectionString="<%$ ConnectionStrings:db %>" ProviderName="<%$ ConnectionStrings:db.ProviderName %>" SelectCommand=" SELECT id, targa FROM veicoli_contratti WHERE ((@id_convenzionato IS NULL) OR (id_convenzionato = @id_convenzionato)) ORDER BY targa;"> <SelectParameters> <asp:ControlParameter Name="id_convenzionato" ControlID="cbConvenzionato" PropertyName="SelectedValue" Direction="Input" ConvertEmptyStringToNull="true" DbType="Int32" DefaultValue="" /> </SelectParameters> </asp:SqlDataSource>
There's also a third
sqldatasource
(sdsNoleggi
) that feeds agridview
but this's not a problem right now.In code behind I have two event handlers:
protected void cbConvenzionato_SelectedIndexChanged(object sender, EventArgs e) { sdsVeicoli.Select(DataSourceSelectArguments.Empty); Search(); } protected void ddlVeicoli_SelectedIndexChanged(object sender, EventArgs e) { Search(); } private void Search() { sdsNoleggi.Select(DataSourceSelectArguments.Empty); }
I tought in this way I should filter
ddlVeicoli
items after selecting an item incbConvenzionato
... but it's not working... why?If I look into
sdsVeicoli
SelectParameters
in debug I can seeid_convenzionato
being correctly set to selected value (id coming fromcbConvenzionato
) I bet also thatsdsNoleggi
dataset wiil be correctly updated with new values since I did this many times before. So why bound control it's not? I tried also to force addlVeicoli.DataBind()
aftersdsVeicoli.Select()
call ... but this had no effect. -
Swagger UI not working for REST API (asp.net web api2) application
I have asp.net mvc project with .NET Framework 4.7.2 and the same project contains asp.net web api2 controller in a separate folder : Controllers. The solution is legacy. The API are already in use in the PRODUCTION environment. Now I added the Swagger nuget package (Install-Package Swashbuckle -Version 5.6.0) to this existing project. Post that I see a SwaggerConfig.cs added to the App_Start folder of the Solution Explorer.
Here the asp.net mvc controllers are used by App1 pointing to the server: www.app1.com and asp.net web api2 controllers are used by another frontend angular app: App2 pointing to the server : www.app2.com
The complete deployment package for both App1 and App2 are hosted in IIS
Any request related to App1 is handled by www.app1.com and any api request related to App2 (Angular frontend) is handled by App1 only using IIS Rewrite rules at App2 level which redirect any api request to App1 only.
Now in this case when I tried to navigate to www.app1.com/swagger , I see it is loading the SwaggerUI for me, but when I tried to navigate to www.app2.com/swagger it is not working and instead of that it is loading the Angular frontend application
Here goes the App1 and App2 at IIS level:
Can anyone help me here by providing their guidance to fix this issue?
-
Cors error missing allow origin header. MailKit
I have
cors error missing allow origin header
error only on ONE post request. My CORS Policypublic void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowAllOrigins", builder => { builder.SetIsOriginAllowed(_ => true) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); }
Every request work fine, but one POST request fails, it's really weird. Code in controller action which failed use MailKit and SMTP to send email, maybe that's cause
-
AutoMapperMappingException: Error mapping types: AnalysisDto -> Analysis
I've been working on developing API using the AutoMapper in ASP.NET Core. So, I'm getting an error 'Error mapping types: AnalysisDto -> Analysis' while I'm trying to Update my Analysis model with PUT method. The Error screen is below:
How it's implemented:
1.My Analysis Model:
public class Analysis { [Required] public Guid Id { get; set; } public User SportsmanUserId { get; set; } public User DoctorUserId { get; set; } public string Name { get; set; } public DateTime Date { get; set; } public string Type { get; set; } public double? Weight { get; set; } public double? Height { get; set; } public double? Measure { get; set; } public string Description { get; set; } public bool? Result { get; set; } }
- My Analysis DTO Model to pass the data:
public class AnalysisDto { public Guid Id { get; set; } public Guid SportsmanUserId { get; set; } public Guid DoctorUserId { get; set; } public string Name { get; set; } public DateTime Date { get; set; } public string Type { get; set; } public double Weight { get; set; } public double Height { get; set; } public double Measure { get; set; } public string Description { get; set; } public bool? Result { get; set; } }
The basic idea is that I need to Update the Analysis with already existed Users(Sportsman and Doctor). How my PUT method looks like:
[HttpPut] public async Task<Analysis> Update(AnalysisDto analysisDto) { try { var analysis = await myDbContext.Analysis.Where(o => o.SportsmanUserId.Id == analysisDto.SportsmanUserId).Where(o => o.DoctorUserId.Id == analysisDto.DoctorUserId).FirstOrDefaultAsync(); mapper.Map(analysisDto, analysis); await analysisService.Update(analysis); return analysis; } catch (Exception) { throw; } }
And for the last, how AutoMapper is implemented here:
AutoMapping Profile:
public class AutoMapping : Profile { public AutoMapping() { CreateMap<UserDto, User>(); CreateMap<AnalysisDto, Analysis>(); } }
Startup class configuration:
var mappingConfig = new MapperConfiguration(mc => { mc.AddProfile(new AutoMapping()); }); IMapper mapper = mappingConfig.CreateMapper(); services.AddSingleton(mapper);
What am I doing wrong? Do I need to change the AutoMapping file or how to solve the issue? Thanks to everyone in advance!
-
Error using AutoMapper with DataTable and DataRows
I am using AutoMapper (10.1.1) with AutoMapper.Data (5.0.0) to dynamically map DataRow or DataTable with my DTOs. I configured my application following this instructions https://github.com/AutoMapper/AutoMapper.Data
I have seen also this reference https://elegantcode.com/2009/10/16/mapping-from-idatareaderidatarecord-with-automapper/
This is my configuration class
var mapper = new Mapper(cfg => { cfg.AddDataReaderMapping(); cfg.CreateMap<IDataRecord, MyModelDto>(); });
I inject IMapper with success in my service:
public class ServiceClass { [Dependency] public IMapper Mapper { get; set; } public IEnumerable<MyModelDto> GetList() { IEnumerable<MyModelDto> res; var conn = new SqlConnection("..."); SqlCommand cmd = new SqlCommand("SELECT * FROM MyTable", conn); conn.Open(); using (SqlDataReader reader= cmd.ExecuteReader()) { res = this.Mapper.Map<IDataReader, IEnumerable<MyModelDto>>(reader); // throws error conn.Close(); } return res; } }
When I invoke Map() method occurs the following error "Object reference not set to an instance of an object"
Thanks for help
-
Object reference not set using AutoMapper with DataTable and DataRows
I am using AutoMapper (10.1.1) with AutoMapper.Data (5.0.0) to dynamically map DataRow or DataTable with my DTOs. I configured my application following this instructions https://github.com/AutoMapper/AutoMapper.Data
I have seen also this reference https://elegantcode.com/2009/10/16/mapping-from-idatareaderidatarecord-with-automapper/
This is my configuration class
var mapper = new Mapper(cfg => { cfg.AddDataReaderMapping(); cfg.CreateMap<IDataRecord, MyModelDto>(); });
I inject IMapper with success in my service:
public class ServiceClass { [Dependency] public IMapper Mapper { get; set; } public IEnumerable<MyModelDto> GetList() { IEnumerable<MyModelDto> res; var conn = new SqlConnection("..."); SqlCommand cmd = new SqlCommand("SELECT * FROM MyTable", conn); conn.Open(); using (SqlDataReader reader= cmd.ExecuteReader()) { res = this.Mapper.Map<IDataReader, IEnumerable<MyModelDto>>(reader); // throws error conn.Close(); } return res; } }
When I invoke Map() method occurs the following error "Object reference not set to an instance of an object"
Thanks for help