Stripe Transfer JSON
I'm trying to get all charge IDs associated with a transfer.
var json = new StreamReader(context.Request.InputStream).ReadToEnd();
var stripeEvent = StripeEventUtility.ParseEvent(json);
StripeTransfer stripeTransfer;
switch (stripeEvent.Type)
{
case "transfer.created":
stripeTransfer = Stripe.Mapper<StripeTransfer>.MapFromJson(stripeEvent.Data.Object.ToString());
var transferId = stripeTransfer.Id;
stripeTransfer = _stripeManager.GetTransfer(transferId);
foreach (var charge in stripeEvent.Data.Object["transactions"])
{
}
_stripeManager.ProcessTransfer(stripeTransfer);
break;
In visual studio's immediate window, stripeEvent.Data.Object["transactions"] shows the data I want so I know that the json is getting sucked in properly. Those transactions are a collection of charges, they match my .net StripeCharge object. I'm having trouble figuring out how to iterate through the transactions...all I really need is the ID for each. Would like to see "transactions" as a C# IEnumerable object.
(the json in question is linked at the top of this post) let me know if more info is needed.
I've found the specific item is under ["transactions"]["data"][0]["id"] but there may be more than one so, still working on how to get them out and cast them...think I'm close but it seems like there should be a more elegant way of doing it.
EDIT,
Thanks Andrew, so even though I have all of the charge data, it is incoming data. So what I'll be doing is using the event to just get the id and then make the call to get the charge object from my own end to prevent any event spoofs. So that means I don't have to worry about casting at this point. Here is my solution, feel free to advise if there is a better way to do it
for (int i = 0; i < Int32.Parse(stripeEvent.Data.Object["transactions"]["total_count"].ToString()); i++)
{
string chargeId = stripeEvent.Data.Object["transactions"]["data"][i]["id"].ToString();
// do stuff with it
}
just for completeness:
Data under transactions looks like an array so should be able to index into them..
If you need to access to any other fields in the future you could construct c# objects but given the webhook 3rd party dance you are already doing probably not worth it as you only need id.
Related
I serialize all the objects contained in a list each time a new object is added (kind of an history if the application crashes).
Serialization is done within a millisecond when adding the first ~20 objects, but from now on, each newly added object is going to take longer and longer (if I add 10 more it can take 10 minutes to serialize).
As I said, it's kind of an history. So if I restart app, every object in the JSON file is added back to the list. Let's admit I had 20 objects before closing app.
Now I can add 20 more objects, so it will serialize 40 within a millisecond.
Once again, if I add even more objects, I'll have to close and restart app.
I don't understand why multiple serializations in the same instance of the app takes that long.
Here's the serialization code:
public static void SerializeAll()
{
string output = JsonConvert.SerializeObject(ListOfModelToSerialize, Formatting.Indented);
IO.StreamWriter writer = new IO.StreamWriter("A:\history.json");
writer.Write(output);
writer.Close();
}
Deserialization code:
public static List<ModelToSerialize> DeserializeAll()
{
if (IO.File.Exists("A:\history.json"))
{
string input = IO.File.ReadAllText("A:\history.json");
var result = JsonConvert.DeserializeObject<List<ModelToSerialize>>(input);
return result;
}
else
{
return new List<ModelToSerialize>();
}
}
And I only serialize 4 properties from my model. Here's the serialized model output:
{
"an_integer": 1,
"a_string": "...",
"a_list_of_string": [],
"another_list_of_string": []
}
UPDATE 1:
It seems like the integer (ID) I'm serializing is the problem.
In fact, this ID is not assigned at the model creation because it changes everytime a new object is added to the list, as the list is sorted alphabetically. So to get the ID, I do this:
[JsonProperty(PropertyName = "id")]
public int Id
{
get
{
if (_id > 0)
{
return _id;
}
else
{
int id = Properties.Settings.Default.PREVIOUS_MAX_ID + 1;
foreach (File file in _directory.Files)
{
if (file == this)
{
return id;
}
else if (file.Id == id)
{
id += 1;
}
}
return 0;
}
}
}
So the reason why it doesn't take longer to serialize the first 20 objects after the app restart is that the ID is directly assigned at deserialization.
So I have to adapt the ID retrieval.
UPDATE 2:
As the ID retrieval was the performance issue, I fixed it by assigning the ID to each object each time a new object is added.
Like that, when the object ID is called, there is no more iteration in the model.
The following block is my custom Add() method for my list of objects:
public new void Add(File file)
{
if (!base.Contains(file))
{
base.Add(file);
base.Sort(new Comparer());
for (int i = 0; i < Count; i++)
{
this[i].Id = Properties.Settings.Default.PREVIOUS_MAX_ID + i;
}
}
}
I added ~100 new objects to the current instance of the app, and serialization is not taking years anymore.
Serialization (JSON etc) is best when used to communicate a discrete bit of data from one medium to another, such as making network API calls. It can also be used to store data to disk as you are doing.
But it's not a great option when you are frequently updating that data because the most popular formats (JSON, XML) are not structured so that new data can just be appended to existing data. That's why it needs to be serialized every time. And so of course as the data gets larger serialization will take longer.
For your purpose I would suggest a database like SQLite. You could still serialize each individual row to JSON if the data doesn't lend itself well to columns, but you'll be able to append new data to the database without having to rewrite the old. And if you use transactions you can also ensure that the data keeps its integrity even if your app crashes.
For any kind of performance issue I would recommend to measure, ideally using a performance profiler that can tell you exactly what part of the code is slow.
Some general suggestions
You probably want to have a limit on how much history you keep. Otherwise there is a risk that your application will get slower and slower as you accumulate objects. This also lets you test worst case performance.
Use a faster serializer, while json.net is good, using some variant of binary serialization, like protobuf.net, typically results in less data and time (benchmark), at the cost of not being humanly readable. You might also consider a fast compressor like lz4 to reduce the file size and therefore disk-performance.
Change your model so you do not have to overwrite all data. Either serialize to different files, or use some serialization method that lets you append messages to the same file.
Limit save-frequency. You might not need to save history for each and every change, it might be sufficient to save every 5s or so.
If you have not already done so, ensure that at least saving data is done asynchronously so it does not block the UI thread. This might require some way to access your data in a thread safe manner so ensure it cannot change while it is being serialized.
So I am doing this c# program which basically is a coffee machine. Asks the user to register and adds the instance in a textfile, then login, then asks which coffee he wants from a provided list, and finally increments a property named "coffee points". The problem is that I have no idea how I am going to update the coffee points inside my textfile. I can get the coffee points and increment them by 1 and then print them in console, however, I dont know how to update just the coffee points in my textfile of a certain user.
Below is the code I am using to retrieve the coffee points of the logged in user and increment them by 1, and store them in the variable "newCoffeePoints".
int newCoffeePoints = 0;
for (int i = 0; i < customerList.Count; i++)
{
if (customerList[i].iUsername == cu2.iUsername)
{
customerList[i].iCoffeePoints += 1;
newCoffeePoints = customerList[i].iCoffeePoints;
break;
}
}
Well, for this exact purpose we have so many different types of databases such as Mongo, SQL etc.
But if you're trying to serialize/deserialize object and save it to a file among other types of serialization you might want to consider JSON format. The libarary Newtonsoft.js is what we (C# developers) usually use for that.
You could create a virtual structure that reflects what you need.
Since we might want to find object by key a Dictionary<TKey, TValue> collection suits much better than List<T>.
Do whatever operation you need to do with users in a Dictionary<key, value> and then serialize it to JSON and save it to disc using the File.WriteAllText(json) method.
Whether to do it after each update (so that if app crashes all the data is saved) or do it once when the app is about to finish execution will depend on your needs.
The field with dictionary could be something along the lines of:
// CKeyType here is a type of customer's id field such as int, string etc.
private static readonly CustomerDict = new Dictionary<CKeyType, Customer>();
You can easily solve this problem by using JSON and Newtonsoft Library. (Fabjan mentioned above)
Here is a tutorial link from Microsoft Virtual Academy that you can follow.
https://mva.microsoft.com/en-US/training-courses/introduction-to-json-with-c-12742?l=xxtX274UB_8805494542
I am currently trying to save a list in Xamarin forms. I use this code snippet:
var list = new List<myClass> ();
Application.Current.Properties["myList"] = list;
await Application.Current.SavePropertiesAsync();
When I then close the app and use this code...
if (Application.Current.Properties.ContainsKey("myList"))
{
}
...I cannot reach this if statement.
I read something about people having issues saving a list with this solution but they solved it by converting it to a string. I am a bit unsure on how to do this. If I do this...
Application.Current.Properties["myList"] = list.ToString();
...the app crashes.
I saw that there is a plugin called "Settings" that I might need to use instead in case there isn't a solution to this problem but I would prefer to work with my current code if possible.
The Properties dictionary can only serialize primitive types for
storage. Attempting to store other types (such as List can
fail silently).
It means that you can't save List because it's not a primitive type of object. You can serialize it to JSON string for example then it will work. Code example:
var jsonValueToSave = JsonConvert.SerializeObject(myList);
Application.Current.Properties["myList"] = jsonValueToSave;
await Application.Current.SavePropertiesAsync();
Don't forget to deserialize JSON to List<string> when loading the value back.
Note that yourList.ToString() will not work in this case. More info here.
P.S.: Get familiar with the official documentation & check this post on another related thread.
So I'm doing a exercise with wpf and getting data from azure table but I am using the DynamicTableEnity to query the cloudtableclient. A big issue comes in trying to covert the results that come back to a object that can be displayed in the Datagrid of WPF.
This requires a list of object, which I don't know what object comes back BUT I have all the data in the properites of the DynamicTableEnity. So my first hack at this was as follow.
List<dynamic> dynamicList = new List<dynamic>();
foreach (var entry in tableStorageEntry)
{
var dictionaryObject = AzureConversionHelper.Converstion(entry);
var json = new JavaScriptSerializer().Serialize(dictionaryObject);
dynamic foo = JObject.Parse(json);
dynamicList.Add(foo);
}
public static object Converstion(DynamicTableEntity entity)
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("PartitionKey", entity.PartitionKey);
dictionary.Add("RowKey", entity.RowKey);
dictionary.Add("TimeStamp", entity.Timestamp.ToString());
foreach (var prop in entity.Properties)
{
dictionary.Add(prop.Key, prop.Value.PropertyAsObject);
}
return dictionary;
}
I had no idea what I am doing and it was kind of a struggle since I haven't worked much with anonymous objects. My hack was to convert the properties into a dictionary of strings convert them into a json string and then parse them back into a dynamic object. . . . . that sounds really bad even in my head but after a couple hours of slap around articles of anonymous types I came up with that idea.
This granted how horrible it is works, so its a start for me but it becomes a real issue when I am pull down large set of data, and it makes task almost painful since I'm almost doing a triple read through the data. Can anyone point me to a better method or maybe some pointer on how to better approach this issue.
So I'm trying to create discount coupons for a Kentico 7 site, and I'm not sure if I'm completely misunderstanding how the DiscountCouponInfoProvider works, or if I'm barking up the wrong tree entirely.
The code I'm currently using is:
var newCoupon = new DiscountCouponInfo {
//Fill in data fields here
};
DiscountCouponInfoProvider.SetDiscountCouponInfo(newCoupon);
This doesn't throw an error, but the coupon never shows up in the database. A few lines down I use
var result = DiscountCouponInfoProvider.GetDiscountCouponinfo();
passing in the same ID I used when creating the coupon, and it stores all of the correct information in result.
I noticed that there is an insert method for the DiscountCouponInfo class
newCoupon.Insert();
which may be closer to what I'm looking for, but haven't tried yet.
Any help would be appreciated. Or a link to the Kentico 7 api reference. Every time I go looking for it I keep finding the Kentico 8.1 api reference.
Thanks.
You can create coupons within the Kentico UI by going to CMS Desk > Ecommerce > Discount Coupons. However, if you are needing to create them outside the UI for some reason, then you were pretty close. You will want to use an Info object along with the InfoProvider object, like this:
// Instantiate an info object
DiscountCouponInfo dci = new DiscountCouponInfo();
// Set your properties
dci.DiscountCouponDisplayName = "Some text";
dci.DiscountCouponValue = 10;
//Update the DB with an InfoProvider object
DiscountCouponInfoProvider.SetDiscountCouponInfo(dci);
The Info object is just a simple data container that you can instantiate, populate with data, then pass it as an argument to an InfoProvider object.
The InfoProvider then has methods for update/creating records, etc.
You could also populate an Info object with data from the Kentico DB like this:
DiscountCouponInfo dci = new DiscountCouponInfoProvider.GetDiscountCouponInfo(DiscountCouponID);
I actually JUST wrote a blog post about this. Feel free to check it out or read Kentico's docs for more info.