Serializing an object as Json - c#

I'm attempting to serialize an object as Json. The error returned by the code below is "An instance of type string cannot be assigned to a variable of type JsonResult". Can someone explain what I've done wrong? I thought serialize() accepts an object and that's what I am passing it.
public class SummaryStats
{
public int rating_number { get; set; }
public string rating_label { get; set; }
public string rating_view { get; set; }
public int max_stars { get; set; }
public int star_1_rating { get; set; }
public int star_2_rating { get; set; }
public int star_3_rating { get; set; }
public int star_4_rating { get; set; }
public int star_5_rating { get; set; }
}
public JsonResult GetSummaryStats()
{
SummaryStats stats = new SummaryStats();
stats.star_1_rating = 1;
stats.star_2_rating = 1;
stats.star_3_rating = 1;
stats.star_4_rating = 11;
stats.star_5_rating = 20;
JavaScriptSerializer json = new JavaScriptSerializer();
JsonResult output = json.Serialize(stats);
return output;
}

Assuming this is within a Controller derivative, just do:
return Json(stats);
The rest is handled for you.

Try Serializing your class :
[Serializable()]
public class SummaryStats
{
...
}

Related

Deserialize JSON string when there is dynamic type JSON array in that object

I have a JSON string like this
{
Success :1,PageNumber :1,TotalPages :5,Data:[{projectName:'Pr1',ProjectId:'p3452'},{projectName:'Pr2',ProjectId:'p5485'}....]
}
Here is my class structure for that
public class KipReport
{
public bool Success { get; set; }
public int PageNumber { get; set; }
public int RecordsPerPage { get; set; }
public int TotalPages { get; set; }
public int TotalRecords { get; set; }
public object Data { get; set; }
}
Here the Data part I cant specify a constant type because it may change from report to report... I some other reports data will be like
{
reportID:33,pageNumber:1,totalPages:15,Data:[{EmpName:'EMP1',Department:'R&D',EmpId:234},{EmpName:'Emp2',Department:'Software Development',EmpId:366}....]
}
So I have different classes for these Data part
class project{
public string ProjectId{get;set;}
public string ProjectName{get;set}
}
class Employee{
public string EmpName{get;set;}
publis string EmpId{get;set;}
public string Department{get;set}
}
This is how I deserialize using Newtonsoft
rpt = JsonConvert.DeserializeObject<KipReport>(responseBody);
So once the rpt is deserialized (works fine) I have a switch case in which i am taking the Data part into corresponding object
Switch(reportid){
case 1:
List<Project> jsonPS = new List<Project>();
jsonPS =(List<Project>)rpt.Data;
break;
case 2:
List<Employee> jsonPS = new List<Employee>();
jsonPS =(List<Employee>)rpt.Data;
break;
}
But its not at all working and this is the error
Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type
'System.Collections.Generic.List`1[common.ProjectS]'.
So what I did wrong or how can I make it work
I suggest you make the KipReport generic.
public class KipReport<T>
{
public bool Success { get; set; }
public int PageNumber { get; set; }
public int RecordsPerPage { get; set; }
public int TotalPages { get; set; }
public int TotalRecords { get; set; }
public IList<T> Data { get; set; } // Also note here, it is a List, not a single object
}
When you deserialize, specify the type:
JsonConvert.DeserializeObject<KipReport<project>>(responseBody);
JsonConvert.DeserializeObject<KipReport<Employee>>(responseBody);
If you want to know the type before deserializing, so that you know which deserialization to perform, maybe perform a string check by some keyword beforehand.
You can try to do this way:
var result = rpt.Data.OfType<Employee>();
var result2 = rpt.Data.OfType<project>();
Example:
object[] obj = { 1, "2" };
var result = obj.OfType<string>();
// result = "2"

json string do not fit in my made class using Xamarin

i´m in the middle of a project and i just got stuck. My problem is parsing the Json string to my class. This is my Json:
{
"ReturnCode": 0,
"CampaignId": 155087586,
"TotalSMSSent": 1,
"TotalSMSwithError": 0,
"MSISDNwithErrorList": {
}
}
and this is my class
public class RootObject
{
public int ReturnCode { get; set; }
public int CampaignId { get; set; }
public int TotalSMSSent { get; set; }
public int TotalSMSwithError { get; set; }
public List<MSISDNwithErrorList> MSISDNwithErrorList { get; set; }
}
public class MSISDNwithErrorList
{
}
this is my code to get the json string
HttpClient client = new HttpClient();
var response = client.GetAsync("http://evolus.ddns.net/Q4Evolution/php/phpCategoria/BOPesquisaEmp.php").Result;
if (response.IsSuccessStatusCode)
{
string output = JsonConvert.SerializeObject(response.Content.ReadAsStringAsync().Result);
JsonConvert.DeserializeObject<RootObject>(output);
}
And the error is this...
Newtonsoft.Json.JsonSerializationException: Error converting value "{"ReturnCode":0,"CampaignId":155087586,"TotalSMSSent":1,"TotalSMSwithError":0,"MSISDNwithErrorList":{}}" to type 'AppTeste.RootObject'. Path '', line 1, position 115.
MSISDNwithErrorList member seems only object as per the json structure
public class RootObject
{
public int ReturnCode { get; set; }
public int CampaignId { get; set; }
public int TotalSMSSent { get; set; }
public int TotalSMSwithError { get; set; }
//Change from List to Object
public MSISDNwithErrorList MSISDNwithErrorList { get; set; }
}
Rest of Code should be like ...
HttpClient client = new HttpClient();
var response =client.GetAsync("http://evolus.ddns.net/Q4Evolution/php/phpCategoria/BOPesquisa
Emp.php").Result;
if (response.IsSuccessStatusCode)
{
//Here Result already gives you a valid json, you do not need to serialize again
string output =response.Content.ReadAsStringAsync().Result;
//obj is your desired c# object
var obj =JsonConvert.DeserializeObject<RootObject>(output);
}
You can check your working code on https://dotnetfiddle.net/CeXDNA

How to populate list as class object?

How do you populate a list as a class object? For example, this does not work:
[DataContract]
public class JsonReviewFormFields
{
[DataMember]
public PersonalDevelopmentPlan personalDevelopmentPlan { get; set; }
}
public class PersonalDevelopmentPlan
{
public List<ShortTerm> shortTerm { get; set; }
public List<LongTerm> longTerm { get; set; }
}
public class ShortTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
public class LongTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
This is controller action:
public JsonReviewFormFields GetReviewForm()
{
PersonalDevelopmentPlan personalDevelopmentPlan = new PersonalDevelopmentPlan();
List<ShortTerm> _itemsShort = new List<ShortTerm>();
_itemsShort.Add(new ShortTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
List<LongTerm> _itemsLong = new List<LongTerm>();
_itemsLong.Add(new LongTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.longTerm = _itemsLong;
return jsonReviewFormFields;
}
The code crashes at
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
It's probably a basic object orientated error. How do you populate the list?
You are not instantiating it, you have to instantiated the type first:
jsonReviewFormFields.personalDevelopmentPlan = new PersonalDevelopmentPlan();
and then set property of it:
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort
before that you also have to instantiate main class which i don't see in your controller action anywhere :
JsonReviewFormFields jsonReviewFormFields = new JsonReviewFormFields();

using JSON response from REST api with nonstandard names

{"balances-and-info":{"on_hold":[],"available": {"USD":0.93033384},"usd_volume":"243.18","fee_bracket": {"maker":"0.00","taker":"0.60"},"global_usd_volume":"0.09942900"}}
I have this JSON response, and I'm trying to store it in an object, however as you can see "balances-and-info" cannot be used as a variable name. The method I have been using is:
RestClient client = new RestClient("http://currency-api.appspot.com/api/");
RestRequest request = new RestRequest(url);
var response = client.Execute<Currency>(request);
Currency obj = response.Data;
Where obviously the class is a lot easier
public class Currency
{
public string rate { get; set; }
}
So how can I handle this?
String.replace() balances-and-info with balances_and_info
in your code
YourObject deserialized = parseResponse(obj.replace("balances-and-info", "balances_and_info"));
YourObject parseResponse(string response) {
try
{
// https://www.nuget.org/packages/Newtonsoft.Json/
// Json.NET
YourObject ret = JsonConvert.DeserializeObject<YourObject>(response);
return ret;
}
catch (JsonSerializationException)
{
// do something
}
return null;
}
YourObject
Use http://json2csharp.com/ and generate your object (copy response string, replace balances-and-info with balances_and_info and generate)
public class Available
{
public double USD { get; set; }
}
public class FeeBracket
{
public string maker { get; set; }
public string taker { get; set; }
}
public class BalancesAndInfo
{
public List<object> on_hold { get; set; }
public Available available { get; set; }
public string usd_volume { get; set; }
public FeeBracket fee_bracket { get; set; }
public string global_usd_volume { get; set; }
}
public class YourObject
{
public BalancesAndInfo balances_and_info { get; set; }
}

Serialize deserialize anonymous child JSON properties to model

I have an API I am receiving data from. That API is out of my control on how it is structured, and I need to serialize and deserialize the JSON output to map the data to my model.
Everything works well where JSON is nicely formatted with named properties.
What can you do where there is no named value and there is just an array of ints and strings? like under locations
here is a sample of the JSON:
{"id":"2160336","activation_date":"2013-08-01","expiration_date":"2013-08-29","title":"Practice Manager","locations":{"103":"Cambridge","107":"London"}}
I have models that are like:
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date{ get; set; }
public string Title { get; set; }
public Location Locations { get; set; }
}
public class Location
{
public int Id { get; set; }
public string value { get; set; }
}
and I am mapping using the inbuilt ajax serialization:
protected T MapRawApiResponseTo<T>( string response )
{
if ( string.IsNullOrEmpty( response ) )
{
return default( T );
}
var serialize = new JavaScriptSerializer();
return serialize.Deserialize<T>( response );
}
var results = MapRawApiResponseTo<ItemResults>(rawApiResponse);
So the ID and all other properties are picked up and mapped but what every I do I can not seem to map the locations.
Many thanks
public Dictionary<int,string> Locations { get; set; }
job done; you should find that using Json.NET, at least, i.e.
var result = JsonConvert.DeserializeObject<ItemResults>(json);
you get 2 entries in result.Locations; specifically result[103] = "Cambridge"; and result[107] = "London";
If you don't mind, you can workaround with dictionary:
class Program
{
static void Main(string[] args)
{
string json =
"{'id':'2160336','activation_date':'2013-08-01','expiration_date':'2013-08-29','title':'Practice Manager','locations':{'103':'Cambridge','107':'London'}}";
var deserializeObject = JsonConvert.DeserializeObject<ItemResults>(json);
Console.WriteLine("{0}:{1}", deserializeObject.Locations.First().Key, deserializeObject.Locations.First().Value);
Console.ReadKey();
}
}
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date { get; set; }
public string Title { get; set; }
public Dictionary<int, string> Locations { get; set; }
}
you can also use manual parsing, like here: Json.NET (Newtonsoft.Json) - Two 'properties' with same name?
This will work:
public Dictionary<string, string> Locations { get; set; }
public IEnumerable<Location> LocationObjects { get { return Locations
.Select(x => new Location { Id = int.Parse(x.Key), value = x.Value }); } }
I propose you the following solution :
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date { get; set; }
public string Title { get; set; }
[JsonProperty("locations")]
public JObject JsonLocations { get; set; }
[JsonIgnore]
public List<Location> Locations { get; set; }
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
this.Locations = new List<Location>();
foreach (KeyValuePair<string, JToken> item in this.JsonLocations)
{
this.Locations.Add(new Location() { Id = int.Parse(item.Key), value = item.Value.ToString() });
}
}
}
public class Location
{
public int Id { get; set; }
public string value { get; set; }
}
After you just have to deserialize your JSON with : JsonConvert.DeserializeObject<ItemResults>(json);

Categories

Resources