I am having the below model class CallbackResponse.cs :
public class CallbackResponse
{
public Callback Data { get; set; }
}
public class Callback
{
public IEnumerable<ReviewInProgressActivityFeed> ActivitiesFeed { get; set; }
}
public class ReviewInProgressActivityFeed
{
public ReviewInProgressStatus ReviewerSession { get; set; }
}
public class ReviewInProgressStatus
{
public Guid ReviewActivityId { get; set; }
public string ReviewerName { get; set; }
public string ReviewComments { get; set; }
public DateTime ActivityDateTime { get; set; }
}
Sample Payload:
{
"data":
{
"activitiesFeed": [
{
"reviewerSession":
{
"reviewActivityId": "dd9937c3-7c01-4a4a-bc8d-05ef37b07ee5",
"ReviewerName": "Verification Team",
"reviewComments": "upload business verification document for further verification.",
"activityDateTime": "2021-03-31T18:34:26.5978962Z"
},
},
{
"reviewerSession":
{
"reviewActivityId": "dd9937c3-7c01-4a4a-bc8d-05ef37b07ee5",
"ReviewerName": "Other Team",
"reviewComments": "other documents required for verification.",
"activityDateTime": "2021-03-31T19:34:26.5978962Z"
},
}
]
}
}
I am trying to get the data from DB via the CallbackResponse model class. Please find the code for below.
public async Task<CallbackResponse> CallbackActivityFeedAsync(Guid Id)
{
CallbackResponse containerItems = new CallbackResponse();
IQueryable<HumanReviewRequest> query = cosmosReviewRequestContainer.GetItemLinqQueryable<HumanReviewRequest>(true);
query = query.Where(x => x.id == Id);
FeedIterator<HumanReviewRequest> feedIterator = query.ToFeedIterator();
while (feedIterator.HasMoreResults)
{
FeedResponse<HumanReviewRequest> r = await feedIterator.ReadNextAsync().ConfigureAwait(false);
foreach (HumanReviewRequest requestModel in r)
{
containerItems = new CallbackResponse
{
Data = new Callback
{
ActivitiesFeed = new List<ReviewInProgressActivityFeed>
{
new ReviewInProgressActivityFeed
{
ReviewerSession = new ReviewInProgressStatus
{
ReviewActivityId = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewActivityId).LastOrDefault(),
ActivityDateTime = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ActivityDateTime).LastOrDefault(),
ReviewComments = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewerComments).LastOrDefault(),
ReviewerName = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewerName).LastOrDefault()
}
}
}
}
};
}
}
return containerItems;
}
The Problem here is I could not able to fetch all the records present in activitiesFeed array in DB. Instead I could only able to fetch the last record in that array(I am using Azure Cosmos DB). Please help me in this.
HumanReviewRequest.cs (which is DB Class)for reference:
public class HumanReviewRequest
{
public Guid Id { get; set; }
public IEnumerable<ReviewActivity> ReviewActivities { get; set; }
public class ReviewActivity
{
public ReviewerSession ReviewerSession { get; set; }
public string UserComments { get; set; }
}
public class ReviewerSession
{
public Guid ReviewActivityId { get; set; }
public Guid ReviewerUserId { get; set; }
public DateTime ActivityDateTime { get; set; }
public string ReviewerComments { get; set; }
}
This is because you are creating a new List<ReviewInProgressActivityFeed>, a new ReviewInProgressActivityFeed and reading only the last element in activitiesFeed for each iteration:
ReviewerSession = new ReviewInProgressStatus
{
ReviewActivityId = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewActivityId).LastOrDefault(),
ActivityDateTime = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ActivityDateTime).LastOrDefault(),
ReviewComments = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewerComments).LastOrDefault(),
ReviewerName = requestModel.ReviewActivities.Select(x => x.ReviewerSession.ReviewerName).LastOrDefault()
}
Try below code instead of the above code:
public async Task<CallbackResponse> CallbackActivityFeedAsync(Guid Id)
{
CallbackResponse containerItems = new CallbackResponse();
containerItems.Data = new Callback();
containerItems.Data.ActivitiesFeed = new List<ReviewInProgressActivityFeed>();
IQueryable<HumanReviewRequest> query = cosmosReviewRequestContainer.GetItemLinqQueryable<HumanReviewRequest>(true);
query = query.Where(x => x.id == Id);
FeedIterator<HumanReviewRequest> feedIterator = query.ToFeedIterator();
while (feedIterator.HasMoreResults)
{
FeedResponse<HumanReviewRequest> r = await feedIterator.ReadNextAsync().ConfigureAwait(false);
if (r != null || r.ReviewActivities != null)
{
foreach (HumanReviewRequest requestModel in r.ReviewActivities)
{
containerItems.Data.ActivitiesFeed.Add(
new ReviewInProgressActivityFeed
{
ReviewerSession = new ReviewInProgressStatus
{
ReviewActivityId = requestModel.ReviewerSession.ReviewActivityId,
ActivityDateTime = requestModel.ReviewerSession.ActivityDateTime,
ReviewComments = requestModel.ReviewerSession.ReviewerComments,
ReviewerName = requestModel.ReviewerSession.ReviewerName
}
});
}
}
}
};
}
}
return containerItems;
}
Related
I use AutoMapper 8.1.0 in a asp.net core project. I have an Automapper mapping that doesn't work as I expected. I reproduced the configuration so you can test it by yourself. So I have an ExpenseReport with a collection of ExpenseReportItem and this one with another collection. I have to keep the data of eTaxCollection after the mapping, but they are lost in the process.
So the question is why values of eTaxCollections are lost after calling _mapper.Map(vmodel, model) and how can I keep them?
The ignore attribute don't work. I also tried UseDestinationValue(). I lost 2 days trying to figure it out and I'm exhausted.
public void WeatherForecasts()
{
int[] excludeTaxes = new int[] { 2 };
var vmodel = new ExpenseReportCreateEditModel();
vmodel.Expenses.Add(new ExpenseReportItemModel()
{
ExcludeTaxIds = excludeTaxes,
Total = 12,
Id = 1
});
// fetch from bd
var model = new ExpenseReport();
// values will be lost after _mapper.Map...
var eTaxCollections = new HashSet<ExcludeExpenseReportItemTax>();
eTaxCollections.Add(new ExcludeExpenseReportItemTax()
{
TaxId = 1,
ExpenseReportItemId = 1
});
model.Items.Add(new ExpenseReportItem()
{
ExcludeTaxes = eTaxCollections,
ExpenseReportId = 1,
Id = 9
});
_mapper.Map(vmodel, model);
}
public class ExpenseReportCreateEditModelProfile : Profile
{
public ExpenseReportCreateEditModelProfile()
{
CreateMap<ExpenseReportCreateEditModel, ExpenseReport>()
.ForMember(d => d.Items, s => s.MapFrom(m => m.Expenses));
}
}
public class ExpenseReportItemModelProfile : Profile
{
public ExpenseReportItemModelProfile()
{
CreateMap<ExpenseReportItemModel, ExpenseReportItem>()
.ForMember(d => d.ExcludeTaxes, s => s.Ignore()); // <<<==== data are lost
}
}
public class ExpenseReportCreateEditModel
{
public int Id { get; set; }
public ICollection<ExpenseReportItemModel> Expenses { get; set; }
public ExpenseReportCreateEditModel()
{
Expenses = new HashSet<ExpenseReportItemModel>();
}
}
public class ExpenseReportItemModel
{
public int Id { get; set; }
public ICollection<int> ExcludeTaxIds { get; set; }
public decimal Total { get; set; }
public ExpenseReportItemModel()
{
ExcludeTaxIds = new HashSet<int>();
}
}
public class ExpenseReport
{
public int Id { get; set; }
public virtual ICollection<ExpenseReportItem> Items { get; set; }
public ExpenseReport()
{
Items = new HashSet<ExpenseReportItem>();
}
}
public class ExpenseReportItem
{
public int Id { get; set; }
public int ExpenseReportId { get; set; }
public virtual ICollection<ExcludeExpenseReportItemTax> ExcludeTaxes { get; set; }
public ExpenseReportItem()
{
ExcludeTaxes = new HashSet<ExcludeExpenseReportItemTax>();
}
}
public class ExcludeExpenseReportItemTax
{
public int ExpenseReportItemId { get; set; }
public virtual ExpenseReportItem ExpenseReportItem { get; set; }
public int TaxId { get; set; }
}
Thank you for any help
Edit
I execute the execution plan and perhaps this is the problem:
$typeMapDestination = ($dest ?? .New WebApplication1.Controllers.SampleDataController+ExpenseReportItem());
This is only way I can lost the values.
I have to find a solution now
Here the complete execution plan :
.If ($src == null) {
.Default(WebApplication1.Controllers.SampleDataController+ExpenseReportItem)
} .Else {
.Block() {
$typeMapDestination = ($dest ?? .New WebApplication1.Controllers.SampleDataController+ExpenseReportItem());
.Try {
.Block(System.Int32 $resolvedValue) {
.Block() {
$resolvedValue = .If (
$src == null || False
) {
.Default(System.Int32)
} .Else {
$src.Id
};
$typeMapDestination.Id = $resolvedValue
}
}
} .Catch (System.Exception $ex) {
.Block() {
.Throw .New AutoMapper.AutoMapperMappingException(
"Error mapping types.",
$ex,
.Constant<AutoMapper.TypePair>(AutoMapper.TypePair),
.Constant<AutoMapper.TypeMap>(AutoMapper.TypeMap),
.Constant<AutoMapper.PropertyMap>(AutoMapper.PropertyMap));
.Default(System.Int32)
}
};
$typeMapDestination
}
}
I'm trying to use the FreshService API for assets and getting a list of assets returns JSON like the below. Notice that the properties inside "levelfield_values" have the id appended to the end of their property name.
I'm trying to pull the "license_expiry_date" for all assets but am having problems converting to objects to pull that field since the name changes with each item. Any suggestions?
{"config_item": {"agent_id": 215,
"asset_tag": batch_2017,
"assigned_on": "2014-07-18T03:54:18+05:30",
"ci_type_id": 3,
"created_at": "2014-07-25T14:25:04+05:30",
"deleted": false,
"department_id": 4,
"depreciation_id": null,
"description": null,
"disabled": false,
"display_id": 113,
"expiry_notified": false,
"id": 113,
"impact": 3,
"location_id": 21,
"name": "windows 7",
"salvage": null,
"trashed": false,
"updated_at": "2014-07-25T14:25:04+05:30",
"user_id": 214,
"department_name": "Finance",
"used_by": "Rachel",
"business_impact": "Medium",
"agent_name": "Andrea",
"levelfield_values": {
"product_3": 100,
"vendor_3": 43,
"cost_3": 4000,
"license_validity_3": 24,
"installation_date_3": "2014-07-25T14:25:04+05:30",
"license_expiry_date_3": "2016-07-25T00:00:00+05:30",
"license_key_3": "234_423_543_534",
"version_3": 2,
"license_type_3": "commercial",
"installed_machine_3": "Andrea’s computer",
"installation_path_3": null,
"last_audit_date_3": "2014-07-25T14:25:04+05:30"
},
"ci_type_name": "Software",
"product_name": "windows_os",
"vendor_name": "micosoft",
"state_name": null,
"location_name": "America" } }
You could do something like this
JsonConvert.DeserializeObject<JObject>(jsonString)["config_item"]["levelfield_values"]
.ToObject<JObject>()
.Properties()
.FirstOrDefault(x => x.Name.ToLower().Contains("license_validity"));
basically you;
navigate into config_item
navigate into levelfield_values
get all properties of navigated object (levelfield_values)
find a property that has a name like license_validity
That example Json is awful and incorrect, but.. here is how I'll make serialization seamless.
levelfield_values to definied as Expando object
defining a class for levelfield_values clean (no id in properties)
Add regenerative properties between Expando to defined class property and viceversa
I used visual studio paste special to write initially the class.
Example or fiddle:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var example = new Config
{
config_item = new Config_Item
{
LevelfieldValuesParshed = new CleanLevelfield_Values
{
Id = 2,
product = 1232
}
}
};
var serialized = JsonConvert.SerializeObject(example); // should have "product_2" : 2 inside
// VOILA deserialization with property parsing in a clean object
var deserialzed = JsonConvert.DeserializeObject<Config>(serialized);
if (example.config_item.LevelfieldValuesParshed.Id != deserialzed.config_item.LevelfieldValuesParshed.Id ||
example.config_item.LevelfieldValuesParshed.product != deserialzed.config_item.LevelfieldValuesParshed.product)
{
throw new Exception("Impossible to happen!!!");
}
}
}
public class Config
{
public Config_Item config_item { get; set; }
}
public class Config_Item
{
public int agent_id { get; set; }
public string asset_tag { get; set; }
public DateTime assigned_on { get; set; }
public int ci_type_id { get; set; }
public DateTime created_at { get; set; }
public bool deleted { get; set; }
public int department_id { get; set; }
public object depreciation_id { get; set; }
public object description { get; set; }
public bool disabled { get; set; }
public int display_id { get; set; }
public bool expiry_notified { get; set; }
public int id { get; set; }
public int impact { get; set; }
public int location_id { get; set; }
public string name { get; set; }
public object salvage { get; set; }
public bool trashed { get; set; }
public DateTime updated_at { get; set; }
public int user_id { get; set; }
public string department_name { get; set; }
public string used_by { get; set; }
public string business_impact { get; set; }
public string agent_name { get; set; }
// Regenerative property with backing filed => _levelfieldValuesParshed
[JsonIgnore] // Ignore property at serialization
public CleanLevelfield_Values LevelfieldValuesParshed
{
get
{
if (_levelfieldValuesParshed == null)
{
if (_levelfield_values != null) // if null everything is null
{
var propsByName = (IDictionary<string, object>)_levelfield_values; // Expando Object to dictionary
var product = propsByName.Keys.FirstOrDefault(x => x.StartsWith("product_", StringComparison.InvariantCultureIgnoreCase)); // user first to fail if not found, it can be smarter but it works
if (!string.IsNullOrEmpty(product))// hurray we know the id
{
if (int.TryParse(product.Replace("product_", ""), out int id)) // C# 7
{
// Cleaner code can be written (generic method to set get object props with reflection)
_levelfieldValuesParshed = new CleanLevelfield_Values
{
Id = id
};
_levelfieldValuesParshed.product = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"product_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"product_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
_levelfieldValuesParshed.vendor = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"vendor_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"vendor_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
_levelfieldValuesParshed.cost = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"cost_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"cost_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
_levelfieldValuesParshed.license_validity = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_validity_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"license_validity_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
_levelfieldValuesParshed.installation_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installation_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"installation_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
_levelfieldValuesParshed.license_expiry_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_expiry_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"license_expiry_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
_levelfieldValuesParshed.license_key = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_key_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToString(propsByName.First(x => x.Key.Equals($"license_key_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
_levelfieldValuesParshed.version = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"version_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"version_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
_levelfieldValuesParshed.license_type = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_type_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToString(propsByName.First(x => x.Key.Equals($"license_type_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
_levelfieldValuesParshed.installed_machine = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installed_machine_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToString(propsByName.First(x => x.Key.Equals($"installed_machine_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
_levelfieldValuesParshed.installation_path = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installation_path_{id}", StringComparison.InvariantCultureIgnoreCase)))
? propsByName.First(x => x.Key.Equals($"installation_path_{id}", StringComparison.InvariantCultureIgnoreCase)).Value : new object();
_levelfieldValuesParshed.last_audit_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"last_audit_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"last_audit_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
}
}
}
}
return _levelfieldValuesParshed;
}
set
{
_levelfieldValuesParshed = value;
_levelfield_values = null;
}
}
private CleanLevelfield_Values _levelfieldValuesParshed;
// Regenerative Expando property with backing field => _levelfield_values
public System.Dynamic.ExpandoObject levelfield_values
{
get
{
if (_levelfieldValuesParshed != null)
{
_levelfield_values = new ExpandoObject();
// Cleaner code can be written with a foreach (generic method to set get object props with reflection)
var keValuesPairs = (IDictionary<string, object>)_levelfield_values;
keValuesPairs.Add($"product_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.product);
keValuesPairs.Add($"vendor_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.vendor);
keValuesPairs.Add($"cost_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.cost);
keValuesPairs.Add($"license_validity_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_validity);
keValuesPairs.Add($"installation_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installation_date);
keValuesPairs.Add($"license_expiry_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_expiry_date);
keValuesPairs.Add($"license_key_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_key);
keValuesPairs.Add($"version_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.version);
keValuesPairs.Add($"license_type_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_type);
keValuesPairs.Add($"installed_machine_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installed_machine);
keValuesPairs.Add($"installation_path_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installation_path);
keValuesPairs.Add($"last_audit_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.last_audit_date);
return _levelfield_values;
}
return null;
}
set
{
_levelfield_values = value;
_levelfieldValuesParshed = null; // remove cleaned object, it will regenerated itself when opened
}
}
private ExpandoObject _levelfield_values;
public string ci_type_name { get; set; }
public string product_name { get; set; }
public string vendor_name { get; set; }
public object state_name { get; set; }
public string location_name { get; set; }
}
public class CleanLevelfield_Values
{
public int Id { get; set; }
public int product { get; set; }
public int vendor { get; set; }
public int cost { get; set; }
public int license_validity { get; set; }
public DateTime installation_date { get; set; }
public DateTime license_expiry_date { get; set; }
public string license_key { get; set; }
public int version { get; set; }
public string license_type { get; set; }
public string installed_machine { get; set; }
public object installation_path { get; set; }
public DateTime last_audit_date { get; set; }
}
}
I have this:
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
public List<???prpClass???> Whatever(string prpClass)
where string prpClass can be "Blah" or "Doh".
I would like the List type to be class Blah or Doh based on what the string prpClass holds.
How can I achieve this?
EDIT:
public List<prpClass??> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result;
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result;
}
return null
}
}
you have to have a common supertype:
public interface IHaveAnId
{
int id { get;set; }
}
public class Blah : IHaveAnId
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh : IHaveAnId
{
public int id {get;set;}
public string dohh { get; set; }
public string mahh { get; set; }
}
then you can do:
public List<IHaveAnId> TheList = new List<IHaveAnId>();
and in some method:
TheList.Add(new Blah{id=1,blahh = "someValue"});
TheList.Add(new Doh{id =2, dohh = "someValue", mahh = "someotherValue"});
to iterate through the list:
foreach(IHaveAnId item in TheList)
{
Console.WriteLine("TheList contains an item with id {0}", item.id);
//item.id is allowed since you access the property of the class over the interface
}
or to iterate through all Blahs:
foreach(Blah item in TheList.OfType<Blah>())
{
Console.WriteLine("TheList contains a Blah with id {0} and blahh ='{1}'", item.id, item.blahh);
}
Edit:
the 2 methods and a int field holding the autovalue:
private int autoValue = 0;
public void AddBlah(string blahh)
{
TheList.Add(new Blah{id = autovalue++, blahh = blahh});
}
public void AddDoh(string dohh, string mahh)
{
TheList.Add(new Doh{id = autovalue++, dohh = dohh, mahh = mahh});
}
Another Edit
public List<object> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result.Cast<object>().ToList();
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result.Cast<object>.ToList();
}
return null;
}
}
in the view you then have to decide what type it is. In asp.net MVC you can use a display template and use reflection to get a good design. But then i still don't know what technology you are using.
Yet another Edit
TestClass:
public class SomeClass
{
public string Property { get; set; }
}
Repository:
public static class Repository
{
public static List<object> Whatever(string prpClass)
{
switch (prpClass)
{
case "SomeClass":
return new List<SomeClass>()
{
new SomeClass{Property = "somestring"},
new SomeClass{Property = "someOtherString"}
}.Cast<object>().ToList();
default:
return null;
}
}
}
And a controller action in mvc:
public JsonResult Test(string className)
{
return Json(Repository.Whatever("SomeClass"),JsonRequestBehavior.AllowGet);
}
then i called it with: http://localhost:56619/Home/Test?className=SomeClass
And got the result:
[{"Property":"somestring"},{"Property":"someOtherString"}]
Is this what you are trying to do?
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
class Program
{
public static List<T> Whatever<T>(int count) where T: new()
{
return Enumerable.Range(0, count).Select((i) => new T()).ToList();
}
static void Main(string[] args)
{
var list=Whatever<Doh>(100);
// list containts 100 of "Doh"
}
}
I am trying to parse the following complex JSON result, which is returned from the Zoho Crm API:
{
"response":
{
"result":
{
"Contacts":
{
"row":
[
{
"no":"1",
"FL":
[
{
"content":"555555000000123456",
"val":"CONTACTID"
},
{
"content":"555555000000012345",
"val":"SMOWNERID"
},
{
"content":"John Doe",
"val":"Contact Owner"
},
{
"content":"Pete",
"val":"First Name"
},
{
"content":"Smith",
"val":"Last Name"
},
{
"content":"pete#mail.com",
"val":"Email"
},
{
"content":"5555551000000012346",
"val":"SMCREATORID"
},
{
"content":"Jane Doe",
"val":"Created By"
},
{
"content":"555555000000012347",
"val":"MODIFIEDBY"
},
{
"content":"Doris Doe",
"val":"Modified By"
},
{
"content":"2013-06-14 17:24:10",
"val":"Created Time"
},
{
"content":"2013-06-14 17:24:10",
"val":"Modified Time"
},
{
"content":"2013-06-14 17:28:05",
"val":"Last Activity Time"
}
]
},
{
...
}
]
}
},
"uri":"/crm/private/json/Contacts/getRecords"
}
}
Here is how my Object looks:
public class Contact
{
[JsonProperty(PropertyName = "CONTACTID")]
public string ContactID { get; set; }
[JsonProperty(PropertyName = "SMOWNERID")]
public string OwnerID { get; set; }
[JsonProperty(PropertyName = "Contact Owner")]
public string ContactOwner { get; set; }
[JsonProperty(PropertyName = "First Name")]
public string FirstName { get; set; }
[JsonProperty(PropertyName = "Last Name")]
public string LasName { get; set; }
[JsonProperty(PropertyName = "Email")]
public string Email { get; set; }
[JsonProperty(PropertyName = "SMCREATORID")]
public string CreatorID { get; set; }
[JsonProperty(PropertyName = "Created By")]
public string CreatedBy { get; set; }
[JsonProperty(PropertyName = "MODIFIEDBY")]
public string ModifiedByID { get; set; }
[JsonProperty(PropertyName = "Modified By")]
public string ModifiedBy { get; set; }
[JsonProperty(PropertyName = "Created Time")]
public DateTime CreatedTime { get; set; }
[JsonProperty(PropertyName = "Modified Time")]
public DateTime ModifiedTime { get; set; }
[JsonProperty(PropertyName = "Last Activity Time")]
public DateTime LastActivityTime { get; set; }
}
The "row" pattern repeats (no 1, 2, 3 ...) so what I am basically trying to get is a Generic List of Objects of this type. I am trying to using JSON.NET, but I am open to other suggestions if it makes this any easier.
This doesn't work in this case obviously:
var response = JsonConvert.DeserializeObject<Contact>(jsonString);
And neither does this:
var deserializedObjects = JsonConvert.DeserializeObject<List<Contact>>(jsonString);
Here is a workaround I have put together to parse this using JavaScriptSerializer, but it is by far one of my worst code blocks ever!
List<Contact> loContactList = new List<Contact>();
Contact loContact = null;
Dictionary<string, object> dictionary = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);
var response = (Dictionary<string, object>)dictionary["response"];
var result = (Dictionary<string, object>)response["result"];
var contacts = (Dictionary<string, object>)result["Contacts"];
var row = (ArrayList)contacts["row"];
foreach (var item in row)
{
var loArrayItem = (Dictionary<string, object>)item;
var fl = (ArrayList)loArrayItem["FL"];
loContact = new Contact();
foreach (var contactitem in fl)
{
var contactdict = (Dictionary<string, object>)contactitem;
string val = (string)contactdict["val"];
string content = (string)contactdict["content"];
if (val == "CONTACTID")
{
loContact.ContactID = content;
}
else if (val == "SMOWNERID")
{
loContact.OwnerID = content;
}
else if (val == "Contact Owner")
{
loContact.ContactOwner = content;
}
else if (val == "First Name")
{
loContact.FirstName = content;
}
else if (val == "Last Name")
{
loContact.LastName = content;
}
else if (val == "Email")
{
loContact.Email = content;
}
else if (val == "SMCREATORID")
{
loContact.CreatorID = content;
}
else if (val == "Created By")
{
loContact.CreatedBy = content;
}
else if (val == "MODIFIEDBY")
{
loContact.ModifiedByID = content;
}
else if (val == "Modified By")
{
loContact.ModifiedBy = content;
}
else if (val == "Created Time")
{
loContact.CreatedTime = Convert.ToDateTime(content);
}
else if (val == "Modified Time")
{
loContact.ModifiedTime = Convert.ToDateTime(content);
}
else if (val == "Last Activity Time")
{
loContact.LastActivityTime = Convert.ToDateTime(content);
}
}
loContactList.Add(loContact);
}
I have gone through other similar posts on StackOverflow and none of them seem to provide a solution for this problem. Does anyone have a solution for this? My goal is to parse this JSON response in a more elegant way, which doesn't involve a million dictionary objects and ArrayList! Any help would be appreciated.
Thanks,
Pete
Update 7/2/13:
Based on Manvik's suggestion, I put together the following additional solution:
public class ResponseActual
{
[JsonProperty("response")]
public Response2 Response { get; set; }
}
public class Response2
{
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("uri")]
public string Uri { get; set; }
}
public class Result
{
[JsonProperty("Contacts")]
public Contacts Contacts { get; set; }
}
public class Contacts
{
[JsonProperty("row")]
public IList<Row> Row { get; set; }
}
public class Row
{
[JsonProperty("no")]
public string No { get; set; }
[JsonProperty("FL")]
public IList<FL> FL { get; set; }
}
public class FL
{
[JsonProperty("content")]
public string Content { get; set; }
[JsonProperty("val")]
public string Val { get; set; }
}
List<Contact> loContactList = new List<Contact>();
Contact loContact = null;
ResponseActual respone = JsonConvert.DeserializeObject<ResponseActual>(jsonString);
foreach (var row in respone.Response.Result.Contacts.Row)
{
loContact = new Contact();
var rowItem = row.FL.ToList();
try { loContact.ContactID = rowItem.Where<FL>((s, t) => s.Val == "CONTACTID").Select(x => x.Content).Single(); }
catch { }
try { loContact.OwnerID = rowItem.Where<FL>((s, t) => s.Val == "SMOWNERID").Select(x => x.Content).Single(); }
catch { }
try { loContact.ContactOwner = rowItem.Where<FL>((s, t) => s.Val == "Contact Owner").Select(x => x.Content).Single(); }
catch { }
try { loContact.FirstName = rowItem.Where<FL>((s, t) => s.Val == "First Name").Select(x => x.Content).Single(); }
catch { }
try { loContact.LastName = rowItem.Where<FL>((s, t) => s.Val == "Last Name").Select(x => x.Content).Single(); }
catch { }
try { loContact.Email = rowItem.Where<FL>((s, t) => s.Val == "Email").Select(x => x.Content).Single(); } catch { }
try { loContact.CreatorID = rowItem.Where<FL>((s, t) => s.Val == "SMCREATORID").Select(x => x.Content).Single(); }
catch { }
try { loContact.CreatedBy = rowItem.Where<FL>((s, t) => s.Val == "Created By").Select(x => x.Content).Single(); }
catch { }
try { loContact.ModifiedByID = rowItem.Where<FL>((s, t) => s.Val == "MODIFIEDBY").Select(x => x.Content).Single(); }
catch { }
try { loContact.ModifiedBy = rowItem.Where<FL>((s, t) => s.Val == "Modified By").Select(x => x.Content).Single(); }
catch { }
try { loContact.CreatedTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Created Time").Select(x => x.Content).Single()); }
catch { }
try { loContact.ModifiedTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Modified Time").Select(x => x.Content).Single()); }
catch { }
try { loContact.LastActivityTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Last Activity Time").Select(x => x.Content).Single()); }
catch { }
loContactList.Add(loContact);
}
Use the below classes for de-serializing using JSON.Net
public class ResponseActual
{
[JsonProperty("response")]
public Response2 Response { get; set; }
}
public class Response2
{
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("uri")]
public string Uri { get; set; }
}
public class Result
{
[JsonProperty("Contacts")]
public Contacts Contacts { get; set; }
}
public class Contacts
{
[JsonProperty("row")]
public IList<Row> Row { get; set; }
}
public class Row
{
[JsonProperty("no")]
public string No { get; set; }
[JsonProperty("FL")]
public IList<FL> FL { get; set; }
}
public class FL
{
[JsonProperty("content")]
public string Content { get; set; }
[JsonProperty("val")]
public string Val { get; set; }
}
//To De-serialize
ResponseActual respone = JsonConvert.DeserializeObject<ResponseActual>(jSON_sTRING)
//Get the contacts list
List<FL> contacts = respone.Response.Result.Contacts.Row[0].FL.ToList();
//Now Get the required value using LINQ
var value = contacts.Where<FL>((s, e) => s.Val =="Email").Select(x=>x.Content).Single();
You may also checkout this -
Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?)
You need to include the following portion of JSON in your deserialization object Type :
{
"response":
{
"result":
{
"Contacts":
{
"row":
[
{
"no":"1",
"FL":
Class type : 'Contact' is inadequate.
you can use this code:
dynamic dictionary = (JsonConvert.DeserializeObject>(jsonstring))["response"];
var result = dictionary.result;
var contact= result.Contacts;
var row= contact.row;
foreach (var item in row)
{
var no= item.no;
}
Can I ask you something? Are you the one exporting the JSON? I ask this because the format is quite weird and it does get in the way of your code.
A simpler format would allow you to serialize the string pretty much in a direct way.
Below codes run perfectly but i want to re generate simply
static void YeniMethodListele()
{
Calısan calisan = new Calısan(){ ID=1, Ad="xxx", SoyAd="yyy"};
List<Calısan> myList = new List<Calısan>();
myList.Add(calisan);
MyCalısan myCalısan = new MyCalısan() { list = myList };
//myCalısan.list.Add(calisan);
foreach (Calısan item in myCalısan.list)
{
Console.WriteLine(item.Ad.ToString());
}
}
}
public class Calısan
{
public int ID { get; set; }
public string Ad { get; set; }
public string SoyAd { get; set; }
}
public class MyCalısan
{
public List<Calısan> list { get; set; }
public MyCalısan()
{
list = new List<Calısan>();
}
}
Here is a sample of a couple of ways to create the list a little more simply. Note the small change to the Calısan object to give it a default constructor and an overloaded constructor.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
////Calısan calisan = new Calısan() { ID = 1, Ad = "xxx", SoyAd = "yyy" };
MyCalısan myCalısan = new MyCalısan();
//option 1:
//==========
myCalısan.list.AddRange(new[] { new Calısan() { ID = 1, Ad = "xxx", SoyAd = "yyyy" }, new Calısan() { ID = 2, Ad = "blah", SoyAd = "jiggy" } });
//option 2:
//=========
myCalısan.list.AddRange(new[] { new Calısan(1, "xxx", "yyy"), new Calısan(2, "blah", "jiggy") });
////myCalısan.list.Add(calisan);
foreach (Calısan item in myCalısan.list)
{
Console.WriteLine(item.Ad.ToString());
}
Console.ReadKey();
}
}
public class Calısan
{
public Calısan() { }
public Calısan(int id, string ad, string soyad)
{
ID = id;
Ad = ad;
SoyAd = soyad;
}
public int ID { get; set; }
public string Ad { get; set; }
public string SoyAd { get; set; }
}
public class MyCalısan
{
public List<Calısan> list { get; set; }
public MyCalısan()
{
list = new List<Calısan>();
}
}
}