Get coursework from google classroom course - c#

I'm trying to get a list of CourseWork objects from a list of courses and add each coursework object to a list. However I have no idea how to get the Coursework object, I'm thinking that it's to do with either eTags or Ids, but have no way of knowing. The code I'm using is below:
public static IList<Course> GetAllCourses()
{
CoursesResource.ListRequest request = ClassService.Courses.List();
request.PageSize = 100;
ListCoursesResponse response = request.Execute();
GoogleClassroomCourses = response.Courses;
return GoogleClassroomCourses;
}
public static IList<CourseWork> GetCourseWork()
{
IList<string> courseIds = new List<string>();
IList<string> eTags = new List<string>();
foreach (Course course in GetAllCourses())
{
string id = course.Id;
courseIds.Add(id);
foreach (string cId in courseIds)
{
Course c = ClassService.Courses.Get(cId).Execute();
eTags.Add(c.ETag);
}
}
}

You may want to use Method: courses.courseWork.list using this HTTP request format:
GET https://classroom.googleapis.com/v1/courses/{courseId}/courseWork
which, if successful, returns course work items that match the request in the response body.
Sample JSON representation:
{
"courseWork": [
{
object(CourseWork)
}
],
"nextPageToken": string,
}

Related

Update the SQLite Database in C#

In my Xamarin app, there is a Picker which gets the Bank List from Database, and this DB gets the Bank details through an API.
Everything works fine, but now, I want to update the DB, if the new Banks are added in API, I want to add them in the existing database.
I wrote this small code, but the problem is, it first output all the existing records from the database and then print the new records, many times as the total amount of records e.g. (if there are ten records, it will print every record ten times).
ViewModel.cs
// Load all Banks into a List
var getBanks = await App.Database.GetBankAsync();
// Update the Bank Details where new Banks doesn't exist in the Database
List<Bank> updateBanks = new List<Bank>();
foreach (Banks i in obj.banks)
{
foreach (var record in getBanks.Where(c => c.Name != i.alias.name))
{
updateBanks.Add(new Bank { Name = i.alias.name, Status = "Not Registered" });
}
}
foreach (var bank in updateBanks)
{
await App.Database.SaveBankAsync(bank);
}
// Load all Banks into a List
var getBanksUpdated = await App.Database.GetBankAsync();
// Load the Banks whose Status is "Not Registered"
foreach (var record in getBanks.Where(c => c.Status == "Not Registered")
{
_bankList.Add(record);
}
public class Alias
{
public string name { get; set; }
}
public class Banks
{
public Alias alias { get; set; }
public string id { get; set; }
}
public class RootObject
{
public List<Banks> banks { get; set; }
}
Data getting through API
{
success: true,
banks: [
{
alias: {
name: "Bank 1",
Address: "Earth"
},
endpoint: {
uri: "http://127.0.0.1:0000"
},
state: "Registered",
createdAtUtc: "2021-01-19T13:55:12.2318662",
updatedAtUtc: "2021-01-19T13:55:14.9944042"
},
]
}
Code to get the data from API
HttpClient httpClient = new HttpClient(new NativeMessageHandler());
Uri getDataBanks = new Uri(string.Format("http://127.0.0.1:0000/Banks"));
HttpResponseMessage restponseBanks = await httpClient.GetAsync(getDataBanks);
string contentBanks = await restponseBanks.Content.ReadAsStringAsync();
RootObject obj = JsonConvert.DeserializeObject<RootObject>(contentBanks);
// get the names of all existing banks
List<string> names= obj.banks.Select(u => u.Name).ToList();
// get the names of all banks taken from the API
List<string> names_new= getBanks.Select(u => u.Name).ToList();
foreach (var record in names_new)
{
//check if the bank is exists or not
if(! names.contains(record)
{
updateBanks.Add(new Bank { Name = record.alias.name, Status = "Not Registered" });
}
}
I'm not aware of your data, but you you have too foreach loops and you are checking the whole collection in every loop. SO, it's possible, that your condition catches every account on every loop.

populate array(list) to send a call from c# to php

So I'm passing parameters from unity to a PHP API and all are fine but now I want to pass it as an array, so in this method I have declared my lists and trying to send the requests with the correct parameters
tokenID, address, and value (the last 3) need to be populated from the lists declared, but I'm stuck on how to do that.
any help appreciated
public List<string> recipientAdvancedAddress = new List<string>();
public List<string> tokenAdvancedSend = new List<string>();
public List<string> valueAdvancedSend = new List<string>();
public void Send()
{
StartCoroutine(SendAsync(userSession, senderAdvancedID, tokenAdvancedSend, recipientAdvancedAddress, valueAdvancedSend));
}
IEnumerator SendAsync(string session, int senderID, List<string> tokenID, List<string> addresses, List<string> value)
{
CryptoFilter cryptoFilter = new CryptoFilter();
cryptoFilter.AddParam("action", "advancedSendFT");
cryptoFilter.AddParam("session", session);
cryptoFilter.AddParam("senderID", $"{senderID}");
cryptoFilter.AddParam("tokenID", tokenID);
cryptoFilter.AddParam("addresses", addresses);
cryptoFilter.AddParam("value", value);
using (UnityWebRequest webRequest = UnityWebRequest.Post($"http://{SERVER_ADDR}/tsd/api.php", cryptoFilter.GetRequestPayload()))
{
yield return webRequest.SendWebRequest();
var result = webRequest.downloadHandler.text;
// Decrypt the response from the server.
result = cryptoFilter.GetResponsePayload(result);
sendItem data = JsonConvert.DeserializeObject<sendItem>(result);
if (!data.error)
txID = data.id;
}
}
this is the error: https://i.ibb.co/frNR5tF/error.png
and this is the method in the CryptoFilter.cs
class CryptoFilter
{
// Encrypt & Decrypt Engine
AES256 aes = new AES256();
// Request parameters
Dictionary<string, string> request = new Dictionary<string, string>();
/*
*
* Add a parameter.
*
*/
public void AddParam(string name, string value)
{
if (value != "")
request.Add(name, value);
}
/*
*
* Get the encrypted request string.
*
*/
public string GetRequestPayload()
{
string plain = JsonConvert.SerializeObject(request);
return aes.EncryptString(plain);
}
/*
*
* Get the decrypted response string.
*
*/
public string GetResponsePayload(string encrypted)
{
return aes.DecryptString(encrypted);
}
}
Btw, couldn't I do a foreach in the main script?
this is how the php is sent btw:
CreateEnjinRequest(
identity_id: YOUR_IDENTITY_ID,
type: ADVANCED_SEND,
advanced_send_token_data: {transfers: [
{tokenID: "xxxxxxxxxxxxxxxx", addresses: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", value:"1" },
{tokenID: "xxxxxxxxxxxxxxxx", addresses: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", value:"1" }
]})
so if I have 1 tokenID it's fine, but when I need to send 2 tokenID's to 2 different addresses is what I'm trying to achieve
How about an overload for the AddParam method:
AddParam(List<string>)
Or a generic version:
AddParam(List<T>)
Or even:
AddParam(Collection<T>)
I think I don't really understand what you're asking but within this method, you could maybe just loop through the items and do with them whatever you're already doing.
Edit: Looks like you need a json in the end. You can use Unity's built-in serialization for this. First make a class that represent the DTO (data transfer object) and then serialize it so it's a json string.
[Serializable]
public class CryptoFilter
{
public string action;
// other string fields
public List<string> addresses;
// other string list fields
public CryptoFilter(string action, List<string> addresses)
{
this.action = action;
this.addresses = addresses;
}
}
Then use:
CryptoFilter cryptoFilter = new CryptoFilter(...);
string json = JsonUtility.ToJson(cryptoFilter);
Edit: A string to string dictionary as request won't work for lists. Use a serializable class like the one I posted for this. Just call it Request or so instead of CryptoFilter. Then create the object and set it to the CryptoFilter once instead of calling AddParam multiple times.

C# - Create JSON array of objects from Dictionary

I'm sure there is a simple solution to this, I just haven't been able to figure it out yet.
I need to return an array of objects in JSON (which I'm completely new to). The structure should look like the following:
{"files": [
{
"picture1.jpg": true
},
{
"picture2.jpg": true
}
]}
I thought I could do this by using a Dictionary but that doesn't seem to work the way I want it to either. Below is what I have so far and what the output is. Any guidance would be greatly appreciated!
This is what I have in C#:
public async Task<JsonResult> DeleteImages(List<string> ids)
{
var files = new Dictionary<string, bool>();
foreach (var id in ids)
{
var file = await _fileService.GetByIdAsync(id);
if (await AzureStorage.DeleteFile(file))
{
files.Add(file.Name, true)
}
}
return Json(JsonConvert.SerializeObject(files));
}
The problem is that this returns the following:
{
"picture1.jpg": true,
"picture2.jpg": true
}
The following solution will provide exactly what you are looking for. The real key is creating an intermediate object to hold the entries you are looking for rather than simply placing the files in a Dictionary. The other complication is that you are really looking for a list of dictionaries, where each dictionary contains one file name/deleted entry.
The file collection class:
public class FileCollection
{
[JsonProperty("files")]
public List<Dictionary<string, bool>> Files { get; set; }
public FileCollection()
{
Files = new List<Dictionary<string, bool>>();
}
}
Your existing logic, modified to use the new collection class:
public async Task<JsonResult> DeleteImages(List<string> ids)
{
var files = new FileCollection();
foreach (var id in ids)
{
var file = await _fileService.GetByIdAsync(id);
if (await AzureStorage.DeleteFile(file))
{
files.Files.Add(new Dictionary<string, bool> { { file.Name, true } });
}
}
return Json(JsonConvert.SerializeObject(files));
}

JSON with dynamic Root-Object

problably I'm not experienced enought and my question is kind of dumb:
For learning purposes I'm trying to connect to a REST-Service, which delivers JSON-Data.
From what I've learned, the purpose of JSON is to deliver the same data to any possible client without having a State of itself.
My code is looking like this:
public static void DoSomething()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("SomeUrl"));
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// List data response.
HttpResponseMessage response = client.GetAsync("").Result;
if (response.IsSuccessStatusCode)
{
Task<Stream> readTask = response.Content.ReadAsStreamAsync();
readTask.ContinueWith(task =>
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
using (Stream result = task.Result)
{
result.Position = 0;
RootObject obj = (RootObject)ser.ReadObject(result);
}
});
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
public class Sum
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int summonerLevel { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Sum khalgor { get; set; }
}
But here's my Problem: I've created this classes "Sum" and "RootObject" by using the Website http://json2csharp.com/, the JSON-String is looking like this:
{"khalgor":{"id":23801741,"name":"Khalgor","profileIconId":7,"summonerLevel":30,"revisionDate":1396876104000}}
The Problem: The Name "Khalgor" seems to be used as a Root-Object, but it's a Name. So if I'd like to user for another Name, I'd have to user another RootObject.
It does not make that much sense to create such a Structure, so my question: What's the best practice here? Do I map this RootObject/Property to another object manually? Do I use some Reflection to dynamically create an Property or rename it?
As usual, thanks a lot for all Responses
Matthias
Edit:
I tinkered arround a bit and that's my first idea of a solution:
public static class LOLObjectFactory
{
public static ILOLObject Create(string jsonString)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
Dictionary<String, object> entry = (jss.Deserialize<dynamic>(jsonString) as Dictionary<string, object>).First().Value as Dictionary<String, object>;
Type selectedType = null;
List<string> fieldNames = entry.Select(f => f.Key).OrderBy(f => f).ToList();
Type[] types = typeof(ILOLObject).Assembly.GetTypes();
foreach(var type in types)
{
List<string> typeProperties = type.GetProperties().Select(f => f.Name).OrderBy(f => f).ToList();
if (fieldNames.SequenceEqual(typeProperties) && typeof(ILOLObject).IsAssignableFrom(type))
{
selectedType = type;
break;
}
}
ILOLObject result = System.Activator.CreateInstance(selectedType) as ILOLObject;
foreach(var prop in result.GetType().GetProperties())
{
prop.SetValue(result, entry.First(f => f.Key == prop.Name).Value);
}
return result;
}
}
So all the objects I have have the ILOLObject implemented. I'm sure it's not working for everything, but I guess that would be a good approach?
Edit2: Just by looking at it I see I'll have a lot of work to do, but I think the idea behind it is quite clear.
I think your best bet for json "fragments" is to deserialize into a dynamic object:
dynamic stuff = JsonConvert.DeserializeObject(inputData);
Then you can deserialize parts that make sense into proper .NET objects.
SomeObject o = JsonConvert.DeserializeObject<SomeObject>(stuff["someProperty"].ToString());
If you want to ignore the root altogether (e.g. it changes its name everytime) use Json.NET to parse it into an object and ignore the topmost element. Example:
JObject obj = JObject.Parse(json);
if (obj != null)
{
var root = obj.First;
if (root != null)
{
var sumJson = root.First;
if (sumJson != null)
{
var sum = sumJson.ToObject<Sum>();
}
}
}

JSON Twitter List in C#.net

My code is below. I am not able to extract the 'name' and 'query' lists
from the JSON via a DataContracted Class (below)
I have spent a long time trying to work this one out, and could really do
with some help...
My Json string:
{"as_of":1266853488,"trends":{"2010-02-22
15:44:48":[{"name":"#nowplaying","query":"#nowplaying"},{"name":"#musicmonday","query":"#musicmonday"},{"name":"#WeGoTogetherLike","query":"#WeGoTogetherLike"},{"name":"#imcurious","query":"#imcurious"},{"name":"#mm","query":"#mm"},{"name":"#HumanoidCityTour","query":"#HumanoidCityTour"},{"name":"#awesomeindianthings","query":"#awesomeindianthings"},{"name":"#officeformac","query":"#officeformac"},{"name":"Justin
Bieber","query":"\"Justin Bieber\""},{"name":"National
Margarita","query":"\"National Margarita\""}]}}
My code:
WebClient wc = new WebClient();
wc.Credentials = new NetworkCredential(this.Auth.UserName, this.Auth.Password);
string res = wc.DownloadString(new Uri(link));
//the download string gives me the above JSON string - no problems
Trends trends = new Trends();
Trends obj = Deserialise<Trends>(res);
private T Deserialise<T>(string json)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer serialiser = new DataContractJsonSerializer(obj.GetType());
obj = (T)serialiser.ReadObject(ms);
ms.Close();
return obj;
}
}
[DataContract]
public class Trends
{
[DataMember(Name = "as_of")]
public string AsOf { get; set; }
//The As_OF value is returned - But how do I get the
//multidimensional array of Names and Queries from the JSON here?
}
I've run into this very issue while developing Twitterizer. The issue is that the dataset isn't in a traditional object-oriented design.
If you were to map that as objects, you would see:
object root
int as_of
object trends
array[object] <date value of as_of>
string query
string name
As you can see, the trend object has a property that's name changes. The name is based on the as_of date value. As such, it can't be automatically deserialized.
My first solution was to use System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(). That method returns a hierarchy of weakly typed, nested dictionary instances. I then stepped through the results myself.
internal static TwitterTrendTimeframe ConvertWeakTrend(object value)
{
Dictionary<string, object> valueDictionary = (Dictionary<string, object>)value;
DateTime date = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds((int)valueDictionary["as_of"]);
object[] trends = (object[])((Dictionary<string, object>)valueDictionary["trends"])[date.ToString("yyyy-MM-dd HH:mm:ss")];
TwitterTrendTimeframe convertedResult = new TwitterTrendTimeframe()
{
EffectiveDate = date,
Trends = new Collection<TwitterTrend>()
};
for (int i = 0; i < trends.Length; i++)
{
Dictionary<string, object> item = (Dictionary<string, object>)trends[i];
TwitterTrend trend = new TwitterTrend()
{
Name = (string)item["name"]
};
if (item.ContainsKey("url"))
{
trend.Address = (string)item["url"];
}
if (item.ContainsKey("query"))
{
trend.SearchQuery = (string)item["query"];
}
convertedResult.Trends.Add(trend);
}
return convertedResult;
}
It's ugly, but it worked.
I've since embraced the use of Json.NET for it's speed and simplicity.
have you considered using JSON.net ?
Consider this example:
public struct TwitterResponse
{
public int32 as_of;
public Trend[] Trends;
}
public struct Trends
{
public String name;
public String query;
}
Trend[] obj = JavaScriptConvert.DeserializeObject<TwitterResponse>( res ).Trends;
Probably needs finetuning, but that's the general idea on how to do it.

Categories

Resources