In this code here I set the values to model classes from JSON file called myJson.code works fine and values binding to the model classes without any issues. My code as follows.
class Program
{
static void Main(string[] args)
{
ReadJson();
}
public static string ReadJson()
{
string case20 = "this is 20", case40 = "this is 40";
string json;
using (StreamReader r = new StreamReader(#"C:\Users\HP\Desktop\Output\myJson.json"))
{
json = r.ReadToEnd();
}
MyClass response = JsonConvert.DeserializeObject<MyClass>(json);
var dropDowns = response;
string jsonDropdown = JsonConvert.SerializeObject(dropDowns, Formatting.Indented);
return "";
}
}
Here is my model classes:
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
var rateVal = this.RATE;
switch (rateVal)
{
case 20:
return ""; // Here, I need to get value from the ReadJson method to return (value of case20)
case 40:
return ""; // Here, I need to get value from the ReadJson method to return (value of case40)
}
return "test";
}
}
}
public class MyClass
{
public string StatusCode { get; set; }
public Customer Customer { get; set; }
public object LoanDetail { get; set; }
}
After I set the values to model classes,from the Customer class I want to check the RATE and in order to the value of the RATE I want to return value of the case20 and case40 variable's value in the ReadJson() method. How can I access those value form Customer class.
Thanks in advance!!!
Updated:
This is sample JSON string
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue":""
},
"LoanDetail": null
}
According to belove JSON string, My output should be
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue":"this is 20"
},
"LoanDetail": null
}
Your functions are reading the JSON data from the string into your customer object.
Shouldn't the case20 & case40 be set in the customer object or program themselves?
You are not reading into the case20 or 40 strings from the JSON anywhere I could see. So I am assuming that their output does not change dynamically when running the program.
Also your var rateVale = this.rate; should be something like var rateVal = int.Parse(this.rate); as you are comparing it as an integer. either that or switch cases should be "20" not 20 etc.
Can you include an example of the code you have and what the appropriate object values should be and the output of the newValue parameter please?
Change your code according below and it does what you want. But I still cant understand why you need NewValue property while you have already RATE property. Does not they carrying same value? You setting NewValue based on RATE, why dont you use just RATE everywhere?
public static string ReadJson()
{
string json = File.ReadAllText(#"C:\Users\HP\Desktop\Output\myJson.json");
MyClass response = JsonConvert.DeserializeObject<MyClass>(json);
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
switch (RATE)
{
case 20:
return "this is 20";
case 40:
return "this is 40";
default:
return "";
}
}
}
}
public static void Main(string[] args)
{
Console.WriteLine(ReadJson());
}
The output is :
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue": "this is 20"
},
"LoanDetail": null
}
Thanks to everyone who helped me to solve this. I found the solution to solve my problem.
I created a static class, called TestCase.
public static class TestCase
{
public static string case20 { get; set; }
public static string case40 { get; set; }
}
Then set the values to those fields within the ReadJson()
public static string ReadJson()
{
TestCase.case20 = "this is 20";
TestCase case40 = "this is 40";
// same code has beign used....
}
Then within the Customer class, I accessed those values as follows.
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
switch (RATE)
{
case 20:
return TestCase.case20;
case 40:
return TestCase.case40;
default:
return "";
}
}
}
}
Related
I am using Newtonsoft.Json.JsonConvert.SerializeObject to convert a JsonPatchDocument<T> to string but it's value property (which is in JObject format) doesn't seem to be converted to string.
Here is what it looks like:
Here is the JSON I am using to create patchDocument object
[
{
"path": "/expenseLines/",
"op": "ReplaceById",
"value": {
"ExpenseLineId": 1,
"Amount": 4.0,
"CurrencyAmount": 4.0,
"CurrencyCode": "GBP",
"ExpenseDate": "2021-11-01T00:00:00",
"ExpenseType": "TAXI"
}
}
]
This JSON is successfully deserialized to JsonPatchDocument object but when I try to serialize it back to JSON, I lose value property (as shown in the picture by red arrows).
Any help would be appreciated :)
I can't reproduce your problem, can you provide more information? I got stuck during your second serialization. But I used using System.Text.Json to complete your needs, you can look at:
Model:
public class Test
{
public string path { get; set; }
public string op { get; set; }
public TestValue testValue { get; set; } = new TestValue();
}
public class TestValue
{
public int ExpenseLineId { get; set; }
public double Amount { get; set; }
public double CurrencyAmount { get; set; }
public string CurrencyCode { get; set; }
public DateTime ExpenseDate { get; set; }
public string ExpenseType { get; set; }
}
TestController:
[ApiController]
public class HomeController : Controller
{
[Route("test")]
public Object Index()
{
var patchDocument = new Test();
patchDocument.path = "/expenseLines/";
patchDocument.op = "ReplaceById";
patchDocument.testValue.ExpenseLineId = 1;
patchDocument.testValue.Amount = 4.0;
patchDocument.testValue.CurrencyAmount = 4.0;
patchDocument.testValue.CurrencyCode = "GBP";
patchDocument.testValue.ExpenseDate = DateTime.Now;
patchDocument.testValue.ExpenseType = "TAXI";
var options = new JsonSerializerOptions { WriteIndented = true };
// var content = JsonConvert.SerializeObject(patchDocument);
// string content1 = JsonConvert.SerializeObject(patchDocument.Operations);
string jsonString = System.Text.Json.JsonSerializer.Serialize<Test>(patchDocument);
string jsonString1 = System.Text.Json.JsonSerializer.Serialize(patchDocument, options);
return jsonString;
}
Result:
Hope this helps you too.
I am trying to map string value fields from MongoDB to integers in VisualStudio, using .NET. The fields have one of a few known values, like "pedestrian", "bicycle", "car". How can i check against these values and map them to be represented by "0", "1", "2"? I know the basics of automapper, but i cant find how to do this.
I am getting them as a List<> and they need to stay as a List<>.
Using:
VS 19
Automapper v8
Example of a MongoDB document:
{
"Street" : "Oak",
"Object" : "pedestrian",
"Id" : "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
"City" : "NY",
"Direction" : 0
}
Reading the rows:
public class Stuff
{
[BsonElement("_id")]
public ObjectId Id { get; set; }
public List<MyDocument> MyDocuments { get; set; }
}
...
var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<Stuff>("alma");
var rows = (await collection.FindAsync(FilterDefinition<Stuff>.Empty)).ToList();
Option 1:
You don't need to use Automapper for that, the MongoDB driver converts enums as long as the name of the option matches.
[BsonNoId]
public class MyDocument
{
public string Id { get; set; }
public string Street { get; set; }
public ObjectEnum Object { get; set; }
public string City { get; set; }
public int Direction { get; set; }
}
public enum ObjectEnum
{
None = 0,
pedestrian = 1,
bicycle = 2,
car = 3
}
...
foreach (var row in rows)
{
// use the enum, or if you need the associated number just use int cast
int myNumberRepresentation = (int)row.MyDocuments[0].Object;
}
Option 2:
Write custom serializer, and your return type can be anything you like:
public enum ObjectEnum
{
None = 0,
// notice the upper case
Pedestrian = 1,
Bicycle = 2,
Car = 3
}
[BsonNoId]
public class MyDocument
{
public string Id { get; set; }
public string Street { get; set; }
[BsonSerializer(typeof(CustomObjectSerializer))]
public ObjectEnum Object { get; set; }
public string City { get; set; }
public int Direction { get; set; }
}
public class CustomObjectSerializer: SerializerBase<ObjectEnum>
{
public override ObjectEnum Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var s = context.Reader.ReadString();
switch (s)
{
case "pedestrian":
return ObjectEnum.Pedestrian;
case "bicycle":
return ObjectEnum.Bicycle;
case "car":
return ObjectEnum.Car;
default:
return ObjectEnum.None;
}
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, ObjectEnum value)
{
string ret = "";
switch (value)
{
case ObjectEnum.Pedestrian:
ret = "pedestrian";
break;
case ObjectEnum.Bicycle:
ret = "bicycle";
break;
case ObjectEnum.Car:
ret = "car";
break;
}
context.Writer.WriteString(ret);
}
}
for two days I have been trying to understand how to move this JSON to an object in C#. I read a lot of topics and tried several ways to solve my problem, but still haven't solved it.
My JSON looks like this (cropped).
{
"data": [{
"id": 5643793,
"title": "It's a Title",
"description": "It's a Description.",
"tags": "#tag1 #tag2 #tag3 #tag4",
"source_url": "https:\/\/p.dw.com\/p\/3geny",
"vote_count": 120,
"bury_count": 17,
"comments_count": 33,
"related_count": 0,
"date": "2020-08-10 09:43:32",
"author": {
"login": "lnwsk",
"color": 2,
"avatar": "https:\/\/www.api.page.com\/cdn\/c3397992\/lnwsk_MfQz8MEQb2,q150.jpg"
},
"preview": "https:\/\/www.api.page.com\/cdn\/c3397993\/link_1597045214DgzqxRGEmy2UlpPZwaWfhI,w104h74.jpg",
"plus18": false,
"status": "promoted",
"can_vote": true,
"is_hot": false
}],
"pagination": {
"next": "https:\/\/api.page.com\/links\/promoted\/appkey\/X*******4y\/page\/2\/"
}
}
As you can see, there is an "element within an element" here (eg author or pagination (eg pagination I would like to get rid of)) and that is what gives me the most problem.
Here is my class where I have all the code to read the API:
using Newtonsoft.JSON;
public class PageAPI
{
public class Product
{
public string[] title { get; set; }
public double[] description { get; set; }
public string[] tags { get; set; }
public string[] source_url { get; set; }
public string[] vote_count { get; set; }
public string[] bury_count { get; set; }
public string[] comments_count { get; set; }
public string[] related_count { get; set; }
public string[] date { get; set; }
}
public async Task<Product> GetDataAsync()
{
string url = "https://api.page.com/";
string apisign = "6*********c1fe49a23f19ad6b2";
string requestParams = "links/promoted/appkey/X*******y";
Product obj = null;
// HTTP GET.
using (var client = new HttpClient())
{
// Setting Base address.
client.BaseAddress = new Uri(url);
// Setting content type.
client.DefaultRequestHeaders.Add("apisign", apisign);
// Initialization.
HttpResponseMessage response = new HttpResponseMessage();
// HTTP GET
response = await client.GetAsync(requestParams).ConfigureAwait(false);
// Verification
if (response.IsSuccessStatusCode)
{
try
{
// Reading Response.
string result = response.Content.ReadAsStringAsync().Result;
obj = JsonConvert.DeserializeObject<Product>(result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
}
}
else
{
obj = null;
}
}
return obj;
}
}
in the Form where I want to get data from the "PageAPI" class I have:
private async void Form1_LoadAsync(object sender, EventArgs e)
{
var task = api.GetMainAsync();
task.Wait();
var data = task.Result;
label1.Text = data.title[0];
}
And... this doesn't works - on label1.Text = data.title[0]; i get error PageAPI.Product.title.get returned null
Thanks for any help!
You are missing the Root class that has "data" and "pagination" properties. Create Root class and deserialize to it and then get the data you need. Also, your Product class will have only strings.. not string[].
public class RootObject
{
public List<Product> data { get; set; }
}
public class Product
{
public string title { get; set; }
public double description { get; set; }
public string tags { get; set; }
public string source_url { get; set; }
public string vote_count { get; set; }
public string bury_count { get; set; }
public string comments_count { get; set; }
public string related_count { get; set; }
public string date { get; set; }
}
// and deserialize it
var rootObj = JsonConvert.DeserializeObject<RootObject>(result);
obj = rootObj.data.FirstOrDefault();
data object is an array ... you can loop through it to work with All the items. In above example, i used FirstOrDefault() to get the first item from the object.
Also note that when you access this data, you would not access it via [0]. Simply use
label1.Text = data.title;
Side Note
If you want the pagination property as well, create another class to get the name from pagination object.
public class RootObject {
public List<Product> data {get;set;}
public Pagination pagination {get;set;}
}
public class Pagination {
public string next {get;set; }
}
and when you deserialize your json, you would access the pagination by using,
Console.WriteLine(rootObj.pagination.next); // prints the url
How to get All the Product Names displayed
This is how you would go about getting a list of All the titles in the data object.
foreach (var product in rootObj.data)
{
Console.WriteLine(product.title);
Console.WriteLine(product.description);
Console.WriteLine(product.vote_count); // etc.
}
// Or you can create a list of all the titles from the rootObj using LINQ
List<string> allTitles = rootObj.data.Select(x => x.title).ToList();
I am not sure what you intend to do with the data you get... so not sure how to explain that piece.. but above example should give you an idea on how to iterate through all the products in the data object.
I'm trying to deserialize a JSon object with an Anroid app, but can't get it running. The intention is to read data from an asset item ("AllPoloniexPairs.txt"), which is the JSON objrct I'm trying to deserialyze and get "currencyPairs" from the Data part and put it into the spinner.
Below is (part of) my JSON
{"BTC_BCN":{"id":7,"baseID":28,"quoteID":17,"base":"BTC","quote":"BCN","currencyPair":"BTC_BCN"},"BTC_BTS":{"id":14,"baseID":28,"quoteID":32,"base":"BTC","quote":"BTS","currencyPair":"BTC_BTS"}}
This is my code
public class Data
{
public int id { get; set; }
public int baseID { get; set; }
public int quoteID { get; set; }
public string Base { get; set; }
public string Quote { get; set; }
public string currencyPair { get; set; }
}
public class Pairs
{
public string id { get; set; }
public Data data { get; set; }
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
using (StreamReader sr = new StreamReader(assets.Open("AllPoloniexPairs.txt")))
{
content = sr.ReadToEnd();
}
Pairs pairs = JsonConvert.DeserializeObject<Pairs>(content);
ArrayAdapter<String> adapter;
Spinner spinner2 = (Spinner)FindViewById(Resource.Id.spinner2);
List<string> spinnerItems = new List<string>();
foreach (var k in pairs.data.currencyPair)
{
spinnerItems.Add(k.ToString());
}
spinnerItems.Sort();
adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerDropDownItem, spinnerItems);
spinner2.Adapter = adapter;
}
When I skip the foreach loop the app runs, but of course with no items in the spinner. If I include the foreach part, the application hangs.
I have tried several things now for the last couple of hours, but without any luck.
What could be the reason that the code doesn't run?
Well why do you reinvent the wheel google has already done it for you you can do it in two lines of code:
https://github.com/google/gson
Gson gson = new Gson();
MyClass myClass= gson.fromJson(json, MyClass.class);
Well sorry for the delay was figuring your json data and it seems wrong to me and GSON you better use something like :
[
{
"id": 7,
"baseID": 28,
"quoteID": 17,
"base": "BTC",
"quote": "BCN",
"currencyPair": "BTC_BCN"
},
{
"id": 14,
"baseID": 28,
"quoteID": 32,
"base": "BTC",
"quote": "BTS",
"currencyPair": "BTC_BTS"
}
]
You were using an object which has two objects in it.
That's not an array remember array should have brackets.
Now let's do this with the above json we have a class called MyClass let's say:
public class MyClass {
int id;
int baseID;
int quoteID;
String base;
String quote;
String currencyPair;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBaseID() {
return baseID;
}
public void setBaseID(int baseID) {
this.baseID = baseID;
}
public int getQuoteID() {
return quoteID;
}
public void setQuoteID(int quoteID) {
this.quoteID = quoteID;
}
public MyClass(String currencyPair) {
this.currencyPair = currencyPair;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
}
Now in your activity use:
Gson gson = new Gson();
String jsonOutput = "[{\"id\":7,\"baseID\":28,\"quoteID\":17,\"base\":\"BTC\",\"quote\":\"BCN\",\"currencyPair\":\"BTC_BCN\"},{\"id\":14,\"baseID\":28,\"quoteID\":32,\"base\":\"BTC\",\"quote\":\"BTS\",\"currencyPair\":\"BTC_BTS\"}]";
MyClass[] posts = gson.fromJson(jsonOutput, MyClass[].class);
Log.v("SteveMoretz", String.valueOf(posts.length));
You will get 2 by the Log which means you have two objects now you can use where ever you want.:)
Trying to get the result from a webservice call to return a Model. I eep getting the error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'CI.Models.Schedule' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
public Schedule getCourseSchedule()
{
var obj = new
{
States = new[] { new { State = "MX" } },
Zip = "",
Miles = "",
PaginationStart = 1,
PaginationLimit = 3
};
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "apoplication/json";
var url = "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule";
var json = JsonConvert.SerializeObject(obj);
byte[] data = Encoding.UTF8.GetBytes(json);
byte[] result = client.UploadData(url, data);
string returnjson = Encoding.UTF8.GetString(result);
Schedule sched = JsonConvert.DeserializeObject<Schedule>(returnjson);
return sched;
}
}
Schedule Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
namespace CI.Models
{
public class Schedule
{
public IEnumerable<Course> Courses { get; set; }
}
public class Course
{
/*
JSON Data returned from web service:
{
"ProgramGroup":"MR",
"ProgramCode":"RM",
"EventCode":"20160901MXMR",
"FormalDate":"September 1-2, 2016",
"StartDate":"2016\/09\/01",
"Price":5,
"LocName":"WB Hotel",
"LocAddress":"Av. Speedy Gonzales 220",
"LocCity":"Monterrey",
"LocState":"MX",
"LocZipCode":null,
"LicenseeURL":null,
"AgendaURL":"NA",
"SeatsAreAvailable":"2",
"GeneralInfoHTML":"General Info goes here.",
"GateKeeperHTML":null,
"EventType":"SS",
"TotalCourses":3
}
*/
public string ProgramGroup { get; set; }
public string ProgramCode { get; set; }
public string EventCode { get; set; }
public string FormalDate { get { return FormalDate; } set { FormalDate = convertFormalDateToSpanish(value); } }
public string StartDate { get; set; }
public double Price { get; set; }
public string LocName { get; set; }
public string LocAddress { get; set; }
public string LocCity { get ; set; }
public string LocState { get; set; }
public string LocZipCode { get; set; }
public string LicenseeURL { get; set; }
public string AgendaURL { get { return AgendaURL; } set { AgendaURL = buildAgendaLink(value); } }
public string SeatsAreAvailable { get; set; }
public string GeneralInfoHTML { get; set; }
public string GateKeeperHTML { get; set; }
public string EventType { get; set; }
public int TotalCourses { get; set; }
public string convertFormalDateToSpanish(string val)
{
DateTime TheDate = DateTime.Parse(StartDate);
string[] FormalDate = val.Split(" ".ToCharArray());
CultureInfo ci = new CultureInfo("es-ES");
string _Date = FormalDate[1].Replace("-", " al ").Replace(",", "");
string _Month = ci.TextInfo.ToTitleCase(TheDate.ToString("MMMM", ci));
val = string.Concat(_Date, " ", _Month);
return val;
}
private string buildAgendaLink(string val)
{
if (val.Trim() != "")
{
val = string.Concat("Agenda");
}
else
{
val = "Agenda";
}
return val;
}
}
}
Your server returns an array. Just try
Course[] courses = JsonConvert.DeserializeObject<Course[]>(returnjson);
Note that this is not an answer to your original problem, but I added it like an answer in order to explain my comment above with some actual code.
First problem with your code is that FormalDate and AgendaUrl properties simply won't work. Accessing them will result in a StackOverflowException, because you basically defined them recursively.
A property is merely syntax sugar for two separate getter/setter methods, so by writing this:
public class Course
{
public string FormalDate
{
get { return FormalDate; }
}
}
You are basically writing this:
public class Course
{
public string GetFormalDate()
{
// recursive call, with no terminating condition,
// will infinitely call itself until there is no
// more stack to store context data (and CLR
// will then throw an exception)
return GetFormalDate();
}
}
To fix that, you need to add an actual backing field, e.g.:
public class Course
{
private string _formalDate; // <-- this is a backing field;
// and this property uses the backing field to read/store data
public string FormalDate
{
get { return _formalDate; }
set { _formalDate = convertFormalDateToSpanish(value); }
}
}
Additionally, it's unusual for a property getter to return a different value than the one set through a setter. In other words, I would never expect this from a class:
var course = new Course();
course.StartDate = "2016/09/01";
course.FormalDate = "September 1-2, 2016";
Console.WriteLine(course.FormalDate); // prints "1 al 2 Septiembre" ?
I would rather move this functionality into a different class, or at least create different properties which return these values:
public class CourseInfo
{
// this is now a "dumb" auto-implemented property
// (no need for a backing field anymore)
public string FormalDate { get; set; }
// this read-only property returns the converted value
public string LocalizedFormalDate
{
get
{
return convertFormalDateToSpanish(FormalDate);
}
}
}