Loop for add a json for each object in list - c#

I'm making a tool that needs to export a json. He needs to be in this format:
{
"version" : "2",
"mangas" : [ {
"manga" : [ "sample", "manganame", 1234567890, 0, 0 ],
"chapters" : [ {
"u" : "urlexample",
"r" : 1
}, {
"u" : "urlexample",
"r" : 1
}, {
"u" : "urlexample",
"r" : 1
} ]
} ]
}
And this is my code:
void createJson(String manganame, String mangaoid, String sourceid)
{
String[] mangainfo = { "/manga/" + mangaoid, manganame, sourceid, "0", "0" };
var root = new RootObject()
{
version = "2",
mangas = new List<Manga>()
{
new Manga()
{
manga = mangainfo,
chapters = new List<Chapter>()
{
new Chapter
{
u = "sample",
r = 1
}
}
}
}
};
var json = JsonConvert.SerializeObject(root);
File.WriteAllText(#"D:\path.txt", json);
Console.WriteLine(json);
}
I'm lost, if someone can help me. Already give a search on Google, but the answer didn't come up in my head, already trying for a few time, slowly I'm getting but now is time to ask for help lol
For the list I was talking about, I'll explain it. I have a sqlite DB that have various information from mangas etc... I execute a query where I filter by a id, "SELECT * FROM MangaChapter WHERE manga_id = 'someid'", then i put the result on a list using a for loop. In the DB chapter url is stored like that "mr-chapter-166165" this is why i have had to concat string in chapterList.add.
List<String> chapterList = new List<String>();
cmd.CommandText = "SELECT * FROM MangaChapter WHERE manga_id = '3252'";
reader = cmd.ExecuteReader();
while (reader.Read())
{
chapterList.Add("/pagesv2?oid=" + reader.GetString("oid"));
}
For reference this is what I'm using to manage the sqlite db https://www.nuget.org/packages/dotConnect.Express.for.SQLite/
In the list, each chapter is something like that "/pagesv2?oid=mr-chapter-166165", if I print all the list on the console we'll be having something like that:
/pagesv2?oid=mr-chapter-166165
/pagesv2?oid=mr-chapter-166166
/pagesv2?oid=mr-chapter-166167

Here are the classes I generated from the given JSON sample
public class Chapter
{
[JsonProperty("u")]
public string U { get; set; }
[JsonProperty("r")]
public int R { get; set; }
}
public class Manga
{
[JsonProperty("manga")]
public IList<object> MangaInfos { get; set; }
[JsonProperty("chapters")]
public IList<Chapter> Chapters { get; set; }
}
public class Example
{
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("mangas")]
public IList<Manga> Mangas { get; set; }
}
and here the code to reproduce the give JSON sample
var d = new Example
{
Version = "2",
Mangas = new List<Manga>
{
new Manga()
{
MangaInfos = new List<object>{ "sample", "manganame", 1234567890, 0, 0 },
Chapters = new List<Chapter>
{
new Chapter()
{
U = "urlexample",
R = 1,
},
new Chapter()
{
U = "urlexample",
R = 1,
},
new Chapter()
{
U = "urlexample",
R = 1,
},
},
},
},
};
var json = JsonConvert.SerializeObject(d,Formatting.Indented);
Console.WriteLine(json);
The output looks like
{
"version": "2",
"mangas": [
{
"manga": [
"sample",
"manganame",
1234567890,
0,
0
],
"chapters": [
{
"u": "urlexample",
"r": 1
},
{
"u": "urlexample",
"r": 1
},
{
"u": "urlexample",
"r": 1
}
]
}
]
}
and live view at .net fiddle

Based on your comment, if you want to have various chapters for each "Manga", you have to change your data structure and that changes the Result Json you want.
maybe something like this?
public partial class Root
{
public long Version { get; set; }
public Mangas[] Mangas { get; set; }
}
public partial class Mangas
{
public Manga[] Manga { get; set; }
}
public partial class Chapter
{
public string U { get; set; }
public long R { get; set; }
}
public partial struct Manga
{
public long? Integer;
public string String;
public Chapter[] Chapters { get; set; }
}

Iterate through chapters. Solution below.
class Parent
{
public int Version { get; set; }
public List<Manga> mangas { get; set; }
}
class Manga
{
public List<object> manga { get; set; }
public List<Chapter> chapters { get; set; }
}
class Chapter
{
public string u { get; set; }
public int r { get; set; }
}
void createJson(String manganame, string mId, String mangaoid, long sourceid)
{
var json = new Parent()
{
Version = 2,
mangas = new List<Manga>()
{
new Manga()
{
manga = new List<object>{ "/manga/"+mangaoid, manganame, sourceid, 0, 0 },
chapters = Chapters(),
}
}
};
var sjson = JsonConvert.SerializeObject(json, Formatting.Indented);
File.WriteAllText(#"C:\Users\Izurii\Desktop\oi.json", sjson);
}
List<Chapter> Chapters()
{
List<Chapter> chapters = new List<Chapter>();
for(int i = 0; i < links.Count; i ++)
{
chapters.Add(
new Chapter()
{
u = links[i],
r = 1,
});
}
return chapters;
}

Related

Dapper ORM multiple level nested object

I'm trying to return SQL Server data using Dapper ORM that had nested object, so far here is what I'm doing
Model class
public class CustomerAll
{
public string KODELANG { get; set; }
public string GRUPLANG { get; set; }
public string NAMALANG { get; set; }
public string ALAMAT { get; set; }
public string STATUS { get; set; }
public List<NoDiscount> DISC_ACTIVE { get; set; }
}
public class NoDiscount
{
public string NO_DISC { get; set; }
public List<ProductDiscount> LIST_PRODUCT{ get; set; }
}
public class ProductDiscount
{
public string KODEPROD{ get; set; }
}
Raw query
SELECT CUSTOMER.KODELANG
,CUSTOMER.GRUPLANG
,CUSTOMER.NAMALANG
,CUSTOMER.ALAMAT
,CUSTOMER.STATUS
,DISCOUNT.NO_DISC
,PRODUCT.KODEPROD
FROM CUST_TABLE CUSTOMER, DCNT_TABLE DISCOUNT, PRODUCT_TABLE PRODUCT
WHERE CUSTOMER.KODELANG = DISCOUNT.KODELANG
AND DISCOUNT.NO_DISC = PRODUCT.NO_DISC
AND CUSTOMER.KODELANG = #CustNum
Controller class
var parameters = new { CustNum = customerNumber };
var lookup = new Dictionary<string, CustomerAll>();
con.Query<CustomerAll, NoDiscount, ProductDiscount, CustomerAll>(
querySql,
(c, n, p) =>
{
CustomerAll customer;
if (!lookup.TryGetValue(c.KODELANG, out customer))
{
lookup.Add(c.KODELANG, customer = c);
}
if (customer.DISC_ACTIVE == null)
{
customer.DISC_ACTIVE = new List<NoDiscount>();
}
if (p != null)
{
if (n.LIST_PRODUCT == null)
{
n.LIST_PRODUCT = new List<ProductDiscount>();
}
n.LIST_PRODUCT.Add(p);
}
customer.DISC_ACTIVE.Add(n);
return customer;
}
,parameters
,splitOn: "KODELANG, NO_DISC, KODEPROD");
return Ok(lookup.Values);
Here is what response returned
[
{
"KODELANG": "101308",
"GRUPLANG": "22",
"NAMALANG": "Name Example",
"ALAMAT": "Street number 4",
"STATUS": "A",
"DISC_ACTIVE": [
{
"NO_DISC": "DISC/1021/0001",
"LIST_PRODUCT": [
{
"KODEPROD": "TLBCA"
}
]
},
{
"NO_DISC": "DISC/1021/0001",
"LIST_PRODUCT": [
{
"KODEPROD": "TLBCB"
}
]
},
{
"NO_DISC": "DISC/3304/0009",
"LIST_PRODUCT": [
{
"KODEPROD": "ZVKAA"
}
]
}
]
}
]
What i'm trying to had is to be returned like these
[
{
"KODELANG": "101308",
"GRUPLANG": "22",
"NAMALANG": "Name Example",
"ALAMAT": "Street number 4",
"STATUS": "A",
"DISC_ACTIVE": [
{
"NO_DISC": "DISC/1021/0001",
"LIST_PRODUCT": [
{
"KODEPROD": "TLBCA"
},
{
"KODEPROD": "TLBCB"
},
{
"KODEPROD": "TLBCC"
}
]
},
{
"NO_DISC": "DISC/3304/0001",
"LIST_PRODUCT": [
{
"KODEPROD": "ZVKAA"
}
]
}
]
}
]
I don't want the LIST_PRODUCT getting added again if the NO_DISC are the same
Try this, beware that same NoDiscount object may have duplicate copys in diffierent customers.
var parameters = new { CustNum = customerNumber };
var customDict = new Dictionary<string, CustomerAll>();
con.Query<CustomerAll, NoDiscount, ProductDiscount, CustomerAll>(
querySql,
(c, n, p) =>
{
CustomerAll customer = null;
if (customDict.ContainsKey(c.KODELANG))
{
customer = customDict[c.KODELANG];
}
else
{
var customerObj = new CustomerAll()
{
KODELANG = c.KODELAN,
DISC_ACTIVE = new List<NoDiscount>()
};
customDict.Add(c.KODELANG, customerObj);
};
NoDiscount noDiscount = customer.DISC_ACTIVE.FirstOrDefault(x => x.NO_DISC == n.NO_DISC);
if (noDiscount ==null)
{
var noDiscountObj = new NoDiscount()
{
NO_DISC = n.NO_DISC,
LIST_PRODUCT = new List<ProductDiscount>()
};
noDiscount = noDiscountObj;
customer.DISC_ACTIVE.Add(noDiscountObj);
}
if (p != null && !noDiscount.LIST_PRODUCT.Contains(x=>x.KODEPROD==p.KODEPROD))
{
noDiscount.LIST_PRODUCT.Add(p);
}
return customer;
}
, parameters
, splitOn: "KODELANG, NO_DISC, KODEPROD");
return Ok(customDict.Values);

How to receive JSON data in Dictionary using FromData in Web api?

Below is JSON example which client will send to my API named as 'GetQuestion'
{
"lstQuestions": [{
"QuestionCategory": 1,
"QuestionText": "what is m in mvc",
"OptionA": "model",
"OptionB": "view",
"OptionC": "controller",
"OptionD": "razor",
"CorrectOption": "A"
},
{
"QuestionCategory": 2,
"QuestionText": "How are you",
"OptionA": "fine",
"OptionB": "not fine",
"OptionC": "ok",
"OptionD": "not ok",
"CorrectOption": "A"
}],
"Status" : 1
}
Below is my controller API code:
public class QuestionDetails
{
public List<Questions> lstQuestions { get; set; }
public int Status { get; set; }
}
public class Questions
{
public string QuestionCategory { get; set; }
public string QuestionText { get; set; }
public string OptionA { get; set; }
public string OptionB { get; set; }
public string OptionC { get; set; }
public string OptionD { get; set; }
public string CorrectOption { get; set; }
}
[Route("GetQuestions")]
[HttpPost]
public HttpResponseMessage SendQuestionDetails([FromBody] QuestionDetails UserDetailInput)
{
HttpResponseMessage mesage = Request.CreateResponse(HttpStatusCode.OK, "Demo"); ;
if (ModelState.IsValid)
{
//in progress
}
return mesage;
}
What I want to do is how to create a class with Dictionary and pass as parameter, I don't want to use List because its heavy and Dictionary is much faster than List.
For example:
public class QuestionDetails
{
public Dictionary<string, Questions> lstQuestions { get; set; }
public int Status { get; set; }
}
public HttpResponseMessage SendQuestionDetails([FromBody] Dictionary<string, QuestionDetails> UserDetailInput)
{
HttpResponseMessage mesage = Request.CreateResponse(HttpStatusCode.OK, "Demo"); ;
if (ModelState.IsValid)
{
//in progress
}
return mesage;
}
Don't know what are you talking about with Dictionary is much faster than List but you just need to send the JSON as
{
"A": {
"lstQuestions": {
"A": {
"QuestionCategory": 1,
"QuestionText": "what is m in mvc",
"OptionA": "model",
"OptionB": "view",
"OptionC": "controller",
"OptionD": "razor",
"CorrectOption": "A"
},
"V": {
"QuestionCategory": 2,
"QuestionText": "How are you",
"OptionA": "fine",
"OptionB": "not fine",
"OptionC": "ok",
"OptionD": "not ok",
"CorrectOption": "A"
}
},
"Status": 1
}
}
Hope below code will clear your query.
public HttpResponseMessage SendQuestionDetails([FromBody] Dictionary<string, QuestionDetails> UserDetailInput)
{
List<Questions> list = new List<Questions> { };
list.Add(new Questions
{
CorrectOption = "CorrectOption1",
OptionA = "OptionA1",
OptionB = "OptionB1",
OptionC = "OptionC1",
OptionD = "OptionD1",
QuestionCategory = "QuestionCategory1",
QuestionText = "QuestionText1"
});
list.Add(new Questions
{
CorrectOption = "CorrectOption2",
OptionA = "OptionA2",
OptionB = "OptionB2",
OptionC = "OptionC2",
OptionD = "OptionD2",
QuestionCategory = "QuestionCategory2",
QuestionText = "QuestionText2"
});
Dictionary<QuestionDetails, int> dictionary = new Dictionary<QuestionDetails, int> { };
QuestionDetails detail = new QuestionDetails { lstQuestions = list, Status = 1 };
HttpResponseMessage mesage = Request.CreateResponse(HttpStatusCode.OK, detail);
return mesage;
return mesage;
}

How can I create a JsonPatchDocument from comparing two c# objects?

Given I have two c# objects of the same type, I want to compare them to create a JsonPatchDocument.
I have a StyleDetail class defined like this:
public class StyleDetail
{
public string Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public decimal OriginalPrice { get; set; }
public decimal Price { get; set; }
public string Notes { get; set; }
public string ImageUrl { get; set; }
public bool Wishlist { get; set; }
public List<string> Attributes { get; set; }
public ColourList Colours { get; set; }
public SizeList Sizes { get; set; }
public ResultPage<Style> Related { get; set; }
public ResultPage<Style> Similar { get; set; }
public List<Promotion> Promotions { get; set; }
public int StoreStock { get; set; }
public StyleDetail()
{
Attributes = new List<string>();
Colours = new ColourList();
Sizes = new SizeList();
Promotions = new List<Promotion>();
}
}
if I have two StyleDetail objects
StyleDetail styleNew = db.GetStyle(123);
StyleDetail styleOld = db.GetStyle(456);
I now want to create a JsonPatchDocument so I can send the differences to my REST API... How to do this??
JsonPatchDocument patch = new JsonPatchDocument();
// Now I want to populate patch with the differences between styleNew and styleOld - how?
in javascript, there is a library to do this https://www.npmjs.com/package/rfc6902
Calculate diff between two objects:
rfc6902.createPatch({first: 'Chris'}, {first: 'Chris', last:
'Brown'});
[ { op: 'add', path: '/last', value: 'Brown' } ]
but I am looking for a c# implementation
Let's abuse the fact that your classes are serializable to JSON!
Here's a first attempt at a patch creator that doesn't care about your actual object, only about the JSON representation of that object.
public static JsonPatchDocument CreatePatch(object originalObject, object modifiedObject)
{
var original = JObject.FromObject(originalObject);
var modified = JObject.FromObject(modifiedObject);
var patch = new JsonPatchDocument();
FillPatchForObject(original, modified, patch, "/");
return patch;
}
static void FillPatchForObject(JObject orig, JObject mod, JsonPatchDocument patch, string path)
{
var origNames = orig.Properties().Select(x => x.Name).ToArray();
var modNames = mod.Properties().Select(x => x.Name).ToArray();
// Names removed in modified
foreach (var k in origNames.Except(modNames))
{
var prop = orig.Property(k);
patch.Remove(path + prop.Name);
}
// Names added in modified
foreach (var k in modNames.Except(origNames))
{
var prop = mod.Property(k);
patch.Add(path + prop.Name, prop.Value);
}
// Present in both
foreach (var k in origNames.Intersect(modNames))
{
var origProp = orig.Property(k);
var modProp = mod.Property(k);
if (origProp.Value.Type != modProp.Value.Type)
{
patch.Replace(path + modProp.Name, modProp.Value);
}
else if (!string.Equals(
origProp.Value.ToString(Newtonsoft.Json.Formatting.None),
modProp.Value.ToString(Newtonsoft.Json.Formatting.None)))
{
if (origProp.Value.Type == JTokenType.Object)
{
// Recurse into objects
FillPatchForObject(origProp.Value as JObject, modProp.Value as JObject, patch, path + modProp.Name +"/");
}
else
{
// Replace values directly
patch.Replace(path + modProp.Name, modProp.Value);
}
}
}
}
Usage:
var patch = CreatePatch(
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "1", Removed = "1" },
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "2", Added = new { x = "1" } });
// Result of JsonConvert.SerializeObject(patch)
[
{
"path": "/Removed",
"op": "remove"
},
{
"value": {
"x": "1"
},
"path": "/Added",
"op": "add"
},
{
"value": "2",
"path": "/Changed",
"op": "replace"
}
]
You could use my DiffAnalyzer. It's based on reflection and you can configure the depth you want to analyze.
https://github.com/rcarubbi/Carubbi.DiffAnalyzer
var before = new User { Id = 1, Name="foo"};
var after= new User { Id = 2, Name="bar"};
var analyzer = new DiffAnalyzer();
var results = analyzer.Compare(before, after);
You can use this
You can install using NuGet, see SimpleHelpers.ObjectDiffPatch at NuGet.org
PM> Install-Package SimpleHelpers.ObjectDiffPatch
Use:
StyleDetail styleNew = new StyleDetail() { Id = "12", Code = "first" };
StyleDetail styleOld = new StyleDetail() { Id = "23", Code = "second" };
var diff = ObjectDiffPatch.GenerateDiff (styleOld , styleNew );
// original properties values
Console.WriteLine (diff.OldValues.ToString());
// updated properties values
Console.WriteLine (diff.NewValues.ToString());

MongoDB: query date by year C#

Having such a document:
var document = new BsonDocument
{
{ "address" , new BsonDocument
{
{ "street", "2 Avenue" },
{ "zipcode", "10075" },
{ "building", "1480" },
{ "coord", new BsonArray { 73.9557413, 40.7720266 } }
}
},
{ "borough", "Manhattan" },
{ "cuisine", "Italian" },
{ "grades", new BsonArray
{
new BsonDocument
{
{ "date", new DateTime(2014, 10, 1, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "A" },
{ "score", 11 }
},
new BsonDocument
{
{ "date", new DateTime(2014, 1, 6, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "B" },
{ "score", 17 }
}
}
},
{ "name", "Vella" },
{ "restaurant_id", "41704620" }
};
How would I query for grades.date.year = 2016?
Was trying:
var filter = Builders<BsonDocument>.Filter.Eq("grades.date.year", 2016);
var result = await collection.Find(filter).ToListAsync();
But I guess dot notation only works on the json doc, not the objects? Scoured the internet, but couldn't find a clean example.
EDIT: C# classes?
class Address
{
public string street { get; set; }
public string zipcode { get; set; }
public string building { get; set; }
public IEnumerable<double> coord { get; set; }
}
class Grade
{
public DateTime date { get; set; }
public string grade { get; set; }
public int score { get; set; }
}
class TestX
{
public ObjectId _id { get; set; }
public Address address { get; set; }
public string borough { get; set; }
public string cuisine { get; set; }
public IEnumerable<Grade> grades { get; set; }
public string name { get; set; }
public string restaurant_id { get; set; }
}
This requires aggregation framework.
If you could post c# class then will update my answer to strongly typed c# , but now decided to project year inside project phase.
public static void Main()
{
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("test");
var collection = database.GetCollection<BsonDocument>("hammer");
var project =
BsonDocument.Parse(
"{_id: 1,address: 1,borough: 1,cuisine: 1,grades: 1,name: 1,restaurant_id: 1,year: {$year: '$grades.date'}}");
var aggregationDocument =
collection.Aggregate()
.Unwind("grades")
.Project(project)
.Match(BsonDocument.Parse("{'year' : {$in : [2013, 2015]}}"))
.ToList();
foreach (var result in aggregationDocument)
{
Console.WriteLine(result.ToString());
}
Console.ReadLine();
}
edit
var aggregationDocument =
collection.Aggregate<TestX>()
.Unwind<TestX>(x=>x.grades)
.Match(BsonDocument.Parse(
"{$and:[{'grades.date':{$gte: ISODate('2012-01-01')}},{'grades.date':{$lt: ISODate('2013-01-01')}}]}"))
.ToList();
Couldn't another approach be to check if date is within that year.
I.e for 2016 using $gte: 2016-01-01 00:00:00 and $lt: 2017-01-01 00:00:00
Find objects between two dates MongoDB
There are probably functions for them in c# like Gte and Lt. There are probably some easy way to combine the filters like with an & or similar.

Json not returning the correct values in the desired pattern

I need this as my json return. This data is being pulled from the DB but currently I am using static data.
{
"data": [
{
"id": 1,
"latitude":17.3700,
"longitude": 78.4800,
"gallery":
[
"assets/img/items/1.jpg"
]
}
]
}
I have tried this in my code behind but I am not getting the desired result.
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public List<> getData()
{
Account account = new Account
{
id = 1,
latitude = "17.3700",
longitude ="78.4800",
gallery = new List<string>
{
"assets/img/items/1.jpg",
"assets/img/items/2.jpg",
}
};
return new JavaScriptSerializer().Serialize(account);
}
public class Account
{
public int id { get; set; }
public string latitude { get; set; }
public string longitude { get; set; }
public IList<string> gallery { get; set; }
}
Result:
{
"id":2,
"latitude":"17.3700",
"longitude":"78.4800",
"gallery":["assets/img/items/1.jpg","assets/img/items/2.jpg"]
}
You need to create a new class with the data property:
public class Result { public object[] Data { get; set; } }
and return that:
public string getData()
{
Result result = new Result
{
Data = new [] { new Account { id = 1, ... } }
};
return new JavaScriptSerializer().Serialize(result);
}

Categories