Error deserializing a JSON array in SSIS Script Component - c#

I am attempting to deserialize a JSON array via an SSIS source script component in C# using Newtonsoft JSON.net, but I'm running into the following error when I try to build the SSIS project:
CS0029: Cannot implicitly convert type 'System.Collections.Generic.List<ScriptMain.Order> to <ScriptMain.Order'
I suspect it's something to do with the Order class not being defined as a list, but I'm fairly new to C# and I really don't know, so would really appreciate any advice.
This was working correctly for a JSON string before I attempted to change the code to handle an array - i.e. in the code I changed
Order order = JsonConvert.DeserializeObject<Order>(record);
to
Order order = JsonConvert.DeserializeObject<List<Order>>(record);
Here is the JSON array - it's just a typical order / orderline scenario where one order can have multiple order lines.
[
{
"OrderID": 291,
"CustomerID": 1135,
"OrderDate": "2020-07-21",
"OrderLine": [
{
"OrderLineID": 1,
"ProductID": 2,
"Units": 1,
"ClientID": 2
},
{
"OrderLineID": 2,
"ProductID": 8,
"Units": 2,
"ClientID": 1
}
]
},
{
"OrderID": 292,
"CustomerID": 59,
"OrderDate": "2020-07-21",
"OrderLine": [
{
"OrderLineID": 1,
"ProductID": 5,
"Units": 1,
"ClientID": 1
},
{
"OrderLineID": 2,
"ProductID": 7,
"Units": 2,
"ClientID": 2
},
{
"OrderLineID": 3,
"ProductID": 9,
"Units": 1,
"ClientID": 3
}
]
}
]
and here is the C# from the script component in SSIS:
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
string filePath = Connections.OrdersFile20200720.AcquireConnection(null).ToString();
using (StreamReader fileContents = new StreamReader(filePath))
{
while (fileContents.Peek() >= 0)
{
string record = fileContents.ReadLine();
//Order order = JsonConvert.DeserializeObject<Order>(record);
Order order = JsonConvert.DeserializeObject<List<Order>>(record); //this is failing
OrderOutputBuffer.AddRow();
OrderOutputBuffer.OrderID = order.OrderID;
OrderOutputBuffer.CustomerID = order.CustomerID;
OrderOutputBuffer.OrderDate = order.OrderDate;
foreach (OrderLine orderline in order.OrderLine)
{
OrderLineOutputBuffer.AddRow();
OrderLineOutputBuffer.OrderID = order.OrderID;
OrderLineOutputBuffer.OrderLineID = orderline.OrderLineID;
OrderLineOutputBuffer.ProductID = orderline.ProductID;
OrderLineOutputBuffer.Units = orderline.Units;
OrderLineOutputBuffer.ClientID = orderline.ClientID;
}
}
}
}
public class Order
{
public int OrderID { get; set; }
public int CustomerID { get; set; }
public DateTime OrderDate { get; set; }
public OrderLine[] OrderLine { get; set; }
}
public class OrderLine
{
public int OrderLineID { get; set; }
public int ProductID { get; set; }
public int Units { get; set; }
public int ClientID { get; set; }
}
}
Thanks!

I fixed this in the end:
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
string json = File.ReadAllText("Z:\\DataTech Test\\Data\\Orders_20200720.json");
var records = JsonConvert.DeserializeObject<List<Order>>(json);
foreach (var r in records)
{
OrderOutputBuffer.AddRow();
OrderOutputBuffer.OrderID = r.OrderID;
OrderOutputBuffer.CustomerID = r.CustomerID;
OrderOutputBuffer.OrderDate = r.OrderDate;
foreach (OrderLine orderline in r.OrderLine)
{
OrderLineOutputBuffer.AddRow();
OrderLineOutputBuffer.OrderID = r.OrderID;
OrderLineOutputBuffer.OrderLineID = orderline.OrderLineID;
OrderLineOutputBuffer.ProductID = orderline.ProductID;
OrderLineOutputBuffer.Units = orderline.Units;
OrderLineOutputBuffer.NurseryID = orderline.NurseryID;
}
}
}
public class OrderLine
{
public int OrderLineID { get; set; }
public int ProductID { get; set; }
public int Units { get; set; }
public int NurseryID { get; set; }
}
public class Order
{
public int OrderID { get; set; }
public int CustomerID { get; set; }
public DateTime OrderDate { get; set; }
public List<OrderLine> OrderLine { get; set; }
}
public class Root
{
public List<Order> Order { get; set; }
}
}

Related

Using NetToplogySuite to get the geometry from Geojson file with method (IsWithinDistance) ASP.NET Core

I'm stuck in using NetTopologySuite with geojson file.
I want to get all the points from the geojson and then use the IsWithinDistance() method to get all the points within certain distance. I could deserialize the data and get the coordinates but the method doesn't work. I suppose that the method needs the points to be converted to WKB ? please correct me if I'm mistaken.
I could successfully execute the method when my first source of data stored in database but from json it doesn't work.
This is my controller :
public IActionResult GetWeather()
{
IList<WeatherViewModel> Tags = new List<WeatherViewModel>();
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var searchAreaCoordinate = new NetTopologySuite.Geometries.Coordinate(-1.882, 52.486);
var searchArea = geometryFactory.CreatePoint(searchAreaCoordinate);
Root weather = JsonConvert.DeserializeObject<Root>(System.IO.File.ReadAllText(#"C:\local\weatherx.json"));
var features = (from c in weather.features select c)
.Select(x=> new {x.id,x.type,x.geometry.coordinates})
// .Where(x=>x.Coor.IsWithinDistance(searchArea, 300))
.ToList();
;
foreach (var item in features)
{
Tags.Add(new WeatherViewModel()
{
id = item.id,
type = item.type,
Long = item.coordinates[0],
Lat = item.coordinates[1],
WKT = new NetTopologySuite.Geometries.Coordinate( item.coordinates[0] , item.coordinates[1])
}
);
}
return View(Tags);
}
Part of my json class:
public class Root
{
public string type { get; set; }
public ParameterDescription parameter_description { get; set; }
public List<double> bbox { get; set; }
public List<Feature> features { get; set; }
}
public class Geometry
{
public string type { get; set; }
public List<double> coordinates { get; set; }
}
public class Feature
{
public string id { get; set; }
public string type { get; set; }
public Properties properties { get; set; }
public Geometry geometry { get; set; }
public Geometry Coor {get;set;}
}
Here is part of my geojson:
{
"type": "FeatureCollection",
"features": [
{
"id": "1",
"type": "Feature",
"properties": {
"t": [
1,
],
"s": [
1,
],
"Time": [
"2021-11-01",
]
},
"geometry": {
"type": "Point",
"coordinates": [
-1.881,
52.486
]
}
},
]
}

Linq: Match to properties of child object in a list of child objects and return parent object from a list of parents

I am attempting to write a Linq query to return a parent object identified by matching to a property of one of its child objects. My class is a Sales Order which has a list of Deliveries which in turn has a list of LineItems. I would like to return a Delivery object when there is a match to the Item Number and Line Number properties in a Delivery's LineItems.
Classes:
public class SalesOrderDetail
{
[JsonProperty("SalesOrderNumber")]
public string SalesOrderNumber { get; set; }
[JsonProperty("PONumber")]
public string PONumber { get; set; }
[JsonProperty("Status")]
public string Status { get; set; }
[JsonProperty("Deliveries")]
public List<Delivery> Deliveries { get; set; }
}
public class Delivery
{
[JsonProperty("DeliveryDocumentNumber")]
public string DeliveryDocumentNumber { get; set; }
[JsonProperty("DeliveryStatus")]
public string DeliveryStatus { get; set; }
[JsonProperty("Parcels")]
public List<Parcel> Parcels { get; set; }
[JsonProperty("LineItems")]
public List<LineItem> LineItems { get; set; }
[JsonProperty("ShippedDate")]
public DateTime ShippedDate { get; set; }
}
public class LineItem
{
[JsonProperty("DeliveryDocumentLineNumber")]
public int DeliveryDocumentLineNumber { get; set; }
[JsonProperty("OrderLineNumber")]
public int OrderLineNumber { get; set; }
[JsonProperty("ItemNumber")]
public string ItemNumber { get; set; }
[JsonProperty("QuantityOrdered")]
public int QuantityOrdered { get; set; }
[JsonProperty("QuantityPicked")]
public int QuantityPicked { get; set; }
[JsonProperty("QuantityScanned")]
public int QuantityScanned { get; set; }
[JsonProperty("QuantityShipped")]
public int QuantityShipped { get; set; }
[JsonProperty("QuantityCanceled")]
public int QuantityCanceled { get; set; }
[JsonProperty("LineItemDetails")]
public List<LineItemDetail> LineItemDetails { get; set; }
}
Example JSON:
{
"SalesOrderNumber": "0017320457",
"PONumber": "PON0234250",
"Status": "Completely Shipped",
"Deliveries": [
{
"DeliveryDocumentNumber": "0088148528",
"DeliveryStatus": "Shipped",
"Parcels": [
{
"CartonNumber": "00093456780095683506",
"CarrierCode": "FEDG",
"TrackingType": "TRACKING",
"TrackingNumber": "946346636541",
"Weight": 12.22,
"WeightUOM": "LB"
}
],
"LineItems": [
{
"DeliveryDocumentLineNumber": 10,
"OrderLineNumber": 10,
"ItemNumber": "SYM-LS2208SR20007RUR",
"QuantityOrdered": 1,
"QuantityPicked": 0,
"QuantityScanned": 0,
"QuantityShipped": 1,
"QuantityCanceled": 0,
"LineItemDetails": [
{
"CartonNumber": "00093456780095683506",
"SerialNumber": "SZ3M7Z8",
"MACAddress": null,
"MACAddressUnformatted": null
}
]
},
],
"ShippedDate": "2021-03-05T03:32:43.903"
}
]
"Deliveries": [
{
"DeliveryDocumentNumber": "0088148351",
"DeliveryStatus": "Shipped",
"Parcels": [
{
"CartonNumber": "000934567800956835901",
"CarrierCode": "FEDG",
"TrackingType": "TRACKING",
"TrackingNumber": "946346636443",
"Weight": 10.24,
"WeightUOM": "LB"
}
],
"LineItems": [
{
"DeliveryDocumentLineNumber": 20,
"OrderLineNumber": 20,
"ItemNumber": "ZEB-ZD62142T01F00EZ",
"QuantityOrdered": 1,
"QuantityPicked": 0,
"QuantityScanned": 0,
"QuantityShipped": 1,
"QuantityCanceled": 0,
"LineItemDetails": [
{
"CartonNumber": "000934567800956835901",
"SerialNumber": "D1N204401680",
"MACAddress": null,
"MACAddressUnformatted": null
}
]
},
],
"ShippedDate": "2021-03-04T03:32:43.903"
}
]
}
The way I started thinking about this is to write the following code. Intellisense states it will return an object of type Delivery, however, a test of the code generates the exception "Sequence contain no elements".
int lineNumber = 10;
string itemNumber = "SYM-LS2208SR20007RUR";
var matchedDelivery = salesOrderDetail.Deliveries.Where(f => f.LineItems == f.LineItems.Where(l => (l.ItemNumber == itemNumber) && (l.OrderLineNumber == lineNumber))).First();
It's probably more like
var matchedDeliveries = salesOrderDetail.Deliveries
.Where(d => d.LineItems.Any(li => li.ItemNumber == itemNumber && li.OrderLineNumber == lineNumber));
Or if you want one delivery swap the Where for First (or Single if you want an exception if there are multiple)
This should read fairly naturally but it's "in all deliveries get deliveries where any member of the delivery's lineitems have an itemNumber of blah and orderLineNumber of blahblah" if it helps make sense of it

How to return ListAsync as an object

So currently this method gets the venuetype and outputs it's name, image and cafeID of that venue.
it's currently being returned as an Array, but I want to return it as an object but wasn't sure how to it's a simple question but I've been staring at it for a while now.
{
public class VenueTypeResponse
{
public string Name { get; set; }
public string ImageUrl { get; set; }
public int id { get; set; }
}
}
public VenueService(EVouchContext context)
{
_context = context;
}
//Gets venuetype and outputs the name, image and cafeID of that venue.
public async Task<List<VenueTypeResponse>> GetVenueType()
{
return await _context.CafeType.Select(s => new VenueTypeResponse()
{
id = s.CafeTypeId,
Name = s.Name,
ImageUrl = s.ImageUrl
}).ToListAsync();
}
I've tried the approach of removing the and returning it as .FirstorDefault but it clearly just returns the first venue type and not all of them. Any suggestions would be great! :)
Response I would like
{
data: [
{
id : 1,
name : "Take aways",
imageUrl : "https://..jpg"
},
{
id : 2,
name : "Desserts",
imageUrl : "https://..jpg"
},
{
...
},
{
...
}
],
meta: {
pageTotal: 1,
pageCurrent: 1
}
}
Response I'm getting
[
{
"name": "Restaurant",
"imageUrl": "https:..",
"id": 1
},
{
"name": "Takeaway",
"imageUrl": "https://...",
"id": 2
},
...
]
You need to create an object that holds your list, something like this:
public class Response
{
[JsonProperty("data")]
public List<VenueTypeResponse> Data { get; set; }
[JsonProperty("meta")]
public ResponseMeta Meta { get; set; }
}
public class ResponseMeta
{
[JsonProperty("pageTotal")]
public int PageTotal { get; set; }
[JsonProperty("pageCurrent")]
public int PageCurrent { get; set; }
}
and then either return this from your method, or wrap the result from this method into this object, before returning it from your endpoint.

Use Linq or C# to parse Json

I am getting familiar with C# and Linq and appreciate any help. It should be easy for someone who works with it. I have a Json object that returns contact information. I also have a list of ids. I need to compare the list to the Json object and wherever the value in the list matches the userclientcode in the Json object, I need to extract the following information (only for the matches):
clienttaxonomy (if not empty)
fullname (if not empty)
[0]contactdata ( -> email if not null or empty)
[1]contactdata (-> address if not null or empty)
[2]contactdata (-> phone number if not null or empty)
First List
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354",
"12342341", "123412322", "163341234", "2345234115", "8967896", "75626234 };
JSON object returned with:
return JsonConvert.DeserializeObject<RelatedContacts>(json)?.list;
This is the Json object:
[![Json object][1]][1]
This is the Json string (unescaped):
{
"type": "com.kurtosys.api.userprofile.domain.RelatedContactList",
"list": [{
"objectlistid": 5678765,
"objectlisttypeid": 4567876,
"objectlistname": "ALL.National",
"clienttaxonomyid": 765677,
"clienttaxonomy": "National Wholesaler",
"order": 1,
"contacts": [{
"personid": 7654345678,
"fullname": "Person Jallo",
"userid": 876567,
"userclientcode": "341234123",
"contactdetails": [{
"contactid": 8765567,
"contacttypeid": 4565,
"contactdata": "person.contact#site.com"
}, {
"contactid": 876545678,
"contacttypeid": 4565,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 87654567,
"contacttypeid": 4584,
"contactdata": "410-413-2640"
}]
}]
}, {
"objectlistid": 765678,
"objectlisttypeid": 40400461,
"objectlistname": "RM.Internal",
"clienttaxonomyid": 7567898,
"clienttaxonomy": "Internal Regional Wholesaler",
"order": 2,
"contacts": [{
"personid": 56789876,
"fullname": "Jackson Man",
"userid": 876567,
"userclientcode": "1012275",
"contactdetails": [{
"contactid": 309598309,
"contacttypeid": 76546,
"contactdata": "mister.jackson##site.com.com"
}, {
"contactid": 876567,
"contacttypeid": 4581,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 876567,
"contacttypeid": 2342,
"contactdata": "123-413-2604"
}]
}]
}, {
"objectlistid": 309571364,
"objectlisttypeid": 40400461,
"objectlistname": "RM.External",
"clienttaxonomyid": 309580710,
"clienttaxonomy": "External Regional Wholesaler",
"order": 3,
"contacts": [{
"personid": 302736188,
"fullname": "Phal Sumi",
"userid": 303826019,
"userclientcode": "163341234",
"contactdetails": [{
"contactid": 309598253,
"contacttypeid": 2342,
"contactdata": "misters.emailas#site.com"
}, {
"contactid": 309611930,
"contacttypeid": 2342,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 34234132,
"contacttypeid": 3422,
"contactdata": "342-803-1793"
}]
}]
}]
}
How do I
1] Select using Linq and Lambdas and put in a list fullname, email, address etc from the deserialized object ?
2]compare with first list and only transfer those items where the userclientcode == the number in list A.
I have tried:
var query5 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
var selected = relatedContact.Where(p => p.contacts
.Any(a => fileContactIds.Contains(p.contacts))
.ToList();
var query2 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
.Select(s => new
{
Description = s.clienttaxonomy,
Fullname = s.contacts[0].fullname,
Email = s.contacts[0].contactdetails[0].contactdata,
Address = s.contacts[0].contactdetails[1].contactdata,
PhoneNumber = s.contacts[0].contactdetails[2].contactdata
});
But don't really know what I'm doing it seems. Any suggestions on how to get the required sections ? I think part of the reason is that the contactdata is a list.
Thanks all
You can create a classes for the desearlization of JSON Object like this
public class Rootobject
{
public string type { get; set; }
public List[] list { get; set; }
}
public class List
{
public int objectlistid { get; set; }
public int objectlisttypeid { get; set; }
public string objectlistname { get; set; }
public int clienttaxonomyid { get; set; }
public string clienttaxonomy { get; set; }
public int order { get; set; }
public Contact[] contacts { get; set; }
}
public class Contact
{
public long personid { get; set; }
public string fullname { get; set; }
public int userid { get; set; }
public string userclientcode { get; set; }
public Contactdetail[] contactdetails { get; set; }
}
public class Contactdetail
{
public int contactid { get; set; }
public int contacttypeid { get; set; }
public string contactdata { get; set; }
}
And then to extract the selected information we can also create a another class like
public class ExtractedInfo
{
public string ocClientTaxonomy { get; set; }
public string ocFullName { get; set; }
public CTDetails ocContactDetails { get; set; }
}
public class CTDetails
{
public string ocCTAddress { get; set; }
public string ocCTEmail { get; set; }
public string ocCTPhoneNumber { get; set; }
}
Now we have to find all the data from JSON
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354", "12342341", "123412322", "163341234", "2345234115", "8967896", "75626234" };
//Read JSON from txt file. You can do it by your way
string myjson = File.ReadAllText("Some.txt");
string ctphno, ctadd, ctemail, cltax, ctfullname;
List<ExtractedInfo> ei = new List<ExtractedInfo>();
CTDetails ctdtl = new CTDetails();
ExtractedInfo eiex = new ExtractedInfo();
//Deserialize the JSON string to Object.
Rootobject AllData = JsonConvert.DeserializeObject<Rootobject>(myjson);
//Finding all data in List Class
foreach(List lst in AllData.list)
{
cltax = lst.clienttaxonomy; // you can directly put eiex.ocClientTaxonomy = lst.clienttaxonomy;
foreach(Contact ct in lst.contacts)
{
//To check if value in the list matches the objectlistid in the Json object
if(fileContactIds.Contains(lst.objectlistid.ToString()))
{
ctfullname = ct.fullname; // you can directly put eiex.ocFullName = ct.fullname;
foreach(Contactdetail ctd in ct.contactdetails)
{
//Here we are trying to find the Match for Email.
if(Regex.IsMatch(ctd.contactdata, #"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase))
{
ctemail = ctd.contactdata;
ctdtl.ocCTEmail = ctemail;
}
//Here We trying to find the match for Phone Number.
else if(Regex.IsMatch(ctd.contactdata, #"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}", RegexOptions.IgnoreCase))
{
ctphno = ctd.contactdata;
ctdtl.ocCTPhoneNumber = ctphno;
}
//If NOthing matches than it might be address (Assumed)
else
{
ctadd = ctd.contactdata;
ctdtl.ocCTAddress = ctadd;
}
}
eiex.ocFullName = ctfullname;
}
}
eiex.ocClientTaxonomy = cltax;
eiex.ocContactDetails = ctdtl;
ei.Add(eiex);
}
Hope this helps and fit in your requirements.

LINQ grouping in object

I have two classes
public class MyObjects{
public bool Active {get; set;}
public List<OtherObject> OtherObjects {get; set;}
}
public class OtherObject {
public int Id {get; set;}
public bool Enabled {get; set;}
public string Address {get; set;}
public string Name {get; set;}
}
My current result is
MyObject { Active = true; },
OtherObjects: [OtherObject: { Id: 1, Name: 'First'},
OtherObject{Id: 2, Name: 'First'},
OtherObject{Id: 3, Name: 'Second'}];
I want to group them by Name so I would still have Active property and those OtherObjects inside would be grouped by OtherObject Name property. Is it possible to do so only using LINQ?
EDIT:
Final result should be json, that I will use in angular, so it should be something like this:
{
""Active"": true,
""OtherObjects"": [
{
""ObjectName"": ""Second"",
""ObjectOtherProperties"": [
{
""Id"": 1,
""Enabled"": false
},
{
""Id"": 2,
""Enabled"": true
}
],
""ObjectName"": ""Second"",
""ObjectOtherProperties"": [
{
""Id"": 1,
""Enabled"": false
}
],
]
}
}
Any suggestions how to achieve this? Maybe I must make other classes and somehow map them by grouping?
This is how I would do it, keeping it simple:
// 1. Add OtherObjectsDictionary
// 2. Block OtherObjects in the json serialization
public class MyObjects
{
public bool Active { get; set; }
[Newtonsoft.Json.JsonIgnore]
public List<OtherObject> OtherObjects { get; set; }
public Dictionary<string, List<OtherObject>> OtherObjectsDictionary { get; set; }
}
// 3. Block Name in the json serialization
public class OtherObject
{
public int Id { get; set; }
public bool Enabled { get; set; }
public string Address { get; set; }
[Newtonsoft.Json.JsonIgnore]
public string Name { get; set; }
}
// 4. Linq queries to achieve the grouped result
// 5. Serialize to Json
static void Main(string[] args)
{
var myObjects = new MyObjects() { Active = true, OtherObjects = new List<OtherObject>() };
myObjects.OtherObjects.Add(new OtherObject { Id = 1, Name = "First" });
myObjects.OtherObjects.Add(new OtherObject { Id = 2, Name = "First" });
myObjects.OtherObjects.Add(new OtherObject { Id = 3, Name = "Second" });
myObjects.OtherObjectsDictionary = new Dictionary<string, List<OtherObject>>();
var distinctNames = myObjects.OtherObjects.Select(otherObject => otherObject.Name).Distinct();
foreach(var distinctName in distinctNames)
{
var groupedObjectsList = myObjects.OtherObjects.Where(otherObject => otherObject.Name == distinctName).ToList();
myObjects.OtherObjectsDictionary.Add(distinctName, groupedObjectsList);
}
var outputJson = Newtonsoft.Json.JsonConvert.SerializeObject(myObjects);
}
This is the json result:
{
"Active": true,
"OtherObjectsDictionary": {
"First": [
{
"Id": 1,
"Enabled": false,
"Address": null
},
{
"Id": 2,
"Enabled": false,
"Address": null
}
],
"Second": [
{
"Id": 3,
"Enabled": false,
"Address": null
}
]
}
}
I hope it helps.
You may also use the System.Web.Extensions .dll as Add References for framework 4.0 projects (not 4.0 Client Profile).
Then add using inside your class.
I also applied a different approach, a more-or-less DB like normalization.
List of classes
public class MyObjects
{
public bool Active { get; set; }
public List<ObjectName> OtherObjects { get; set; }
}
public class ObjectName
{
public string Name { get; set; }
public List<OtherObject> OtherObjectProperties { get; set; }
}
public class OtherObject
{
public int Id { get; set; }
public bool Enabled { get; set; }
[ScriptIgnore]
public string Address { get; set; }
[ScriptIgnore]
public string Name { get; set; }
}
populate the records..
List<OtherObject> oList = new List<OtherObject>();
oList.Add(new OtherObject() { Id = 2, Name = "First" });
oList.Add(new OtherObject() { Id = 3, Name = "Second" });
// each name with objects
List<ObjectName> oNames = new List<ObjectName>();
oNames.AddRange(oList.Select(p => new ObjectName() {
Name = p.Name
, OtherObjectProperties = oList.Where(p1 => p1.Name == p.Name).ToList()
}).Distinct()
);
// parent object with with object names
MyObjects mo = new MyObjects() { Active = true, OtherObjects = oNames };
and finally, the javascript serializer..
JavaScriptSerializer jss = new JavaScriptSerializer();
string b = jss.Serialize(mo);
string b should give you the output like below..
{
"Active":true
,"OtherObjects":[
{
"Name":"First"
,"OtherObjectProperties":[
{
"Id":2
,"Enabled":false}
]},
{
"Name":"Second"
,"OtherObjectProperties":[
{
"Id":3
,"Enabled":false}
]
}]
}
Please advise if you're confused about any of the following.. :)

Categories