Below are my two model classes
public class ResponseData
{
public List<string> labels { get; set; }
public List<string> series { get; set; }
public List<dataForMetric> data{ get; set; }
}
public class dataForMetric
{
public List<int> value { get; set; }
}
and my action method is
public ActionResult GetData()
{
ResponseData res = new ResponseData();
res.labels = new List<string>() { "day1", "day2", "day3" , "day4"};
res.series = new List<string>() { "dummy" };
res.data = new List<dataForMetric>() { new dataForMetric() { value = new List<int>() {10} } ,
new dataForMetric() { value = new List<int>() {110} } ,
new dataForMetric() { value = new List<int>() {120} } ,
new dataForMetric() { value = new List<int>() {130} }
};
return Json(res, JsonRequestBehavior.AllowGet);
}
The JSON output of above action method is
{"labels":["day1","day2","day3","day4"],"series":["dummy"],"data":[{"value":[10]},{"value":[110]},{"value":[120]},{"value":[130]}]}
But for my requirement the output should be
{"labels":["day1","day2","day3","day4"],"series":["dummy"],"data":[[10],[110],[120],[130]]}
Please let me know how it can be achieved.
Well if you actually want output like you describe you should chenge your class to this:
public class ResponseData
{
public List<string> labels { get; set; }
public List<string> series { get; set; }
public int[][] data { get; set; }
}
I generate this class with VS 2013. It now has feature to create class structure from JSON. Edit -> Paste Special -> Pase JSON as classes. Hope this instrument will ease your life a lot.
Your dataForMetric class is unnecessary. You can achieve the desired result with a list of lists:
public class ResponseData
{
public List<string> labels { get; set; }
public List<string> series { get; set; }
public List<List<int>> data { get; set; }
}
public ActionResult GetData()
{
ResponseData res = new ResponseData();
res.labels = new List<string> { "day1", "day2", "day3" , "day4"};
res.series = new List<string> { "dummy" };
res.data = new List<List<int>> {
new List<int> { 10 },
new List<int> { 110 },
new List<int> { 120 },
new List<int> { 130 }
};
return Json(res, JsonRequestBehavior.AllowGet);
}
You must either define data as a single dataForMetric or define dataForMetric.value as a single int.
Your problem is you're instantiating a List of a List of int.
Related
This is my first usage of RestSharp
I am trying to connect to HubSpot using their FormsAPI (https://legacydocs.hubspot.com/docs/methods/forms/submit_form)
Using .Net, C#, MVC.
When I run in Fiddler, it works.
Here is my C# code, when I run it, I get a StatusCode of "NotFound". I am sure it is something simple I am missing?
var client = new RestClient("https://api.hsforms.com");
var request = new RestRequest("submissions/v3/integration/submit/{PortalId}/{formGuid}", Method.POST);
request.AddUrlSegment("portalId", "[myportalid]");
request.AddUrlSegment("formGuid", "[myformid]");
request.AddQueryParameter("hapikey", "[myapikey]");
request.RequestFormat = DataFormat.Json;
request.AddParameter("firstname", "testfirstname");
request.AddParameter("lastname", "testlastname");
request.AddParameter("email", "testemail#emailaddress.com");
request.AddParameter("business_unit", "Test");
It is better to create model of c# class and serialize it to Json and send POST request.
Example of RestSharp request
public async Task SendHubSpotRequest()
{
var PortalId = 1;
var formGuid = 1;
var client = new RestClient("https://api.hsforms.com");
var request = new RestRequest($"submissions/v3/integration/submit/{PortalId}/{formGuid}", Method.POST);
var hubSpotRequest = new HubSpotRequest()
{
SubmittedAt = "1517927174000",
Fields = new Field[]
{
new Field() { Name = "email", Value = "testemail#emailaddress.com" },
new Field() { Name = "firstname", Value = "testfirstname" },
new Field() { Name = "lastname", Value = "testlastname" }
},
Context = new Context
{
Hutk = "hutk",
PageUri = "www.example.com/page",
PageName = "Example page"
},
LegalConsentOptions = new LegalConsentOptions
{
Consent = new Consent
{
// Fill other params
}
}
};
request.AddParameter("application/json; charset=utf-8", JsonConvert.SerializeObject(hubSpotRequest), ParameterType.RequestBody);
var response = await client.ExecuteAsync(request);
var responseContent = response.Content;
}
C# classes of body json model
public class HubSpotRequest
{
[JsonProperty("submittedAt")]
public string SubmittedAt { get; set; }
[JsonProperty("fields")]
public Field[] Fields { get; set; }
[JsonProperty("context")]
public Context Context { get; set; }
[JsonProperty("legalConsentOptions")]
public LegalConsentOptions LegalConsentOptions { get; set; }
}
public class Context
{
[JsonProperty("hutk")]
public string Hutk { get; set; }
[JsonProperty("pageUri")]
public string PageUri { get; set; }
[JsonProperty("pageName")]
public string PageName { get; set; }
}
public class Field
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
public class LegalConsentOptions
{
[JsonProperty("consent")]
public Consent Consent { get; set; }
}
public class Consent
{
[JsonProperty("consentToProcess")]
public bool ConsentToProcess { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("communications")]
public Communication[] Communications { get; set; }
}
public class Communication
{
[JsonProperty("value")]
public bool Value { get; set; }
[JsonProperty("subscriptionTypeId")]
public long SubscriptionTypeId { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
I have a question related to CsvHelper library and I cannot figure out how to map a csv file to the following MyClass object.
the csv file look like:
id, Property1, property2....
1, x, a,b,c
2,x, d,f
3, y, g,h,i,j,k
...
Which I would like to parse to the following classes
public class MyClass
{
public string Id { get; set; }
public List<Custom> MyCustoms { get; set; }
}
public class Custom
{
public string Property1 { get; set; }
public List<string> Property2 { get; set; }
}
ConvertUsing is going to be the easiest way to map this.
public class Program
{
static void Main(string[] args)
{
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
using (var reader = new StreamReader(stream))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
writer.WriteLine("Id,Property1,Property2,Property3,Property4,Property5,Property6");
writer.WriteLine("1,x,a,b,c");
writer.WriteLine("2,x,d,f");
writer.WriteLine("3,y,g,h,i,j,k");
writer.Flush();
stream.Position = 0;
var test = csv.Configuration.RegisterClassMap<MyClassMap>();
var records = csv.GetRecords<MyClass>().ToList();
}
}
}
public class MyClassMap: ClassMap<MyClass>
{
public MyClassMap()
{
Map(m => m.Id);
Map(m => m.MyCustoms).ConvertUsing(row =>
{
var custom = new Custom
{
Property1 = row["Property1"],
Property2 = new List<string>()
};
var index = 2;
while (row.TryGetField(typeof(string), index, out var property))
{
custom.Property2.Add((string)property);
index++;
}
return new List<Custom> { custom };
});
}
}
public class MyClass
{
public string Id { get; set; }
public List<Custom> MyCustoms { get; set; }
}
public class Custom
{
public string Property1 { get; set; }
public List<string> Property2 { get; set; }
}
hello people I have this Json data:
https://openexchangerates.org/api/latest.json?app_id=6cf59607a32d408eb3e04de1427a3169
and I want to deserialize in the following class
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Divisas2MVVM2.Classes
{
public class ExchangeRates
{
[JsonProperty(PropertyName = "disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty(PropertyName = "license")]
public string License { get; set; }
[JsonProperty(PropertyName = "timestamp")]
public int TimeStamp { get; set; }
[JsonProperty(PropertyName = "base")]
public string Base { get; set; }
[JsonProperty(PropertyName = "rates")]
public Rates Rates { get; set; }
}
public class Rates
{
public double AED { get; set; }
public double AFN { get; set; }
public double ALL { get; set; }
public double AMD { get; set; }
// I cut the text so that it would not be to long
public double ZMW { get; set; }
public double ZWL { get; set; }
}
public class Rate
{
public double TaxRate { get; set; }
public string Code { get; set; }
}
this is my attribute
private ExchangeRates exchangeRates;
the constructor of my MainViewModel
new ObservableCollection data
Rates = new ObservableCollection<Rate>();
and in this method a get the json data
try
{
var client = new HttpClient();
client.BaseAddress = new Uri("https://openexchangerates.org");
var url = "/api/latest.json?app_id=6cf59607a32d408eb3e04de1427a3169";
var response = await client.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
Message = response.StatusCode.ToString();
IsRunning = false;
return;
}
var result = await response.Content.ReadAsStringAsync();
exchangeRates = JsonConvert.DeserializeObject<ExchangeRates>(result);
}
everything works fine, the variable result has correctly the json data in a string format, but when i call JsonConvert . DeserializeObject, the data "rates" it is not assigned correctly, all the other data: disclaimer", "license", "timestamp" etc. is correctly assigned. only rates fail.
the string is correct
other data is correct in the class
rates is incorrect
sorry for my English I hope you have understood me :)
use this as your model class
namespace Rate
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Rates
{
[JsonProperty("disclaimer")]
public string Disclaimer { get; set; }
[JsonProperty("license")]
public string License { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("rates")]
public Dictionary<string, double> RatesRates { get; set; }
}
public partial class Rates
{
public static Rates FromJson(string json) => JsonConvert.DeserializeObject<Rates>(json, Rate.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Rates self) => JsonConvert.SerializeObject(self, Rate.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
Then do this in your class
var data = Rate.Rates.FromJson("jsonresult");
var rate = data.RatesRates;
foreach (var pair in rate)
{
string symbol = pair.Key; //"AED"
double value = pair.Value; //3.673175,
}
var time = data.Timestamp;
var disclaimer = data.Disclaimer;
var license = data.License;
Tested and working
iam using a RequestClass with the Route anotation to call a Json-Client POST method.
Now, while the paramters are structured like this
public class GetTicketRequest: IReturn<JsonObject>
{
public string CartId {
get;
set;
}
public string PriceId {
get;
set;
}
}
The BackendAPI needs them to be nesten in "data" in the json request, so more like
{
"data":[
{"cartid":123,
"priceId":11}]
}
Is there any way to transfrom the request object for the body before calling
JsonServiceClient _restClient = new JsonServiceClient(baseUrl);
JsonObject oneResponse = _restClient.Post(options);
This solution is useful where many DTOs require to be wrapped & converted, and is highly reusable, with no changes to your existing DTOs.
You can convert the requests of the JsonServiceClient by overriding the methods that handle preparing the requests for sending. Which means implementing your own extended JsonServiceClient as given below.
If you want to do this for all verbs then you override it's Send<TResponse> methods (otherwise, if it's just for POST then uncomment the commented out code, and remove the Send methods).
public class MyJsonServiceClient : JsonServiceClient
{
public Dictionary<Type, Func<object, object>> DtoConverters = new Dictionary<Type, Func<object, object>>();
public MyJsonServiceClient() {}
public MyJsonServiceClient(string baseUri) : base(baseUri) {}
public MyJsonServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) : base(syncReplyBaseUri, asyncOneWayBaseUri) {}
public override TResponse Send<TResponse>(object request)
{
return base.Send<TResponse>(ConvertRequest(request));
}
public override TResponse Send<TResponse>(string httpMethod, string relativeOrAbsoluteUrl, object request)
{
return base.Send<TResponse>(httpMethod, relativeOrAbsoluteUrl, ConvertRequest(request));
}
/*
public override TResponse Post<TResponse>(string relativeOrAbsoluteUrl, object requestDto)
{
return base.Post(relativeOrAbsoluteUrl, ConvertRequest(requestDto));
}
*/
object ConvertRequest(object request)
{
Type dtoType = request.GetType();
return (DtoConverters.ContainsKey(dtoType)) ? DtoConverters[dtoType](request) : request;
}
}
Usage:
So given this DTO:
[Route("/test", "POST")]
public class TicketRequest : IReturnVoid
{
public string CartId { get; set; }
public string PriceId { get; set; }
}
You simply add the converter:
var client = new MyJsonServiceClient("http://localhost:9000");
// Simple converter for TicketRequest
client.DtoConverters.Add(typeof(TicketRequest), dto => {
var d = (TicketRequest)dto;
return new {
data = new {
CartId = d.CartId.ToInt(),
PriceId = d.PriceId.ToInt()
}
};
});
client.Post(new TicketRequest { CartId = "123", PriceId = "456" });
i solved this issue using a typed data property
public class GetTicketRequest: IReturn<JsonObject>
{
public class TicketCreateData
{
public int priceId {
get;
set;
}
}
public string CartId {
get;
set;
}
public string PriceId {
get;
set;
}
public List<TicketCreateData> data {
get {
var list = new List<TicketCreateData>();
list.Add(new TicketCreateData {
priceId = this.PriceId.ToInt()
});
return list;
}
set {
data = value;
}
}
}
To notes on this:
if neede, use DataContract/DataMember(Name="") to rename fields or only do partial serializing
Do never use structs for, like in this case, the data class - they are not serializeable at all
in my spefici case data even needs to be an array, thats why i used the list
I am playing around with Azure Mobile Services. Right now I am trying to store an object of my custom class in a table.
Here is a snippet from the class which represent the object which I want to store in Azure.
public class CustomItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Id { get; set; }
[JsonProperty(PropertyName = "Categorie")]
public CategorieObject Categorie { get; set; }
[JsonProperty(PropertyName = "Subcategorie")]
public SubcategorieObject Subcategorie { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
...
}
My question is how to store custom types like CategorieObject or SubCategorieObject. These classes contain a String for the name and many other properties, but I only need to store the name of the Categorie and SubcategorieObject.
Maybe you can give me a hint, to solve my problem.
Thanks!
The post at http://blogs.msdn.com/b/carlosfigueira/archive/2012/09/06/supporting-arbitrary-types-in-azure-mobile-services-managed-client-complex-types.aspx shows one way to support complex objects in azure mobile service. For your scenario, you can send the data to the server and in the insert/read/update scripts you "change" the data to only store what you need. For example, assuming that you have those types on the client:
public class CustomItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Id { get; set; }
[JsonProperty(PropertyName = "Categorie")]
public CategorieObject Categorie { get; set; }
[JsonProperty(PropertyName = "Subcategorie")]
public SubcategorieObject Subcategorie { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
}
public class CategorieObject
{
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "SomethingElse")]
public string SomethingElse { get; set; }
}
public class SubcategorieObject
{
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "SomethingElse")]
public string SomethingElse { get; set; }
}
You'd change your insert script to replace the complex object (categorie / subcategorie) with the name, which is what you want to store:
function insert(item, user, request) {
// Replace the complex object with their "Name" property.
// Omitting error / format checking here for conciseness.
item.Categorie = item.Categorie.Name;
item.Subcategorie = item.Subcategorie.Name;
request.execute({
success: function() {
// Recreate the original object
item.Categorie = { Name: item.Categorie };
item.Subcategorie = { Name: item.Subcategorie };
request.respond();
}
});
}
Likewise when updating an item you'd need to do the same:
function update(item, user, request) {
// Replace the complex object with their "Name" property.
// Omitting error / format checking here for conciseness.
item.Categorie = item.Categorie.Name;
item.Subcategorie = item.Subcategorie.Name;
request.execute({
success: function() {
// Recreate the original object
item.Categorie = { Name: item.Categorie };
item.Subcategorie = { Name: item.Subcategorie };
request.respond();
}
});
}
And the same for reading:
function read(query, user, request) {
request.execute({
success: function(results) {
results.forEach(function(item) {
item.Categorie = { Name: item.Categorie };
item.Subcategorie = { Name: item.Subcategorie };
});
request.respond();
}
});
}
Notice that any other properties in the subclasses will be lost when reading from the database (after all, you're not storing them).