I have interface where I am setting a list and trying to fill the list later on, however I am getting null exception in the LoadSet() method.
public interface ISettings
{
List<CustomSetting> CustomSettings { get; set; }
}
public class SettingsService : ISettings
{
CameraResolution cameraResolution = new CameraResolution();
public string Name { get; set; }
public List<CustomSetting> CustomSettings { get; set; }
public SettingsService()
{
Name = customSettings.Name;
CustomSettings = new List<CustomSetting>();
LoadSet();
}
public void LoadSet()
{
var detail = new CustomSetting
{
Name = cameraResolution.Name,
Value = cameraResolution.Value,
};
CustomSettings.Add(detail);
}
}
Related
I m trying to get all properties from a sub class and then set the value.
but I dont not know how I can start. I know how I can get the properties and set the value. but no on a sub class.
public class Program {
public static void Main(string[] args) {
object[] Response = new object[] {
new Cars() {
Details = new Details() {
CanDrive = true,
ID = 123,
IsPolice = true
},
Name = "test",
Speed = 100
}
};
var Result = Test <Cars> (Response);
Console.WriteLine(Result.Speed);
}
private static T Test <T> (object[] Obj) {
var Instance = CreateInstance <T> ();
foreach(var Ob in Obj) {
PropertyInfo[] C = Ob.GetType().GetProperties();
foreach(var n in C) {
PropertyInfo[] P = typeof(T).GetProperties();
foreach(PropertyInfo Val in P) {
if (n.Name == Val.Name) V
Val.SetValue(Instance, n.GetValue(Ob));
}
}
}
return Instance;
}
private static T CreateInstance <T>() => Activator.CreateInstance<T>();
public class Cars {
public int Speed { get; set; }
public string Name { get; set; }
public Details Details { get; set; }
}
public class Details {
public int ID { get; set; }
public bool CanDrive { get; set;}
public bool IsPolice { get; set; }
}
}
how can I get the sub classes? and set the value of the class?
Edit
Updated my Code. for better understanding.
I'm confused why we're going all the way up to reflection for this?
Could this just be as simple as
var car = new Car();
car.Details = new Details()
{
CanDrive = true,
ID = 42,
IsPolice = false
};
public class Program
{
public static void Main(string[] args)
{
var CarInstance = CreateInstance<Cars>();
PropertyInfo[] P = typeof(Cars).GetProperties();
foreach (PropertyInfo Car in P)
{
if(Car.Details.IsPolice) //Access properties of subclass using the name of the property, which is "Details"
Car.SetValue(CarInstance, 12345);
if(Car.Name == "ID")
Car.SetValue(CarInstance, 12345);
}
}
private static T CreateInstance<T>() => Activator.CreateInstance<T>();
public class Cars
{
public int Speed { get; set; }
public string Name { get; set; }
public Details Details { get; set; }
}
public class Details
{
public int ID { get; set; }
public bool CanDrive { get; set; }
public bool IsPolice { get; set; }
}
}
This minor difference may help clear up some confusion:
public class Program
{
public static void Main(string[] args)
{
var CarInstance = CreateInstance<Cars>();
PropertyInfo[] P = typeof(Cars).GetProperties();
foreach (PropertyInfo Car in P)
{
if(Car.ThisCarDetails.IsPolice) //Access properties of subclass using the name of the property, which is "ThisCarDetails"
Car.SetValue(CarInstance, 12345);
if(Car.Name == "ID")
Car.SetValue(CarInstance, 12345);
}
}
private static T CreateInstance<T>() => Activator.CreateInstance<T>();
public class Cars
{
public int Speed { get; set; }
public string Name { get; set; }
public Details ThisCarDetails { get; set; }
}
public class Details
{
public int ID { get; set; }
public bool CanDrive { get; set; }
public bool IsPolice { get; set; }
}
}
The error message that I'm receiving at runtime is:
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
List'1 -> MobileRoot (Destination member list)
System.Collections.Generic.List'1[[Strata.CS.Jazz.Biz.Dashboard.MobileInfo, Strata.CS.Jazz.Biz, Version=2019.10.0.0, Culture=neutral, PublicKeyToken=null]] -> Strata.Jazz.Web.Controllers.MobileController+MobileRoot (Destination member list)
Unmapped properties:
Users
From what I can tell from the error message is that AutoMapper needs to know how to handle the ForMember Users create in the MobileRoot, and then propagate that for each of the subsequent lists down the chain. Can anyone tell me how to do this efficiently using AutoMapper? I know how to do this with Linq using GroupBy and Select, so it is my thought that this should be do-able with AutoMapper.
The query I have returns this class:
public class MobileInfo
{
public string NameFull { get; set; }
public string EmailAddress { get; set; }
public string SolutionName { get; set; }
public int SortOrder { get; set; }
public string Name { get; set; }
public bool IsLegacy { get; set; }
public string Description { get; set; }
public string WidgetName { get; set; }
public int Row { get; set; }
public int Col { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public string WidgetClassName { get; set; }
public string Data { get; set; }
}
I would like to use Automapper with profiles to have it return this:
internal class MobileRoot
{
public IEnumerable<MobileUser> Users { get; set; }
}
internal class MobileUser
{
public string NameFull { get; set; }
public string EmailAddress { get; set; }
public IEnumerable<MobileSolution> Solutions { get; set; }
}
internal class MobileSolution
{
public string Solution { get; set; } // MobileInfo.SolutionName
public int SortOrder { get; set; }
public IEnumerable<MobileDashboard> Dashboards { get; set; }
}
internal class MobileDashboard
{
public string Dashboard { get; set; } // MobileInfo.Name
public bool IsLegacy { get; set; }
public string Description { get; set; }
public IEnumerable<MobileWidget> Widgets { get; set; }
}
internal class MobileWidget
{
public string Widget { get; set; } // MobileInfo.WidgetName
public int Row { get; set; }
public int Col { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public string WidgetClassName { get; set; }
public string Data { get; set; }
}
The Profiles I have defined so far are:
public class ProfileMobileRoot : Profile
{
public ProfileMobileRoot()
{
CreateMap<MobileInfo, MobileRoot>();
}
}
public class ProfileMobileUser : Profile
{
public ProfileMobileUser()
{
CreateMap<MobileInfo, MobileUser>();
}
}
public class ProfileMobileSolution : Profile
{
public ProfileMobileSolution()
{
CreateMap<MobileInfo, MobileSolution>();
}
}
public class ProfileMobileDashboard : Profile
{
public ProfileMobileDashboard()
{
CreateMap<MobileInfo, MobileRoot>();
}
}
public class ProfileMobileWidget : Profile
{
public ProfileMobileWidget()
{
CreateMap<MobileInfo, MobileWidget>();
}
}
You can do something like below. It's a little late so my solution isn't so sophisticated... but it works ;)
public class ProfileMobileRoot : Profile
{
public ProfileMobileRoot()
{
CreateMap<MobileInfo, MobileWidget>()
.ForMember(x=>x.Name, opt=>opt.MapFrom(x=>x.WidgetName));
CreateMap<IEnumerable<MobileInfo>, IEnumerable<MobileDashboard>>()
.ConvertUsing<DashboardConverter>();
CreateMap<IEnumerable<MobileInfo>, IEnumerable<MobileSolution>>()
.ConvertUsing<SolutionConverter>();
CreateMap<IEnumerable<MobileInfo>, IEnumerable<MobileUser>>()
.ConvertUsing<UserConverter>();
CreateMap<IEnumerable<MobileInfo>, MobileRoot>()
.ForMember(x => x.Users, opt => opt.MapFrom(x => x.ToList()));
}
}
class UserConverter : ITypeConverter<IEnumerable<MobileInfo>, IEnumerable<MobileUser>>
{
public IEnumerable<MobileUser> Convert(IEnumerable<MobileInfo> source, IEnumerable<MobileUser> destination, ResolutionContext context)
{
var groups = source.GroupBy(x => new { x.NameFull, x.EmailAddress});
foreach (var v in groups)
{
yield return new MobileUser()
{
EmailAddress = v.Key.EmailAddress,
NameFull = v.Key.NameFull,
Solutions = context.Mapper.Map<IEnumerable<MobileSolution>>(source.Where(x =>
v.Key.NameFull == x.NameFull && v.Key.EmailAddress== x.EmailAddress)).ToList()
};
}
}
}
class SolutionConverter : ITypeConverter<IEnumerable<MobileInfo>, IEnumerable<MobileSolution>>
{
public IEnumerable<MobileSolution> Convert(IEnumerable<MobileInfo> source, IEnumerable<MobileSolution> destination, ResolutionContext context)
{
var groups = source.GroupBy(x => new { x.SolutionName, x.SortOrder});
foreach (var v in groups)
{
yield return new MobileSolution()
{
Solution = v.Key.SolutionName,
SortOrder = v.Key.SortOrder,
Dashboards= context.Mapper.Map<IEnumerable<MobileDashboard>>(source.Where(x =>
v.Key.SolutionName== x.SolutionName&& v.Key.SortOrder== x.SortOrder)).ToList()
};
}
}
}
class DashboardConverter : ITypeConverter<IEnumerable<MobileInfo>, IEnumerable<MobileDashboard>>
{
public IEnumerable<MobileDashboard> Convert(IEnumerable<MobileInfo> source, IEnumerable<MobileDashboard> destination, ResolutionContext context)
{
var groups = source.GroupBy(x => new {x.Name, x.IsLegacy, x.Description});
foreach (var v in groups)
{
yield return new MobileDashboard()
{
Dashboard = v.Key.Name,
Description = v.Key.Description,
IsLegacy = v.Key.IsLegacy,
Widgets = context.Mapper.Map<IEnumerable<MobileWidget>>(source.Where(x =>
v.Key.IsLegacy == x.IsLegacy && v.Key.Name == x.Name && v.Key.Description == x.Description))
};
}
}
}
I have a collection property of DTO like this
public ICollection<Applicant> Applicants{get;set;}
Applicant Model
public class Applicant
{
public int Id{get;set;}
public string name{get;set;}
public ICollection<ApplicantSkillsVM> ApplicantSkills { get; set; }
}
public class ApplicantSkillsVM
{
public int Id {get;set;}
public Skill skill{get;set;}
}
I want to map my List<iApplicant> DTO to entity given that I want to take ApplicantSkillsVM but ignore skill inside ApplicantSkillsVM.
I have a model which is list List<Applicant> and that contains another list List<ApplicantSkillsVM> and ApplicantSkillsVM has a property skill. I want to ignore this (skill) while mapping. Its simple.
How can I do this in latest the AutoMapper version with EF6?
Here a running sample:
internal class Program
{
#region Methods
private static void Main(string[] args)
{
// Configure the mappings
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ApplicantSkillVM, ApplicantSkill>().ForMember(x => x.Skill, x => x.Ignore()).ReverseMap();
cfg.CreateMap<ApplicantVM, Applicant>().ReverseMap();
});
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
var mapper = config.CreateMapper();
ApplicantVM ap = new ApplicantVM
{
Name = "its me",
ApplicantSkills = new List<ApplicantSkillVM>
{
new ApplicantSkillVM {SomeInt = 10, SomeString = "test", Skill = new Skill {SomeInt = 20}},
new ApplicantSkillVM {SomeInt = 10, SomeString = "test"}
}
};
List<ApplicantVM> applicantVms = new List<ApplicantVM> {ap};
// Map
List<Applicant> apcants = Mapper.Map<List<ApplicantVM>, List<Applicant>>(applicantVms);
}
#endregion
}
/// Your source classes
public class Applicant
{
#region Properties
public List<ApplicantSkill> ApplicantSkills { get; set; }
public string Name { get; set; }
#endregion
}
public class ApplicantSkill
{
#region Properties
public Skill Skill { get; set; }
public int SomeInt { get; set; }
public string SomeString { get; set; }
#endregion
}
// Your VM classes
public class ApplicantVM
{
#region Properties
public List<ApplicantSkillVM> ApplicantSkills { get; set; }
public string Description { get; set; }
public string Name { get; set; }
#endregion
}
public class ApplicantSkillVM
{
#region Properties
public Skill Skill { get; set; }
public int SomeInt { get; set; }
public string SomeString { get; set; }
#endregion
}
public class Skill
{
#region Properties
public int SomeInt { get; set; }
#endregion
}
}
Initially my model ApplicantSkillsVM didnt have reference Id for Skill which should be nullable
So my model had to look like
public class ApplicantSkillsVM{
public int Id {get;set;}
public int? skillId{get;set;} //updated property
public Skill skill{get;set;}
}
The problem resolved
namespace ClassesRa.Classes
{
public class FicheLine
{
public int ItemRef { get; set; }
public double Amount { get; set; }
public string UnitCode { get; set; }
}
public class Fiche
{
public List<FicheLine> FicheLines { get; set; }
public Fiche()
{
FicheLines = new List<FicheLine>();
}
public string ClientCode { get; set; }
}
public class SalesFicheLine : FicheLine
{
public decimal Price { get; set; }
}
public class SalesFiche : Fiche
{
public List<SalesFicheLine> FicheLines { get; set; }
public SalesFiche()
{
FicheLines = new List<SalesFicheLine>();
}
public string PayCode { get; set; }
}
}
I want to derive SalesFiche from Fiche and add new members.
I want to derive SalesFicheLine from FicheLine and add new members.
I want to see SalesFicheLine in SalesFiche as FicheLine.
Is there a mistake or a defect in the above example?
namespace ClassesRa
{
public partial class fMain : Form
{
public fMain()
{
InitializeComponent();
}
private void fMain_Load(object sender, EventArgs e)
{
SalesFiche f = new SalesFiche();
f.ClientCode = "120.001";
f.PayCode = "30";
f.FicheLines.Add(new SalesFicheLine() { ItemRef = 1, Amount = 10, UnitCode = "PK", Price = 100 });
string xmlString = SerializeToString(f);
}
public string SerializeToString(object obj)
{
string str = "";
XmlSerializer serializer = new XmlSerializer(obj.GetType());
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, obj);
str = writer.ToString();
}
return str;
}
}
}
When I try to convert it to XML with the SerializeToString function, it gives the following error :
{"There was an error reflecting property 'FicheLines'."}
Thanks..
You have to rename the property "FicheLines" in your SalesFiche class. I tested it with "SalesFicheLines". This will fix the crash.
I also recommend that you change your SaleFiche class to this
public class SalesFiche : Fiche
{
public SalesFiche()
:base()
{
}
public string PayCode { get; set; }
}
You already have access to FicheLines's FicheLines property, so there's really no need to create another FicheLines property in SalesFiche.
How do you populate a list as a class object? For example, this does not work:
[DataContract]
public class JsonReviewFormFields
{
[DataMember]
public PersonalDevelopmentPlan personalDevelopmentPlan { get; set; }
}
public class PersonalDevelopmentPlan
{
public List<ShortTerm> shortTerm { get; set; }
public List<LongTerm> longTerm { get; set; }
}
public class ShortTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
public class LongTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
This is controller action:
public JsonReviewFormFields GetReviewForm()
{
PersonalDevelopmentPlan personalDevelopmentPlan = new PersonalDevelopmentPlan();
List<ShortTerm> _itemsShort = new List<ShortTerm>();
_itemsShort.Add(new ShortTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
List<LongTerm> _itemsLong = new List<LongTerm>();
_itemsLong.Add(new LongTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.longTerm = _itemsLong;
return jsonReviewFormFields;
}
The code crashes at
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
It's probably a basic object orientated error. How do you populate the list?
You are not instantiating it, you have to instantiated the type first:
jsonReviewFormFields.personalDevelopmentPlan = new PersonalDevelopmentPlan();
and then set property of it:
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort
before that you also have to instantiate main class which i don't see in your controller action anywhere :
JsonReviewFormFields jsonReviewFormFields = new JsonReviewFormFields();