I'm new to backend development, having some trouble mapping a viewmodel to dto that has a list.
Can you help me figure out whats wrong with the mapper. The result is coming in correct from the dto. I have a list of 7 items. When it maps to the view they are gone.
Here is the viewmodel
public class StatisticsViewModel : BaseViewModel
{
public string StartDate { get; set; }
public string EndDate { get; set; }
public string ProviderId { get; set; }
public List<StatisticsTotalsViewModel> Totals { get; set; } = new List<StatisticsTotalsViewModel>();
public List<StatisticsProvidersViewModel> Providers { get; set; } = new List<StatisticsProvidersViewModel>();
}
public class StatisticsTotalsViewModel
{
public string PayerName { get; set; }
public string PayerType { get; set; }
public short Status { get; set; }
public int TotalCount { get; set; }
public decimal TotalBalance { get; set; }
}
Heres the dto
public class StatisticsDto
{
public string StartDate { get; set; }
public string EndDate { get; set; }
public string ProviderId { get; set; }
public List<StatisticsTotalsDto> Totals { get; set; } = new List<StatisticsTotalsDto>();
public List<StatisticsProvidersDto> Providers { get; set; } = new List<StatisticsProvidersDto>();
}
public class StatisticsTotalsDto
{
public string PayerName { get; set; }
public string PayerType { get; set; }
public short Status { get; set; }
public int TotalCount { get; set; }
public decimal TotalBalance { get; set; }
}
Here's the mapper
public static StatisticsViewModel MapToView(StatisticsDto dto)
{
var viewmodel = new StatisticsViewModel();
viewmodel.StartDate = dto.StartDate;
viewmodel.EndDate = dto.EndDate;
viewmodel.ProviderId = dto.ProviderId;
var dtoTotals = new List<StatisticsTotalsDto>();
var totals = new List<StatisticsTotalsViewModel>();
foreach (var item in dtoTotals)
{
var totalsModel = new StatisticsTotalsViewModel();
item.PayerName = totalsModel.PayerName;
item.PayerType = totalsModel.PayerType;
item.Status = totalsModel.Status;
item.TotalBalance = totalsModel.TotalBalance;
item.TotalCount = totalsModel.TotalCount;
totals.Add(totalsModel);
}
viewmodel.Totals = totals;
return viewmodel;
}
Problem in this line. Instead
var dtoTotals = new List<StatisticsTotalsDto>();
You need to receive list of StatisticsTotalsDto, instead of create new empty list
var dtoTotals = dto.Totals;
You can try Automapper.
Say for example:
public static StatisticsViewModel MapToView(StatisticsDto dto)
{
Mapper.Initialize(cfg => cfg.CreateMap<StatisticsDto, StatisticsViewModel>());
var ViewModel = Mapper.Map<StatisticsViewModel>(dto);
return viewModel;
}
Take a look at here to know more about Automapper. You can also check here and here if you face problem mapping list items.
P.S Don't forget to include Automapper to your project and add using Automapper() at the top where you are using it
Related
I want to know which one performs faster
from JsonConvert.DeserializeObject or Custom model binding
for Example:
My ViewModel class:
public class AssessmentViewModel : BaseViewModel
{
public Guid AssessmentGUID { get; set; }
public string AssessmentCategory { get; set; }
public string AssessmentType { get; set; }
public string AssessmentName { get; set; }
public string AssessmentNameEnglish { get; set; }
public string AssessmentInstruction { get; set; }
public string AssessmentInstructionEnglish { get; set; }
public int? SequenceNum { get; set; }
public int? MaxScore { get; set; }
public bool? IsNegativeMarking { get; set; }
public decimal? NegativeRatio { get; set; }
public List<StringMapDDLViewModel> AssessmentCategoryDDList { get; set; }
public List<StringMapDDLViewModel> AssessmentTypeDDList { get; set; }
public List<FOFormSectionViewModel> FOFormSectionList { get; set; }
public List<StringMapDDLViewModel> FieldTypeList { get; set; }
public List<StringMapDDLViewModel> ValidationTypeList { get; set; }
}
I am calling Stored Procedure and it returns 100 thousands of data.
So my question is which will perform faster from below code:
Method 1: Serialize result then Deserialize it.
var assessmentList = db.AssessmentSP(Constant.ActionGetAll, null, status).ToList<AssessmentSP_Result>();
objALVM.AssessmentList = JsonConvert.DeserializeObject<List<AssessmentViewModel>>(JsonConvert.SerializeObject(assessmentList));
Method 2: One by one property binding
var assessmentList = db.AssessmentSP(Constant.ActionGetAll, null, status).ToList<AssessmentSP_Result>().ToList();
objALVM.AssessmentList = assessmentList.Select(x => new AssessmentViewModel()
{
AssessmentGUID = x.AssessmentGUID,
AssessmentType = x.AssessmentType,
AssessmentName = x.AssessmentName,
AssessmentNameEnglish = x.AssessmentNameEnglish,
AssessmentInstruction = x.AssessmentInstruction,
AssessmentInstructionEnglish = x.AssessmentInstructionEnglish,
SequenceNum = x.SequenceNum,
MaxScore = x.MaxScore,
IsNegativeMarking = x.IsNegativeMarking,
NegativeRatio = x.NegativeRatio,
}).ToList();
I am getting product data from our ERP through SQL queries whereby the returned data is very flat- at the Size level. A product has 3 levels:
Style
Colours
Sizes
A style has many colours and a colour has many sizes.
I have created the following models:
public class Ap21Style
{
public int StyleIdx;
public string StyleCode;
public IList<Ap21Clr> Clrs { get; set; } = new List<Ap21Clr>();
}
public class Ap21Clr
{
public int ClrIdx { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public IList<Ap21Sku> Skus { get; set; } = new List<Ap21Sku>();
}
public class Ap21Sku
{
public int SkuIdx { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string Barcode { get; set; }
}
My ProductResult looks like this:
public int StyleIdx { get; set; }
public int ClrIdx { get; set; }
public int SkuIdx { get; set; }
public string StyleCode { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public string Barcode { get; set; }
public string WebData { get; set; }
What would be an effective way to loop over the results and create the Ap21Style models whereby they are a composite object with Ap21Clr's, then at the row level, the Colours have Ap21Sku's?
Assuming something like this
List<ProductResult> products = GetPropducts();
Composing the styles would involve grouping the data by the composite keys
List<Ap21Style> results = products
.GroupBy(p => new { p.StyleIdx, p.StyleCode })
.Select(g => new Ap21Style {
StyleIdx = g.Key.StyleIdx,
StyleCode = g.Key.StyleCode,
Clrs = g.GroupBy(s => new {
s.ClrIdx,
s.ColourCode,
s.ColourName,
s.ColourTypeCode,
s.ColourTypeName
}).Select(g1 => new Ap21Clr {
ClrIdx = g1.Key.ClrIdx,
ColourCode = g1.Key.ColourCode,
ColourName = g1.Key.ColourName,
ColourTypeCode = g1.Key.ColourTypeCode,
ColourTypeName = g1.Key.ColourTypeName,
Skus = g1.Select(s => new Ap21Sku {
Barcode = s.Barcode,
SizeCode = s.SizeCode,
SizeSequence = s.SizeSequence,
SkuIdx = s.SkuIdx
}).ToList()
}).ToList()
}).ToList();
I'm trying to deserialize a Json String to a object but I only get 0 and null back.
Here is my code:
string result = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var serializer = new DataContractJsonSerializer(typeof(LandRootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (LandRootObject)serializer.ReadObject(ms);
public class LandRootObject
{
public int page { get; set; }
public int pages { get; set; }
public string per_page { get; set; }
public int total { get; set; }
[DataMember]
public List<Land> land { get; set; }
}
Thanks!
I have tested this method and it's working.
Your entity classes. (I did not code all these classes. They are code generated using paste special.)
public class LandRootObject
{
public int page { get; set; }
public int pages { get; set; }
public string per_page { get; set; }
public int total { get; set; }
}
public class LandBodyObject
{
public string id { get; set; }
public string iso2Code { get; set; }
public string name { get; set; }
public Region region { get; set; }
public Adminregion adminregion { get; set; }
public Incomelevel incomeLevel { get; set; }
public Lendingtype lendingType { get; set; }
public string capitalCity { get; set; }
public string longitude { get; set; }
public string latitude { get; set; }
}
public class Region
{
public string id { get; set; }
public string value { get; set; }
}
public class Adminregion
{
public string id { get; set; }
public string value { get; set; }
}
public class Incomelevel
{
public string id { get; set; }
public string value { get; set; }
}
public class Lendingtype
{
public string id { get; set; }
public string value { get; set; }
}
Then the deserialisation method. Your Json has two parts. So I am splitting it in to 2 for deserialisation.
string result = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var parts = result.Split(new[] {",["}, StringSplitOptions.None);
if (parts.Length > 1)
{
var header = parts[0].Replace("[", "");
var jsonHeader = JsonConvert.DeserializeObject<LandRootObject>(header);
var body = "[" + parts[1].Replace("]]","]");
var jsonBody = JsonConvert.DeserializeObject<List<LandBodyObject>>(body);
}
Use List type
var serializer = new DataContractJsonSerializer(typeof(List<LandRootObject>));
// ...
var data = (List<LandRootObject>)serializer.ReadObject(ms);
Edit:
Now I see - your json array consists of 2 different elements. I suppose its [RootObject, Lands]. You better use the Newtonsoft.Json to deserialize the object.
var str = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var arr = JArray.Parse(str);
var rootJson = arr.ElementAt(0).ToString();
var root = JsonConvert.DeserializeObject<LandRootObject>(rootJson);
var landsJson = arr.ElementAt(1).ToString();
root.Lands = JsonConvert.DeserializeObject<List<Land>>(landsJson);
tryto change the above code to following
ms.Position = 0; // change only this line
var data = (LandRootObject)serializer.ReadObject(ms);
I want to send a collection of two different Collections as a Json but in a sorted format. I am not able to do it with Linq. Need little help.And also is there any better way. Thank you!
Here is my action.
public ActionResult GetAllJobPosts()
{
var Institutes = new List<Institute>()
{
new Institute(){InstituteId="ins1",InstituteName="name1",Location="Mumbai"},
new Institute(){InstituteId="ins2",InstituteName="name2",Location="Navi Mumbai"},
new Institute(){InstituteId="ins3",InstituteName="name3",Location="Thiruvananthpuram"}
};
var Companys = new List<Company>()
{
new Company(){CompanyId="com1",CompanyName="comName1",Location="Mumbai"},
new Company(){CompanyId="com2",CompanyName="comName2",Location="Navi Mumbai"},
new Company(){CompanyId="com3",CompanyName="comName3",Location="Mumbai"}
};
var Organizations = new List<Organization>()
{
new Organization(){OrganizationId="org1",OrganizationName="orgName1",Location="Navi Mumbai"},
new Organization(){OrganizationId="org2",OrganizationName="orgName2",Location="Navi Mumbai"},
new Organization(){OrganizationId="org3",OrganizationName="orgName3",Location="Mumbai"},
};
var CompanyJobPosts = new List<CompanyJobPost>()
{
new CompanyJobPost(){CompanyId="com1",CompanyJobPostId="com1jp1",CreatedOn=System.DateTime.Now.AddDays(-2),JobDiscription="Tester",KeySkils="Sylanium"},
new CompanyJobPost(){CompanyId="com1",CompanyJobPostId="com1jp2",CreatedOn=System.DateTime.Now.AddDays(-3),JobDiscription="Developer",KeySkils="C#"},
new CompanyJobPost(){CompanyId="com2",CompanyJobPostId="com2jp1",CreatedOn=System.DateTime.Now.AddDays(-5),JobDiscription="Tester",KeySkils="Sylanium"},
new CompanyJobPost(){CompanyId="com2",CompanyJobPostId="com2jp2",CreatedOn=System.DateTime.Now.AddDays(-6),JobDiscription="Developer",KeySkils="C#"},
new CompanyJobPost(){CompanyId="com3",CompanyJobPostId="com3jp1",CreatedOn=System.DateTime.Now.AddDays(-7),JobDiscription="Tester",KeySkils="Sylanium"},
new CompanyJobPost(){CompanyId="com3",CompanyJobPostId="com3jp2",CreatedOn=System.DateTime.Now.AddDays(-8),JobDiscription="Developer",KeySkils="C#"}
};
var InstituteJobPosts = new List<InstituteJobPost>()
{
new InstituteJobPost(){InstituteId="ins1",InstituteJobPostId="ins1jp1",CreatedOn=System.DateTime.Now.AddDays(-1),JobDiscription="Trainer",KeySkils="C#",ExtraField="MDifferent"},
new InstituteJobPost(){InstituteId="ins1",InstituteJobPostId="ins1jp2",CreatedOn=System.DateTime.Now.AddDays(-8),JobDiscription="Developer",KeySkils="Java",ExtraField="MDifferent"},
new InstituteJobPost(){InstituteId="ins2",InstituteJobPostId="ins2jp1",CreatedOn=System.DateTime.Now.AddDays(-1),JobDiscription="Trainer",KeySkils="Java",ExtraField="MDifferent"},
new InstituteJobPost(){InstituteId="ins2",InstituteJobPostId="ins2jp2",CreatedOn=System.DateTime.Now.AddDays(-8),JobDiscription="Developer",KeySkils=".Net",ExtraField="MDifferent"},
new InstituteJobPost(){InstituteId="ins3",InstituteJobPostId="ins3jp1",CreatedOn=System.DateTime.Now.AddDays(-1),JobDiscription="Trainer",KeySkils="C#",ExtraField="MDifferent"},
new InstituteJobPost(){InstituteId="ins3",InstituteJobPostId="ins3jp2",CreatedOn=System.DateTime.Now.AddDays(-8),JobDiscription="Developer",KeySkils="Java",ExtraField="MDifferent"}
};
var allJobPosts=new List<object>();
foreach (var item in CompanyJobPosts)
{
allJobPosts.Add(new { JType = "Company", JobPost = item });
}
foreach (var item in InstituteJobPosts)
{
allJobPosts.Add(new { JType = "Institute", JobPost = item });
}
//var allJobPostsOrderdByDate=??
return Json(allJobPosts, JsonRequestBehavior.AllowGet);
}
Here are My Models just to make it simple.
namespace WebApplication1.Models
{
public class Company
{
public string CompanyId { get; set; }
public string CompanyName { get; set; }
public string Location { get; set; }
}
public class Organization
{
public string OrganizationId { get; set; }
public string OrganizationName { get; set; }
public string Location { get; set; }
}
public class Institute
{
public string InstituteId { get; set; }
public string InstituteName { get; set; }
public string Location { get; set; }
}
public class CompanyJobPost
{
public string CompanyJobPostId { get; set; }
public string CompanyId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
}
public class OrganizationJobPost
{
public string OrganizationJobPostId { get; set; }
public string OrganizationId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
public string ExtraField2 { get; set; }
}
public class InstituteJobPost
{
public string InstituteJobPostId { get; set; }
public string InstituteId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
public string ExtraField { get; set; }
}
}
And finally my sweet view
<input name="GetAllJobPosts" id="GetAllJobPosts" type="submit" value="Search Jobs">
<ul id="JobPostList"></ul>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$("#GetAllJobPosts").click(function () {
var actionUrl = '#Url.Action("GetAllJobPosts", "Default")';
$.getJSON(actionUrl, displayDetailData);
});
function displayDetailData(response) {
if (response != null) {
for (var i = 0; i < response.length; i++) {
$("#JobPostList").append("<li>" + response[i].JType + " " + (response[i].JobPost).CreatedOn + "</li>")
}
}
}
Thank You!
Based on your comments, I can only assume the following, so will do my best to point you in the correct direction:
You do not have a common object of inheritance between the two - that is, you wish to sort them on property x, but property x, is not defined to exist in both.
So, solution? Easy: add a common interface, class or abstract class between the two that has the property you wish to sort by, then sort by it:
public interface IJobPost
{
DateTime CreatedOn { get; set; }
}
Then modify your three existing objects:
public class CompanyJobPost : IJobPost
{
public string CompanyJobPostId { get; set; }
public string CompanyId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
}
public class OrganizationJobPost : IJobPost
{
public string OrganizationJobPostId { get; set; }
public string OrganizationId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
public string ExtraField2 { get; set; }
}
public class InstituteJobPost : IJobPost
{
public string InstituteJobPostId { get; set; }
public string InstituteId { get; set; }
public string KeySkils { get; set; }
public string JobDiscription { get; set; }
public DateTime CreatedOn { get; set; }
public string ExtraField { get; set; }
}
Lastly, the action:
var allJobPosts=new List<IJobPost>();
// Add other posts to allJobPosts here.
var allJobPostsOrderdByDate = allJobPosts.OrderBy(x => x.CreatedOn).ToList();
Note: Code is untested. LINQ query may or may not work. Did this all from memory.
Edit: You can also share any other properties you wish to force between the three of them. That is what an interface or abstract class is for. That also means you can share Description or other properties.
I cannot seem to work out how to populate a sub class...
These are the classes I have:
public class Item
{
public Meta meta { get; set; }
public Items[] objects { get; set; }
}
public class Meta
{
public int limit { get; set; }
public object next { get; set; }
public int offset { get; set; }
public object previous { get; set; }
public int total_count { get; set; }
}
public class Items
{
public Additionalprices additionalPrices { get; set; }
public string barcode { get; set; }
public Category category { get; set; }
public int categoryPosition { get; set; }
public string cdate { get; set; }
public DateTime ctime { get; set; }
public DateTime ctimeOnServer { get; set; }
public Dimensions dimensions { get; set; }
public string entityType { get; set; }
public object imageURL { get; set; }
public object[] imageURLs { get; set; }
public string longDesc { get; set; }
public string manufacturer { get; set; }
public int minQty { get; set; }
public DateTime mtime { get; set; }
public DateTime mtimeOnServer { get; set; }
public int multQty { get; set; }
public string name { get; set; }
public int objID { get; set; }
public string owner { get; set; }
public string resource_uri { get; set; }
public string sku { get; set; }
public object thumbnailURL { get; set; }
public object[] thumbnailURLs { get; set; }
public string unitPrice { get; set; }
public string uuid { get; set; }
public Variant[] variants { get; set; }
}
I want to add some dummy objects...
This is the code I have...
// Create a dummy Category
HandShake_Classes.Category categoryToUpload = new HandShake_Classes.Category();
categoryToUpload.name = "Trev Category";
// Create a dummy Item
HandShake_Classes.Item itemToUpload = new HandShake_Classes.Item();
// THIS IS WHERE MY PROBLEM IS...
itemToUpload.objects = new HandShake_Classes.Items();
// THE ERROR I AM GETTING IS Error 2 Cannot implicitly convert type 'handshake.com.HandShake_Classes.Items' to 'handshake.com.HandShake_Classes.Items[]'
// Only populate required fields at the moment
itemToUpload.objects[0].sku = "ljklj";
itemToUpload.objects[0].name = "Trevs Product";
itemToUpload.objects[0].unitPrice = "1.23";
itemToUpload.objects[0].minQty = 1;
itemToUpload.objects[0].category = categoryToUpload;
I just cannot work out how define the Items[] I think
Can anyone point me in the right direction please?
Thanks
You have to initialize the array first. Let's say you need 10 items:
itemToUpload.objects = new HandShake_Classes.Items[10];
And then you can set every array item to the new Items() instance:
itemToUpload.objects[0] = new HandShake_Classes.Items();
itemToUpload.objects[0].sku = "ljklj";
itemToUpload.objects[0].name = "Trevs Product";
itemToUpload.objects[0].unitPrice = "1.23";
itemToUpload.objects[0].minQty = 1;
itemToUpload.objects[0].category = categoryToUpload;
And just to make it clear: if you don't know how many items object property will have to handle, you should consider changing it to List<Items> instead of Items[] array:
itemToUpload.objects = new List<HandShake_Classes.Items>();
var newItem = new HandShake_Classes.Items();
newItem = new HandShake_Classes.Items();
newItem.sku = "ljklj";
newItem.name = "Trevs Product";
newItem.unitPrice = "1.23";
newItem.minQty = 1;
newItem.category = categoryToUpload;
itemToUpload.objects.Add(newItem);
Instantiate the array of type items as
itemToUpload.objects = new HandShake_Classes.Items[10];
After this instantiation, you would require to instantiate every index of the object.
For example
itemToUpload.objects[i] = new HandShake_Classes.Items();
This means you are instantiating a single object, and that object would be in array at index 'i'.
you can then set the properties of the Items in objects array by writing as
itemToUpload.objects[i].barcode
even call the functions
itemToUpload.objects[i].CalculateTax()
similarly you can use any constructors if defined.