I have the following method which is used to retrieve all values as strings from an object using reflection. The object can have IEnumerables within them and I also want to retrieve these values. A list of ignore fields also needs to be taken into account so that those field's values are not returned.
public static IEnumerable<string> StringContent(this object obj, IEnumerable<string> ignoreProperties = null)
{
Type t = obj.GetType();
foreach (var prop in t.GetProperties())
{
if (ignoreProperties != null && ignoreProperties.Contains(field.Name))
{
continue;
}
var value = prop.GetValue(obj);
if (value != null)
{
if (value is IEnumerable<object>)
{
foreach (var item in (IEnumerable<object>)value)
{
foreach (var subValue in item.StringContent())
{
yield return subValue.ToString();
}
}
}
else
{
yield return value.ToString();
}
}
}
}
This method does work perfectly and gives me the correct result. However, I need to speed it up as much as possible because this is performed a lot of times.
Does anybody have any suggestions?
Thanks in advance!
** EDIT **
Example Test Case:
[TestMethod]
public void StringContent()
{
Project project = projectA;
List<string> ignoreFields = new List<string>() { "SalesEngineer", "CreationDate" };
var result = project.StringContent(ignoreFields);
Assert.IsTrue(result.Count() == 26);
}
Project Object:
public class Project : IEntity
{
public Project()
{
Products = new List<ProjectProducts>();
}
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public string SalesEngineer { get; set; }
public string SalesEngineerEmail { get; set; }
public int? TeamId { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Originator { get; set; }
public string ContactName { get; set; }
public string MainClient { get; set; }
public string Contractor { get; set; }
public string ContractorContactName { get; set; }
public string ContractorLocation { get; set; }
public string Wholesaler { get; set; }
public string WholesalerContactName { get; set; }
public string WholesalerLocation { get; set; }
public float EstimatedValue { get; set; }
public float CalculatedValue {
get { return EstimatedValue/Convert.ToSingle(Currency != null ? Currency.Rate : (decimal)1.0); }
}
public int Probability { get; set; }
public int SectorId { get; set; }
public int TypeId { get; set; }
public string StatusCode { get; set; }
public string LostTo { get; set; }
public int ReasonId { get; set; }
public string SecondaryEngineer { get; set; }
public float SplitPercentage { get; set; }
public DateTime ExpectedOrder { get; set; }
public DateTime? RequiredOnSiteBy { get; set; }
public bool LightingDesignRequired { get; set; }
public string ReasonForLightingDesign { get; set; }
public DateTime? DesignRequiredBy { get; set; }
public DateTime? FollowUp { get; set; }
public string Comments { get; set; }
public int CurrencyId { get; set; }
public bool Void { get; set; }
public string AttachmentFolder { get; set; }
public virtual Currency Currency { get; set; }
public virtual Reason Reason { get; set; }
public virtual ProjectStatus Status { get; set; }
public virtual ProjectType Type { get; set; }
public virtual Sector Sector { get; set; }
public virtual ICollection<ProjectProducts> Products { get; set; }
public virtual Team Team { get; set; }
public object Key
{
get { return Id; }
}
}
You can use stringify package.
It exists in Nuget.
You can Hide parameters with Hidden attribute.
You can print every object with a.stringify();
Related
I am use api use variable date whene date change the object name change like this if i have to get data of this day i use this :https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us
and the result of json object is like this :
and if i have to choose other date i change the date and the variable of date object is change like this if i have to get data of 2020-10-11 ,i calll this:
https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us , and this is image show the result and the change of object date
the problem is if i deserialize the api i get result from , metadata object ,total object , updated_at , and dates object and the other object date and countries give me this error
:NullReferenceException: Object reference not set to an instance of an object
I use https://json2csharp.com/ to get class from json and this is my code :
var client = new RestClient("https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
// request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
Root response = client.Execute<Root>(request)?.Data;
var paystoday_confirmed = response?.dates.date.countries.US.today_confirmed;
if (paystoday_confirmed != null)
{
Debug.Log("Confirmed :" + paystoday_confirmed);
}
and this is my object's
public class Link
{
public string href { get; set; }
public string rel { get; set; }
public string type { get; set; }
}
public class Link2
{
public string href { get; set; }
public string rel { get; set; }
public string type { get; set; }
}
public class SubRegion
{
public string date { get; set; }
public string id { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_recovered { get; set; }
public int today_recovered { get; set; }
public double? today_vs_yesterday_confirmed { get; set; }
public double? today_vs_yesterday_deaths { get; set; }
public object today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_recovered { get; set; }
}
public class Region
{
public string date { get; set; }
public string id { get; set; }
public List<Link2> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string source { get; set; }
public List<SubRegion> sub_regions { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_new_tests { get; set; }
public int today_new_total_hospitalised_patients { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public int today_tests { get; set; }
public int today_total_hospitalised_patients { get; set; }
public double? today_vs_yesterday_confirmed { get; set; }
public double? today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double? today_vs_yesterday_recovered { get; set; }
public double today_vs_yesterday_tests { get; set; }
public double? today_vs_yesterday_total_hospitalised_patients { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
public int yesterday_tests { get; set; }
public int yesterday_total_hospitalised_patients { get; set; }
}
public class US
{
public string date { get; set; }
public string id { get; set; }
public List<Link> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public List<Region> regions { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
public class Countries
{
public US US { get; set; }
}
public class Info
{
public string date { get; set; }
public string date_generation { get; set; }
public string yesterday { get; set; }
}
public class _20201102
{
public Countries countries { get; set; }
public Info info { get; set; }
}
public class Dates
{
[JsonProperty("2020-11-02")]
public _20201102 date { get; set; }
}
public class Metadata
{
public string by { get; set; }
public List<string> url { get; set; }
}
public class Total
{
public string date { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string rid { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
public class Root
{
public Dates dates { get; set; }
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
And this is the error on unity
It will work best if you use dictionaries.
You can make your dates and countries property a dictionary.
dates - Dates needs to be a dictionary because you can get data for different dates so the date will change
countries - The service u are using support other countries. If you change the countries to a dictionary, then the structure below should work for any country, not just for US.
Your code structure will then look something like this:
public class Root
{
public Dictionary<string, Date> dates {get;set;}
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
public class Date
{
public Dictionary<string, Country> countries {get;set;}
public Info info {get;set;}
}
public class Country
{
....
//Country properties here
}
public class Info
{
....
//Info properties here
}
public class Metadata
{
....
//Metadata properties here
}
public class Total
{
....
//Total properties here
}
you should then be able to process the data as follow
foreach(var kvp in root.dates)
{
// the key will be the date eg. '2020-11-05'.
// This you can convert to a date using DateTime.Parse() if you need too.
Console.WriteLine(kvp.Key);
// The value will be the Date object
var dateObj = kvp.Value;
var info = dateObj.info;
foreach(var kvp2 in dateObj.countries)
{
Console.WriteLine(kvp2.Key); // this will be the country eg. 'US'
var countryDetails = kvp2.Value // this will be the Country object
}
}
Or just change your code too:
(note: you will need to know exactly what date was returned)
var paystoday_confirmed = response?.dates["2020-11-05"].countries["US"].today_confirmed;
if (paystoday_confirmed != null)
{
Debug.Log("Confirmed :" + paystoday_confirmed);
}
As already stated in the Comments your main issue here is that you hardcoded
public class Dates
{
[JsonProperty("2020-11-02")]
public _20201102 date { get; set; }
}
But as you can see in your second result the date simply is not 2020-11-02 but rather 2020-10-11!
Therefore in this case there is no object in the json representing the data object => It will be the default reference value null.
So how to solve this?
You could instead use a Dictionary .. however it depends a lot on how your JSON library works. I know that at least with JSON .Net the following should work
public class Root
{
public Dictionary<string, Date> dates { get; set; }
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
public class Date
{
public Dictionary<string, Country> countries { get; set; }
public Info info { get; set; }
}
public class Country
{
public string date { get; set; }
public string id { get; set; }
public List<Link> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public List<Region> regions { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
This also sounds more logic since dates indicates that there might be more then one item. And also countries sounds like there might not only be US but also other countries, maybe even multiple entries.
You would then access that e.g. like
foreach(var date in response.dates)
{
foreach(var country in date.value)
{
var paystoday_confirmed = country.value.today_confirmed;
Debug.Log($"Confirmed {paystoday_confirmed} cases for the {date.key} in {country.key}");
}
}
As complete alternative in the case you only need one certain field of your request anyway you could also use SimpleJson (simply copy the provided scripts somewhere into your project) and access them like
var root = JSON.Parse(theJsonString);
var paystoday_confirmed = root["Dates"]["2020-11-05"]["countries"]["US"]["today_confirmed"].AsInt();
For both solutions you will have to get rid of that RestClient package and rather do the UnityWebRequest.Get yourself and use the returned string instead.
i'm using this api: https://store.steampowered.com/api/appdetails?appids=847370 that returns a json object and i've created a model to deserialize it.
But there's an difference on json, if the game has mac or linux requirements, then it returns an { } object, but if it don't have, then it return an [ ].
So my problem is, i've created a model using json2charp.com and deserialized many requests, but if it don't have mac or linux requirements, then the json throws error on deserialize.
My Model:
public class RootObject : Dictionary<string, AppRoot>
{
}
public class AppRoot
{
public bool success { get; set; }
public Data data { get; set; }
}
public class PcRequirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class MacRequirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class LinuxRequirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class PriceOverview
{
public string currency { get; set; }
public int initial { get; set; }
public int final { get; set; }
public int discount_percent { get; set; }
public string initial_formatted { get; set; }
public string final_formatted { get; set; }
}
public class Sub
{
public int packageid { get; set; }
public string percent_savings_text { get; set; }
public int percent_savings { get; set; }
public string option_text { get; set; }
public string option_description { get; set; }
public string can_get_free_license { get; set; }
public bool is_free_license { get; set; }
public int price_in_cents_with_discount { get; set; }
}
public class PackageGroup
{
public string name { get; set; }
public string title { get; set; }
public string description { get; set; }
public string selection_text { get; set; }
public string save_text { get; set; }
public int display_type { get; set; }
public string is_recurring_subscription { get; set; }
public List<Sub> subs { get; set; }
}
public class Platforms
{
public bool windows { get; set; }
public bool mac { get; set; }
public bool linux { get; set; }
}
public class Metacritic
{
public int score { get; set; }
public string url { get; set; }
}
public class Category
{
public int id { get; set; }
public string description { get; set; }
}
public class Genre
{
public string id { get; set; }
public string description { get; set; }
}
public class Screenshot
{
public int id { get; set; }
public string path_thumbnail { get; set; }
public string path_full { get; set; }
}
public class Webm
{
public string __invalid_name__480 { get; set; }
public string max { get; set; }
}
public class Movie
{
public int id { get; set; }
public string name { get; set; }
public string thumbnail { get; set; }
public Webm webm { get; set; }
public bool highlight { get; set; }
}
public class Recommendations
{
public int total { get; set; }
}
public class Highlighted
{
public string name { get; set; }
public string path { get; set; }
}
public class Achievements
{
public int total { get; set; }
public List<Highlighted> highlighted { get; set; }
}
public class ReleaseDate
{
public bool coming_soon { get; set; }
public string date { get; set; }
}
public class SupportInfo
{
public string url { get; set; }
public string email { get; set; }
}
public class ContentDescriptors
{
public List<int> ids { get; set; }
public string notes { get; set; }
}
public class Data
{
public string type { get; set; }
public string name { get; set; }
public int steam_appid { get; set; }
public string required_age { get; set; }
public bool is_free { get; set; }
public string controller_support { get; set; }
public string detailed_description { get; set; }
public string about_the_game { get; set; }
public string short_description { get; set; }
public string supported_languages { get; set; }
public string header_image { get; set; }
public string website { get; set; }
public PcRequirements pc_requirements { get; set; }
public MacRequirements mac_requirements { get; set; }
public LinuxRequirements linux_requirements { get; set; }
public string legal_notice { get; set; }
public List<string> developers { get; set; }
public List<string> publishers { get; set; }
public PriceOverview price_overview { get; set; }
public List<int> packages { get; set; }
public List<PackageGroup> package_groups { get; set; }
public Platforms platforms { get; set; }
public Metacritic metacritic { get; set; }
public List<Category> categories { get; set; }
public List<Genre> genres { get; set; }
public List<Screenshot> screenshots { get; set; }
public List<Movie> movies { get; set; }
public Recommendations recommendations { get; set; }
public Achievements achievements { get; set; }
public ReleaseDate release_date { get; set; }
public SupportInfo support_info { get; set; }
public string background { get; set; }
public ContentDescriptors content_descriptors { get; set; }
}
Can't include json sample here, the limit will be reached, sorry. Just open it on browser, it works.
JSON With Mac Requirements (That work with my model)
https://store.steampowered.com/api/appdetails?appids=847370
JSON Without MAC Requirements (Throws error, can't deserialize on my custom model)
https://store.steampowered.com/api/appdetails?appids=731490
Is there a way to create a unique model to support these different requests? or configure deserialize?
What you'll need in this situation, since you're dealing with a non-standard API that should be returning null rather than an empty array, is a custom JsonConverter.
I've created a proof-of-concept that should work in your situation:
public class NullValueArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.Read(); //Advances to the next character so that the ArrayClose token is ignored.
return null;
}
return serializer.Deserialize(reader, objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
Then you just need to decorate the properties in your model accordingly:
public class Data
{
//...
[JsonConverter(typeof(NullValueArrayConverter))]
public PcRequirements pc_requirements { get; set; }
[JsonConverter(typeof(NullValueArrayConverter))]
public MacRequirements mac_requirements { get; set; }
[JsonConverter(typeof(NullValueArrayConverter))]
public LinuxRequirements linux_requirements { get; set; }
//...
}
I am creating ViewModels for my entities. The FirmViewModel contains two list collections called Addressess and Websites. I have also created viewmodels for Addresses and Websites. At the moment in the controller code, I am getting trouble assigning Addresses and Wesbite collections
of the Firm Entity to FirmViewModels Addresses and Websites collection. Its says cant cast it implicitly. This is the line in the controller that it complains Addresses = firm.Addresses; How do aassign
Systems.Collections.Generic.ICollection<Manager.Model.Address> to Systems.Collections.Generic.ICollection<Manager.WebUI.ViewModels.AddressViewModel>
NewFirmViewModel
public class NewFirmViewModel
{
public int FirmId { get; set; }
public string FirmName { get; set;}
public Nullable<DateTime> DateFounded { get; set; }
public ICollection<AddressViewModel> Addresses { get; set; }
public ICollection<WebsiteViewModel> Websites { get; set; }
public bool hasIntralinks { get; set; }
}
AddressViewModel
public class AddressViewModel
{
public int AddressId { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public string Phone { get; set; }
public bool IsHeadOffice { get; set; }
public int FirmId { get; set; }
}
WebsiteViewModel
public class WebsiteViewModel
{
private int FirmWebsiteId { get; set; }
private string WebsiteUrl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public int FirmId { get; set; }
}
Entities - Firm
public class FIRM: Entity,IHasAUMs<FIRM_AUM>
{
public FIRM()
{
//this.FIRM_PERSON = new HashSet<FIRM_PERSON>();
this.MANAGERSTRATEGies = new HashSet<MANAGERSTRATEGY>();
this.FIRM_ACTIVITY = new HashSet<FIRM_ACTIVITY>();
this.FIRM_AUMs = new HashSet<FIRM_AUM>();
this.FIRM_REGISTRATION = new HashSet<FIRM_REGISTRATION>();
//this.ACTIVITies = new HashSet<ACTIVITY>();
Addresses = new HashSet<ADDRESS>();
//People = new HashSet<PERSON>();
// Websites = new HashSet<FIRM_WEBSITE>();
}
//public decimal ID { get; set; }
//
//
//
//
public string NAME { get; set; }
public string SHORT_NAME { get; set; }
public string ALTERNATE_NAME { get; set; }
public string WEBSITE { get; set; }
public string WEBSITE_USERNAME { get; set; }
public string WEBSITE_PASSWORD { get; set; }
public bool? INTRALINKS_FIRM { get; set; }
public string NOTES_TEXT { get; set; }
public string NOTES_HTML { get; set; }
public string HISTORY_TEXT { get; set; }
public string HISTORY_HTML { get; set; }
public string HISTORY_SUM_TEXT { get; set; }
public string HISTORY_SUM_HTML { get; set; }
public Nullable<decimal> OLD_ORG_REF { get; set; }
public Nullable<decimal> SOURCE_ID { get; set; }
[DisplayFormat(DataFormatString = PermalConstants.DateFormat)]
public Nullable<DateTime> DATE_FOUNDED { get; set; }
public virtual ICollection<ADDRESS> Addresses { get; set; }
// public ICollection<FIRM_WEBSITE> Websites { get; set; }
// public ICollection<PERSON> People { get; set; }
//public SOURCE SOURCE { get; set; }
// public ICollection<FIRM_PERSON> FIRM_PERSON { get; set; }
public ICollection<MANAGERSTRATEGY> MANAGERSTRATEGies { get; set; }
public ICollection<FIRM_ACTIVITY> FIRM_ACTIVITY { get; set; }
public ICollection<FIRM_REGISTRATION> FIRM_REGISTRATION { get; set; }
//public ICollection<ACTIVITY> ACTIVITies { get; set; }
public ICollection<FIRM_WEBSITE> Websites { get; set; }
public Nullable<int> KEY_CONTACT_ID { get; set; }
[NotMapped]
public ICollection<FIRM_AUM> AUMs
{
get
{
return this.FIRM_AUMs;
}
}
public ICollection<FIRM_AUM> FIRM_AUMs { get; set; }
}
ADDRESS
public class ADDRESS : Entity
{
public ADDRESS()
{
// DATE_CREATED = DateTime.Now;
}
public string LINE1 { get; set; }
public string LINE2 { get; set; }
public string LINE3 { get; set; }
public int CITY_ID { get; set; }
public string POSTAL_CODE { get; set; }
public string SWITCHBOARD_INT { get; set; }
public string NOTES { get; set; }
public int? OLD_ADDRESS_REF { get; set; }
public int? SOURCE_ID { get; set; }
public int FIRM_ID { get; set; }
[ForeignKey("FIRM_ID")]
public FIRM FIRM { get; set; }
[ForeignKey("CITY_ID")]
public CITY City { get; set; }
public ICollection<PERSON> People { get; set; }
// public SOURCE SOURCE { get; set; }
public bool IS_HEAD_OFFICE { get; set; }
[NotMapped]
public string AddressBlurb
{
get
{
return string.Join(",", new[] { LINE1, LINE2, City != null ? City.NAME : "", City != null && City.Country != null ? City.Country.NAME : "" }.Where(x => !string.IsNullOrEmpty(x)));
}
}
}
FIRM_WEBSITE
public class FIRM_WEBSITE : Entity
{
public FIRM_WEBSITE()
{
}
private string _WEBSITE_URL;
public string WEBSITE_URL
{
get
{
if (string.IsNullOrEmpty(_WEBSITE_URL))
return _WEBSITE_URL;
try
{
var ubuilder = new System.UriBuilder(_WEBSITE_URL ?? "");
return ubuilder.Uri.AbsoluteUri;
}
catch (UriFormatException ex)
{
return _WEBSITE_URL;
}
}
set { _WEBSITE_URL = value; }
}
public string USERNAME { get; set; }
public string PASSWORD { get; set; }
public int FIRM_ID { get; set; }
[ForeignKey("FIRM_ID")]
public FIRM FIRM { get; set; }
}
FirmController
public class FirmController : ApiControllerBase
{
[HttpGet]
[Route("api/Firm/{id}")]
public IHttpActionResult Details(int id)
{
var viewModel = GetFirmViewModel(id);
return Ok(viewModel);
}
private NewFirmViewModel GetFirmViewModel(int id)
{
var firmSvc = GetService<FIRM>();
var firm = firmSvc.GetWithIncludes(id, f => f.Addresses, f => f.Websites);
var firmVm = new NewFirmViewModel()
{
FirmId = firm.ID,
FirmName = firm.NAME,
DateFounded = firm.DATE_FOUNDED,
Addresses = firm.Addresses;
};
}
public virtual T GetWithIncludes(int id, params Expression<Func<T, object>>[] paths)
{
try
{
using (new TimedLogger(_perfLogger, GetCompletedText("GetWithIncludes"), typeof(T).Name))
{
return Authorize(_repo.GetWithIncludes(id, paths), AuthAccessLevel.Read);
}
}
catch (Exception ex) { Log(ex); throw; }
}
I have a table in my view that a model is typed to it. However, now I need to change that model to a ViewModel (so I can Union other models on to it but one step at a time). Currently, I query my model (which works) but now I need to figure out how to convert that IEnumerable to bind it to the ViewModel (in this case, it is searchResultViewModel). I gathered what i would need to loop through each line in the IEnumerable and bind it individually (that is what the foreach loop is, me trying that) but I need to convert it back in to an 'IEnumerable'. How do I bind the IEnumerable to my ViewModel but as an 'IEnumerable'? I cannot find anyone else asking a question like this.
[HttpPost]
public ActionResult SearchResult(SearchOrders searchOrders)
{
var orderList = uni.Orders;
var model = from order in orderList
select order;
if (searchOrders.SearchStartDate.HasValue)
{
model = model.Where(o => o.OrderDate >= searchOrders.SearchStartDate);
}
if (searchOrders.SearchEndDate.HasValue)
{
model = model.Where(o => o.OrderDate <= searchOrders.SearchEndDate);
}
if (searchOrders.SearchAmount.HasValue)
{
model = model.Where(o => o.Total == searchOrders.SearchAmount);
}
var searchResultViewModel = new SearchResultViewModel();
foreach (var record in model)
{
searchResultViewModel.OrderNumber = record.OrderId;
searchResultViewModel.PaymentName = record.PaymentFullName;
searchResultViewModel.OrderDate = record.OrderDate;
searchResultViewModel.Amount = record.Total;
}
return View(model);
}
Here is my SearchOrders Model:
namespace MicrositeInfo.WebUI.Models
{
public class SearchOrders
{
public DateTime? SearchStartDate { get; set; }
public DateTime? SearchEndDate { get; set; }
public decimal? SearchAmount { get; set; }
}
}
and here is my SearchResultViewModel:
namespace MicrositeInfo.WebUI.Models
{
public class SearchResultViewModel
{
public int OrderNumber { get; set; }
public string PaymentName { get; set; }
public DateTime OrderDate { get; set; }
public decimal Amount { get; set; }
}
}
and the model that is being queried is the order model:
namespace MicrositeInfo.Model
{
[Table("Order")]
public class Order
{
public int OrderId { get; set; }
public string SelectedSession { get; set; }
public string StudentCity { get; set; }
public string StudentExtension { get; set; }
public string StudentFullName { get; set; }
public string StudentPhone { get; set; }
public string StudentPin { get; set; }
public string StudentState { get; set; }
public string StudentStreet01 { get; set; }
public string StudentStreet02 { get; set; }
public string StudentUniversityId { get; set; }
public string StudentZip { get; set; }
public string PaymentCity { get; set; }
public string PaymentCreditCardExpiration { get; set; }
public string PaymentCreditCardNumber { get; set; }
public string PaymentCreditCardSecurityCode { get; set; }
[Display(Name="Payment Name")]
public string PaymentFullName { get; set; }
public string PaymentState { get; set; }
public string PaymentStreet01 { get; set; }
public string PaymentStreet02 { get; set; }
public string PaymentZip { get; set; }
[Display(Name = "Package Id")]
[ForeignKey("Product")]
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public decimal Price { get; set; }
public decimal Tax { get; set; }
public decimal Total { get; set; }
[Display(Name = "Order Date")]
public DateTime OrderDate { get; set; }
public string OrderIp { get; set; }
public string StudentEmail { get; set; }
public string PaymentId { get; set; }
public int Status { get; set; }
public string ApprovalCode { get; set; }
public decimal Shipping { get; set; }
public string STCITrackingClassCode { get; set; }
}
}
public static List<IndianAppStore_GetAllAppsByLanguage_ResultCache> GetAllApps(bool initialized, string language)
{
List<IndianAppStore_GetAllAppsByLanguage_ResultCache> objApp = new List<IndianAppStore_GetAllAppsByLanguage_ResultCache>();
List<IndianAppStore_GetAllAppsByLanguage_Result> objApps = new List<IndianAppStore_GetAllAppsByLanguage_Result>();
if (initialized == false)
{
var t = ListCopy(objApps, x => (IndianAppStore_GetAllAppsByLanguage_ResultCache)x); // Error
objApp = admin.getAllAppsByLanguage(language).ToList();
}
else
{
}
}
public static List<TResult> ListCopy<TSource, TResult>(List<TSource> input, Func<TSource, TResult> convertFunction)
{
return input.Select(x => convertFunction(x)).ToList();
}
My Class
public class IndianAppStore_GetAllAppsByLanguage_ResultCache
{
public long AppId { get; set; }
public string AppName { get; set; }
public string AppDisplayName { get; set; }
public string AppDetails { get; set; }
public string AppImageURL { get; set; }
public byte[] AppImageData { get; set; }
public long CategoryId { get; set; }
public Nullable<long> SubCategoryId { get; set; }
public string AppCreatedBy { get; set; }
public System.DateTime AppCreatedOn { get; set; }
public string AppModifiedBy { get; set; }
public Nullable<System.DateTime> AppModifiedOn { get; set; }
public Nullable<bool> isDeleted { get; set; }
public Nullable<bool> isPromotional { get; set; }
public string GenderTarget { get; set; }
public Nullable<long> CountryId { get; set; }
public Nullable<long> StateId { get; set; }
public Nullable<long> AgeLimitId { get; set; }
public Nullable<int> AppMinAge { get; set; }
public Nullable<int> AppMaxAge { get; set; }
}
I am trying to convert one generic class to another but getting this error
IndianAppStore_GetAllAppsByLanguage_Result and IndianAppStore_GetAllAppsByLanguage_ResultCache are different types and you cannot cast the first type to the other as you are doing in this statement:
var t = ListCopy(objApps, x => (IndianAppStore_GetAllAppsByLanguage_ResultCache)x);
If the types have the same structure you should probably just have one instead of two types. Otherwise you will have to copy the data from the first type to the other. E.g.:
var t = ListCopy(objApps, x => new IndianAppStore_GetAllAppsByLanguage_ResultCache {
AppId = x.AppId,
AppName = x.AppName,
...
});
This becomes tedious very quickly and one option is to use a library like AutoMapper to automate the process.