Can Anyone help me retrieve data from parse using unity please? - c#

I have managed to store data, but I can't retrieve it and i would be so grateful if someone could just help me get at least 1 example working.
First I am storing data when the user signs up:
public void SetupNewParseMember(ParseUser user)
{
ParseObject gameScore = new ParseObject("GameScore");
gameScore["cash"] = 500;
gameScore["playerName"] = user.Username;
gameScore["HighestCash"] = 500;
gameScore["GamesPlayed"] = 0;
Task saveTask = gameScore.SaveAsync();
}
This works fine, I can see the data in parse and all seems ok..
The problem is when i try to retrieve the objects.
public void SetupMainScreen(ParseUser user)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username);
query.FindAsync().ContinueWith(t =>
{
IEnumerable<ParseObject> results = t.Result;
List<ParseObject> resultsList = results.ToList();
DealWithResults(resultsList, user);
});
}
public void DealWithResults(List<ParseObject> resultsList, ParseUser me)
{
userGamesPlayed = resultsList[1].Get<int>("GamesPlayed");
userHighestCash = resultsList[2].Get<int>("HighestCash");
userCash = resultsList[3].Get<int>("Cash");
WelcomeText.text = "Welcome, " + me.Username + "\n" +
"Cash: $" + userCash + "\n" +
"Highest Cash: $" + userHighestCash + "\n" +
"Games Played: " + userGamesPlayed;
}
First I tried just making changes to the unity ui from inside the Query but that did not work, So i made an outside function and passed the results to it that way, and that still does not work?
I tried to debug what i was getting in the list with this:
foreach (var res in resultsList)
{
Debug.Log("Class Name = " + res.ClassName + "| Keys are: " + res.Keys);
}
But all it returned was:
Class Name = GameScore| Keys are: System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]
Can anyone offer any insights?
EDIT2:
ok so first i found results list and its contents
http://i.imgur.com/IKcBbey.png
Then if i open it, it seems to be null ref?
http://i.imgur.com/VmSpi9c.png
But if i go digging, i found the info i need all the way down here
http://i.imgur.com/1Wwu5uc.png
Now just need to work out how to get it?

As there is only one set of data it is always accessible through resultsList[0]. What you want is:
double cash = (double)resultsList[0]["cash"];
string playerName = (string)resultsList[0]["playerName"];
double highestCash = (double)resultsList[0]["HighestCash"];
int gamesPlayed = (int)resultsList[0]["GamesPlayed"];
Though you probably want to check that resultsList is not null and contains one element before you try to dereference it.
Also as your ParseObject appears to be a Dictionary you might find this MSDN page useful.

Ended up solving it.. Much different to the examples...
I had to make a coroutine that called a function on callback to access the variables outside of the query.
I called it with
StartCoroutine(SetupMainScreen(me, DealWithResults));
then called this.
public IEnumerator SetupMainScreen(ParseUser user, Action<GameScore> callback)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username).FirstOrDefaultAsync();
while (!query.IsCompleted)
{
yield return null;
}
if (query.IsFaulted || query.IsCanceled)
{
Debug.Log("Getting of GameScores faulted or cancelled...");
}
else
{
var obj = query.Result;
if (obj != null)
callback(new GameScore(obj.Get<int>("cash"),obj.Get<string>("playerName"),obj.Get<int>("HighestCash"),obj.Get<int>("GamesPlayed")));
}
}
public void DealWithResults(GameScore gs)
{
WelcomeText.text = "Welcome, " + gs.Username + "\n" +
"Cash: $" + gs.Cash + "\n" +
"Highest Cash: $" + gs.HighestCash + "\n" +
"Games Played: " + gs.GamesPlayed;
}
And i just made a class to hold the objects.. Hopefully this helps someone else.

Related

How do i working with Arrays in a While loop?

I have tried to wipe this data while trying to export a database into my program.
The basic problem is that I do not know why he can not use LIKE in my SQL statement.
So I wanted to catch all DataRows and write them into an array, which I can edit later.
The program throws an exception:
Error message: System.IndexOutOfRangeException: "The index was outside the array area."
If I did something unusual or wrong in my Post I sincerely apologies, this is my first entry in this forum.
Code:
public void TestQuery()
{
string file = #"C:\Users\Michael\Downloads\7z1900-x64.msi";
// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
// Create the Windows Installer object
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
// Open the MSI database in the input file
Database database = installer.OpenDatabase(file, 0);
// Open a view on the Property table for the version property
View view = database.OpenView("SELECT * FROM `File`");
// Execute the view query
view.Execute(null);
// Get the record from the view
Record record = view.Fetch();
int i = 1;
string[] sreturns = new string[60];
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
}
First thing I see is that you're starting at 1, while (C#) arrays are 0-based.
In you screenshot I see that i is 60, so that would be the problem. Index 60 doesn't actually exist in your array, as it goes from 0 to 59.
You can add i < sreturns.Length to make sure you are in the array range.
Also, make sure you start with i = 0 and not 1.
int i = 0;
string[] sreturns = new string[60];
while (record != null && i < sreturns.Length)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
Why not using a list instead of an array?
List<string> sreturns = new List<string>();
while (record != null)
{
try
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
var result = record.get_StringData(0);
sreturns.Add(result.ToString());
}
catch (Exception e)
{
Console.WriteLine("No record...");
}
}
This way you dont need to worry about the array size - its maintainable -efficient - and if in the future the size change you don't have to worry about it.
List documentation here
What is the query with LIKE that you have tried? The following should work:
SELECT * FROM File WHERE FileName LIKE '%.exe' OR FileName LIKE '%.msi'
EDIT: On further investigation (https://learn.microsoft.com/en-us/windows/win32/msi/sql-syntax), the documentation seems to imply that the LIKE operator is not supported. But you could start off with an IS NOT NULL and do more complex filtering in the loop, like you're doing.
EDIT 2, expanding on Alex Leo's answer.
List<string> sreturns = new List<string>();
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
var result = record.get_StringData(0);
if(!string.IsNullOrWhiteSpace(result) && (result.EndsWith(".exe") || result.EndsWith(".msi")))
{
sreturns.Add(result.ToString());
}
record = view.Fetch();
}
Note that the view.Fetch() inside the while loop has been moved to the end, or you would skip the first record, as well as get another null reference when the last record has already been read, but the while loop executes one more time.

Extract only the values from SharePoint list with C#

I'm trying to extract the values of a SharePoint list to use with Revit to update the status parameters of some elements and after many tries I can connect and get the values if I know the keys for the dictionary inside every ListItem, but there are many problems with this approach.
The first one is the need to know the keys, sometimes the key is changed because of encoding, It would be more productive for me to get all the list values at one time. I tried to use a GetDataTable like some tutorials, but it appears that this don't work with the client.
The second is sometimes I can't get the value of the List but a description of the value, like "Microsoft.SharePoint.Client.FieldLookupValue".
Can someone help me with this issue? Bellow is the code I'm using.
using Microsoft.SharePoint.Client;
using System;
using System.Security;
namespace ConsoleTESTES
{
class Program
{
static void Main(string[] args)
{
string username = "USERNAME";
string siteURL = "SITEURL";
SecureString password = GetPassword();
GetAllWebProperties(siteURL, username, password);
}
public static void GetAllWebProperties(string siteURL, string username, SecureString password)
{
using (var context = new ClientContext(siteURL))
{
context.Credentials = new SharePointOnlineCredentials(username, password);
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
Console.WriteLine("Title: " + web.Title + "; URL: " + web.Url);
// Assume the web has a list named "Announcements".
//List lista = context.Web.Lists.GetByTitle("Lista teste");
List lista = context.Web.Lists.GetByTitle("LIST");
// This creates a CamlQuery that has a RowLimit of 100, and also specifies Scope="RecursiveAll"
// so that it grabs all list items, regardless of the folder they are in.
CamlQuery query = CamlQuery.CreateAllItemsQuery();
ListItemCollection items = lista.GetItems(query);
// Retrieve all items in the ListItemCollection from List.GetItems(Query).
context.Load(items);
context.ExecuteQuery();
//GET VALUES FROM LISTITEM
foreach (ListItem listItem in items)
{
Console.WriteLine(listItem["Setor"] + " " + "|" + " "
+ listItem["LocalServico"] + " " + "|" + " "
+ listItem["Equipe"] + " " + "|" + " "
+ listItem["Confeccao"]);
}
Console.ReadLine();
}
}
public static SecureString GetPassword()
{
ConsoleKeyInfo info;
SecureString securePassword = new SecureString();
do
{
info = Console.ReadKey();
if (info.Key != ConsoleKey.Enter)
{
securePassword.AppendChar(info.KeyChar);
}
}
while (info.Key != ConsoleKey.Enter);
return securePassword;
}
}
}
You could get the values from the fields collection, but be warned that some special types of fields might require special treatment for the values and that you might not need to get all the values from the server (you can probably reduce your payload):
var items = lista.GetItems(query);
var fields = list.Fields;
var fieldsToIgnore = new[] { "ContentType", "Attachments" };
context.Load(items);
context.Load(fields);
context.ExecuteQuery();
foreach (ListItem listItem in items)
{
foreach (Field field in fields)
{
if (!fieldsToIgnore.Contains(fld.InternalName))
Console.WriteLine(item[field.InternalName]);
}
}
There are some fields that might not be loaded by default of that you might not need, so I have included the fieldsToIgnore to make your test easier.
After some search I found this solution to my FieldLookUpTable, to avoid errors if the item is null I added a if statement, but I could access the value with (listItem["Setor"] as FieldLookupValue).LookupValue. Here my messy code to check if is a LookupValue and get the value. Now I need to implement Pedro's solution to get all the values without the need to write everyone.
String setor = "";
String localServico = "";
String confeccao = "";
if (listItem["Setor"] != null && listItem["Setor"].ToString() == "Microsoft.SharePoint.Client.FieldLookupValue")
{
setor = (listItem["Setor"] as FieldLookupValue).LookupValue;
}
else if (listItem["Setor"] != null && listItem["Setor"].ToString() != "Microsoft.SharePoint.Client.FieldLookupValue")
{
setor = listItem["Setor"].ToString();
}
if (listItem["LocalServico"] != null && listItem["LocalServico"].ToString() == "Microsoft.SharePoint.Client.FieldLookupValue")
{
localServico = (listItem["LocalServico"] as FieldLookupValue).LookupValue;
}
else if (listItem["LocalServico"] != null && listItem["LocalServico"].ToString() != "Microsoft.SharePoint.Client.FieldLookupValue")
{
localServico = listItem["LocalServico"].ToString();
}
if (listItem["Confeccao"] != null && listItem["Confeccao"].ToString() == "Microsoft.SharePoint.Client.FieldLookupValue")
{
confeccao = (listItem["Confeccao"] as FieldLookupValue).LookupValue;
}
else if (listItem["Confeccao"] != null && listItem["Confeccao"].ToString() != "Microsoft.SharePoint.Client.FieldLookupValue")
{
confeccao = listItem["Confeccao"].ToString();
}
Console.WriteLine(setor + " " + "|" + " "
+ localServico + " " + "|" + " "
+ confeccao);

Object not set to an instance of an object in sql query, null reference exception

In this specific case I am getting null reference exception, and I cant solve it.
public class Tiket
{
private Korisnik korisnik;
public Korisnik Korisnik
{
get { if (korisnik == null)
{
korisnik = new Korisnik();
}
return korisnik; }
set { korisnik = value; }
}
}
Inside form I am taking value inserted in textbox and sending it to method which deal with database(its much more complex but I am trying to make it simple):
Tiket t = new Tiket();
t.Korisnik.Ime = txtImeKorisnika.Text;
thatMethod(t);
So above, I am not getting null reference exception while assigning value to t.Korisnik.Ime, but Inside method I am getting one:
string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime;
extra question connected to this topic:
I am having same problem while trying to add values to these fields from database which are also class properties inside Tiket.
tikeet.Korisnik.JMBG = red[5].ToString();
tikeet.Radnik.SifraRadnika = Convert.ToInt32(red[6]);
I know why is this happening but I dont know how to initialize Korisnik, Radnik here.
EDIT: I hope this helps now, so You can help me !
I have client server app and I am sending Tiket to Server..than its sent as OpstiDomenskiObjekat(instead of Tiket) to method I have problem now.
OpstiDomenskiObjekat is interface, so I could have one or few methods for many similar things I need.
public List<OpstiDomenskiObjekat> vratiZaUslovJedanPlus(OpstiDomenskiObjekat odo)
{
string upit = "SELECT * FROM " + odo.tabela + " " + " WHERE " + odo.uslovJedan;
OleDbDataReader citac = null;
OleDbCommand komanda = new OleDbCommand(upit, konekcija, transakcija);
try
{
citac = komanda.ExecuteReader(); // **here is exception thrown**
DataTable tabela = new DataTable();
tabela.Load(citac);
List<OpstiDomenskiObjekat> lista = new List<OpstiDomenskiObjekat>();
foreach (DataRow red in tabela.Rows)
{
OpstiDomenskiObjekat pom = odo.napuni(red);
lista.Add(pom);
}
return lista;
}
catch (Exception ex)
{
throw ex;
}
//this is implementation in class Tiket
public string uslovJedan
{
get
{
return Korisnik.Ime;
}
}
//this should happen after method, I will have List as I needed
List<Tiket> lista = Broker.dajSesiju().vratiZaUslovJedanPlus(odo).OfType<Tiket>().ToList<Tiket>();
return lista;
Connection, transaction etc.. its all somewhere else, but It all works, I promise :)
The + operator in this case is a string concatenation operator. Ticket is the name of your class and its not clear whether you have a property with that same name. If you do have a property by that name,
string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime;
it is possible that the above line is failing because the Tiket property is null. And also, it's ToString() might not be valid for the FROM clause of a query.
Update
As you can see, it didn't compile for me at all. When I wrote a property with the same name. It compiled, and constructed the string, inserting a null character where Ticket was.
The second screenshot shows what happens if it was a property.
Your string is still constructed in that case and you will get an invalid query at the line string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime; which is probably causing your issues. Please update with a screenshot of where the exception is being thrown.

Permissions on a folder

I have been looking for some time now and have not been able to find this. How can I set my program up to write or update a file from multiple users but only one group is allowed to open the read what is in the folder?
class Log_File
{
string LogFileDirectory = #"\\server\boiseit$\TechDocs\Headset Tracker\Weekly Charges\Log\Log Files";
string PathToXMLFile = #"\\server\boiseit$\scripts\Mikes Projects\Headset-tracker\config\Config.xml";
string AdditionToLogFile = #"\Who.Did.It_" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + ".txt";
XML XMLFile = new XML();
public void ConfigCheck()
{
if (!File.Exists(PathToXMLFile))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
}
}
public void CreateLogFile()
{
if (Directory.GetFiles(LogFileDirectory).Count() == 0)
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else if (!File.Exists(XMLFile.readingXML(PathToXMLFile)))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else
{
FileInfo dateOfLastLogFile = new FileInfo(XMLFile.readingXML(PathToXMLFile));
DateTime dateOfCreation = dateOfLastLogFile.CreationTime;
if (dateOfLastLogFile.CreationTime <= DateTime.Now.AddMonths(-1))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
}
}
public void CreateFileOrAppend(string whoDidIt)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetStore((IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User), null, null))
{
using (StreamWriter myWriter = new StreamWriter(XMLFile.readingXML(PathToXMLFile), true))
{
if (whoDidIt == "")
{
}
else
{
myWriter.WriteLine(whoDidIt);
}
}
}
}
This is my path where it needs to go. I have the special permission to open and write to the folder but my co workers do not. I am not allow to let them have this permission.
If I where to set up a database how would i change this code
LoggedFile.CreateFileOrAppend(Environment.UserName.ToUpper() + "-" + Environment.NewLine + "Replacement Headset To: " + AgentName + Environment.NewLine + "Old Headset Number: " + myDatabase.oldNumber + Environment.NewLine + "New Headset Number: " + HSNumber + Environment.NewLine + "Date: " + DateTime.Now.ToShortDateString() + Environment.NewLine);
I need it to pull current user, the agents name that is being affected the old headset and the new headset, and the time it took place.
While you create file, you have to set access rules to achieve your requirements. .
File.SetAccessControl(string,FileSecurity)
The below link has example
https://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol(v=vs.110).aspx
Also the "FileSecurity" class object, which is an input parameter, has functions to set access rules, including group level control.
Below link has example
https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesecurity(v=vs.110).aspx
This question will be opened under a new question since I am going to take a different route for recording the data I need Thank you all for the help

SSIS Script Component: Microsoft.SqlServer.Dts.Pipeline.BlobColumn

Struggling with a C# Component. What I am trying to do is take a column that is ntext in my input source which is delimited with pipes, and then write the array to a text file. When I run my component my output looks like this:
DealerID,StockNumber,Option
161552,P1427,Microsoft.SqlServer.Dts.Pipeline.BlobColumn
Ive been working with the GetBlobData method and im struggling with it. Any help with be greatly appreciated! Here is the full script:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string vehicleoptionsdelimited = Row.Options.ToString();
//string OptionBlob = Row.Options.GetBlobData(int ;
//string vehicleoptionsdelimited = System.Text.Encoding.GetEncoding(Row.Options.ColumnInfo.CodePage).GetChars(OptionBlob);
string[] option = vehicleoptionsdelimited.Split('|');
string path = #"C:\Users\User\Desktop\Local_DS_CSVs\";
string[] headerline =
{
"DealerID" + "," + "StockNumber" + "," + "Option"
};
System.IO.File.WriteAllLines(path + "OptionInput.txt", headerline);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + "OptionInput.txt", true))
{
foreach (string s in option)
{
file.WriteLine(Row.DealerID.ToString() + "," + Row.StockNumber.ToString() + "," + s);
}
}
Try using
BlobToString(Row.Options)
using this function:
private string BlobToString(BlobColumn blob)
{
string result = "";
try
{
if (blob != null)
{
result = System.Text.Encoding.Unicode.GetString(blob.GetBlobData(0, Convert.ToInt32(blob.Length)));
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
Adapted from:
http://mscrmtech.com/201001257/converting-microsoftsqlserverdtspipelineblobcolumn-to-string-in-ssis-using-c
Another very easy solution to this problem, because it is a total PITA, is to route the error output to a derived column component and cast your blob data to a to a STR or WSTR as a new column.
Route the output of that to your script component and the data will come in as an additional column on the pipeline ready for you to parse.
This will probably only work if your data is less than 8000 characters long.

Categories

Resources